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:
parent
5d7cdd2c67
commit
67efbb5f7f
|
@ -34,6 +34,16 @@ static inline uint32_t reg0(uint8_t 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fatal("mcrf not supported yet");
|
||||
|
@ -220,7 +236,7 @@ static void mtcrf(uint8_t fxm, uint32_t value)
|
|||
static void dispatch(uint32_t value)
|
||||
{
|
||||
#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)
|
||||
|
|
|
@ -22,9 +22,11 @@ extern cpu_t cpu;
|
|||
extern uint32_t read_byte(uint32_t address);
|
||||
extern uint32_t read_word(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_word(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);
|
||||
|
||||
|
|
|
@ -47,16 +47,16 @@
|
|||
|
||||
# Fixed point stores
|
||||
|
||||
<38--><RS-><RA-><D-------------> write_byte(reg0(RA) + ext16(D), RS);
|
||||
<31--><RS-><RA-><RB-><215----->. write_byte(reg0(RA) + reg(RB), RS);
|
||||
<38--><RS-><RA-><D-------------> write_byte(reg0(RA) + ext16(D), reg(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;
|
||||
<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);
|
||||
<31--><RS-><RA-><RB-><407----->. write_word(reg0(RA) + reg(RB), RS);
|
||||
<44--><RS-><RA-><D-------------> write_word(reg0(RA) + ext16(D), reg(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;
|
||||
<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);
|
||||
<31--><RS-><RA-><RB-><151----->. write_long(reg0(RA) + reg(RB), RS);
|
||||
<36--><RS-><RA-><D-------------> write_long(reg0(RA) + ext16(D), reg(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;
|
||||
<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--><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)));
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#define INIT_SP RAM_TOP
|
||||
#define INIT_PC 0x08000054
|
||||
|
||||
#define EXIT_PC 0xdeaddead
|
||||
|
||||
/* Read/write macros */
|
||||
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
|
||||
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \
|
||||
|
@ -71,6 +73,11 @@ static uint32_t transform_address(uint32_t address)
|
|||
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 v = READ_LONG(ram, transform_address(address));
|
||||
|
@ -80,7 +87,6 @@ uint32_t read_long(uint32_t address)
|
|||
return v;
|
||||
}
|
||||
|
||||
|
||||
uint32_t read_word(uint32_t 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
cpu.cr &= ~(1<<28); /* reset summary overflow (for success) */
|
||||
|
@ -130,6 +142,21 @@ void system_call(uint8_t trapno)
|
|||
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 */
|
||||
cpu.gpr[4] = 0;
|
||||
break;
|
||||
|
@ -212,7 +239,8 @@ int main(int argc, char* argv[])
|
|||
cpu.cia = entrypoint;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
cpu.lr = EXIT_PC;
|
||||
while (cpu.cia != EXIT_PC)
|
||||
{
|
||||
#if 0
|
||||
dump_state(stderr);
|
||||
|
|
Loading…
Reference in a new issue