Do a bit of floating point stuff; added brk(); fixed a horrible bug where

stores with 16-bit displacements were storing the register number and not the
contents of the register.
This commit is contained in:
David Given 2018-06-16 22:55:23 +02:00
parent 5d7cdd2c67
commit 67efbb5f7f
4 changed files with 73 additions and 9 deletions

View file

@ -34,6 +34,16 @@ static inline uint32_t reg0(uint8_t n)
return cpu.gpr[n]; return cpu.gpr[n];
} }
static inline uint64_t tobytes(double n)
{
return *(uint64_t*)&n;
}
static inline double fpr(uint8_t n)
{
return *(double*)&cpu.fpr[n];
}
static inline uint32_t ext8(int8_t n) static inline uint32_t ext8(int8_t n)
{ {
return (n << 24) >> 24; return (n << 24) >> 24;
@ -72,6 +82,12 @@ static void setcr0(bool setcr0, uint32_t value)
} }
} }
static void setcr1(bool setcr1, uint64_t value)
{
if (setcr1)
fatal("setcr1 not implemented yet");
}
static void mcrf(uint8_t destfield, uint8_t srcfield) static void mcrf(uint8_t destfield, uint8_t srcfield)
{ {
fatal("mcrf not supported yet"); fatal("mcrf not supported yet");
@ -220,7 +236,7 @@ static void mtcrf(uint8_t fxm, uint32_t value)
static void dispatch(uint32_t value) static void dispatch(uint32_t value)
{ {
#include "dispatcher.h" #include "dispatcher.h"
fatal("unimplemented instruction 0x%0x", value); fatal("unimplemented instruction 0x%0x (major opcode %d)", value, value>>26);
} }
void dump_state(FILE* stream) void dump_state(FILE* stream)

View file

@ -22,9 +22,11 @@ extern cpu_t cpu;
extern uint32_t read_byte(uint32_t address); extern uint32_t read_byte(uint32_t address);
extern uint32_t read_word(uint32_t address); extern uint32_t read_word(uint32_t address);
extern uint32_t read_long(uint32_t address); extern uint32_t read_long(uint32_t address);
extern uint64_t read_double(uint32_t address);
extern void write_byte(uint32_t address, uint32_t value); extern void write_byte(uint32_t address, uint32_t value);
extern void write_word(uint32_t address, uint32_t value); extern void write_word(uint32_t address, uint32_t value);
extern void write_long(uint32_t address, uint32_t value); extern void write_long(uint32_t address, uint32_t value);
extern void write_double(uint32_t address, uint64_t value);
extern void system_call(uint8_t trapno); extern void system_call(uint8_t trapno);

View file

@ -47,16 +47,16 @@
# Fixed point stores # Fixed point stores
<38--><RS-><RA-><D-------------> write_byte(reg0(RA) + ext16(D), RS); <38--><RS-><RA-><D-------------> write_byte(reg0(RA) + ext16(D), reg(RS));
<31--><RS-><RA-><RB-><215----->. write_byte(reg0(RA) + reg(RB), RS); <31--><RS-><RA-><RB-><215----->. write_byte(reg0(RA) + reg(RB), reg(RS));
<39--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea; <39--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea;
<31--><RS-><RA-><RB-><247----->. uint32_t ea = reg(RA) + reg(RB); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><RS-><RA-><RB-><247----->. uint32_t ea = reg(RA) + reg(RB); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea;
<44--><RS-><RA-><D-------------> write_word(reg0(RA) + ext16(D), RS); <44--><RS-><RA-><D-------------> write_word(reg0(RA) + ext16(D), reg(RS));
<31--><RS-><RA-><RB-><407----->. write_word(reg0(RA) + reg(RB), RS); <31--><RS-><RA-><RB-><407----->. write_word(reg0(RA) + reg(RB), reg(RS));
<45--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_word(ea, reg(RS)); cpu.gpr[RA] = ea; <45--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_word(ea, reg(RS)); cpu.gpr[RA] = ea;
<31--><RS-><RA-><RB-><439----->. uint32_t ea = reg(RA) + reg(RB); write_word(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><RS-><RA-><RB-><439----->. uint32_t ea = reg(RA) + reg(RB); write_word(ea, reg(RS)); cpu.gpr[RA] = ea;
<36--><RS-><RA-><D-------------> write_long(reg0(RA) + ext16(D), RS); <36--><RS-><RA-><D-------------> write_long(reg0(RA) + ext16(D), reg(RS));
<31--><RS-><RA-><RB-><151----->. write_long(reg0(RA) + reg(RB), RS); <31--><RS-><RA-><RB-><151----->. write_long(reg0(RA) + reg(RB), reg(RS));
<37--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_long(ea, reg(RS)); cpu.gpr[RA] = ea; <37--><RS-><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_long(ea, reg(RS)); cpu.gpr[RA] = ea;
<31--><RS-><RA-><RB-><183----->. uint32_t ea = reg(RA) + reg(RB); write_long(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><RS-><RA-><RB-><183----->. uint32_t ea = reg(RA) + reg(RB); write_long(ea, reg(RS)); cpu.gpr[RA] = ea;
@ -147,3 +147,21 @@
<31--><RS->0<FXM--->.<144----->. mtcrf(FXM, reg(RS)); <31--><RS->0<FXM--->.<144----->. mtcrf(FXM, reg(RS));
<31--><RT->0.........<19------>. cpu.gpr[RT] = cpu.cr; <31--><RT->0.........<19------>. cpu.gpr[RT] = cpu.cr;
# Floating point loads
<50--><FRT><RA-><D------------>. cpu.fpr[FRT] = read_double(reg0(RA) + ext16(D));
<31--><FRT><RA-><RB-><599----->. cpu.gpr[FRT] = read_double(reg0(RA) + reg(RB));
<51--><FRT><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); cpu.fpr[FRT] = read_byte(ea); cpu.gpr[RA] = ea;
<31--><FRT><RA-><RB-><631----->. uint32_t ea = reg(RA) + reg(RB); cpu.fpr[FRT] = read_long(ea); cpu.gpr[RA] = ea;
# Floating point stores
<54--><FRS><RA-><D------------>. write_double(read_double(reg0(RA) + ext16(D)), cpu.fpr[FRS]);
<31--><FRS><RA-><RB-><727----->. write_double(reg0(RA) + reg(RB), cpu.fpr[FRS]);
<55--><FRS><RA-><D-------------> uint32_t ea = reg(RA) + ext16(D); write_double(ea, cpu.fpr[FRS]); cpu.gpr[RA] = ea;
<31--><FRS><RA-><RB-><759----->. uint32_t ea = reg(RA) + reg(RB); write_long(ea, cpu.fpr[FRS]); cpu.gpr[RA] = ea;
# Floating point arithmetic
<63--><FRT>.....<FRB><72------>R setcr1(R, cpu.fpr[FRT] = cpu.fpr[FRB]);
<63--><FRT><FRA><FRB><20------>R setcr1(R, cpu.fpr[FRT] = tobytes(fpr(FRA) - fpr(FRB)));

View file

@ -17,6 +17,8 @@
#define INIT_SP RAM_TOP #define INIT_SP RAM_TOP
#define INIT_PC 0x08000054 #define INIT_PC 0x08000054
#define EXIT_PC 0xdeaddead
/* Read/write macros */ /* Read/write macros */
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR] #define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \ #define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \
@ -71,6 +73,11 @@ static uint32_t transform_address(uint32_t address)
return a; return a;
} }
uint64_t read_double(uint32_t address)
{
return ((uint64_t)read_long(address+0) << 32) | read_long(address+4);
}
uint32_t read_long(uint32_t address) uint32_t read_long(uint32_t address)
{ {
uint32_t v = READ_LONG(ram, transform_address(address)); uint32_t v = READ_LONG(ram, transform_address(address));
@ -80,7 +87,6 @@ uint32_t read_long(uint32_t address)
return v; return v;
} }
uint32_t read_word(uint32_t address) uint32_t read_word(uint32_t address)
{ {
return READ_WORD(ram, transform_address(address)); return READ_WORD(ram, transform_address(address));
@ -109,6 +115,12 @@ void write_long(uint32_t address, uint32_t value)
WRITE_LONG(ram, transform_address(address), value); WRITE_LONG(ram, transform_address(address), value);
} }
void write_double(uint32_t address, uint64_t value)
{
write_long(address+0, value>>32);
write_long(address+4, value);
}
void system_call(uint8_t trapno) void system_call(uint8_t trapno)
{ {
cpu.cr &= ~(1<<28); /* reset summary overflow (for success) */ cpu.cr &= ~(1<<28); /* reset summary overflow (for success) */
@ -130,6 +142,21 @@ void system_call(uint8_t trapno)
break; break;
} }
case 45: /* brk */
{
uint32_t newpos = cpu.gpr[3];
if (newpos == 0)
cpu.gpr[4] = brkpos;
else if ((newpos < brkbase) || (newpos >= BRK_TOP))
cpu.gpr[4] = -ENOMEM;
else
{
brkpos = newpos;
cpu.gpr[4] = 0;
}
break;
}
case 126: /* sigprocmask */ case 126: /* sigprocmask */
cpu.gpr[4] = 0; cpu.gpr[4] = 0;
break; break;
@ -212,7 +239,8 @@ int main(int argc, char* argv[])
cpu.cia = entrypoint; cpu.cia = entrypoint;
} }
for (;;) cpu.lr = EXIT_PC;
while (cpu.cia != EXIT_PC)
{ {
#if 0 #if 0
dump_state(stderr); dump_state(stderr);