mirror of
https://github.com/pruten/shoebill.git
synced 2025-01-06 17:29:56 +00:00
Implemented fmovem_control()
I'm on a roll
This commit is contained in:
parent
2790b03327
commit
2d04c6c104
125
core/newfpu.c
125
core/newfpu.c
@ -1499,7 +1499,130 @@ static void inst_fmovem_control (const uint16_t ext)
|
|||||||
{
|
{
|
||||||
fpu_get_state_ptr();
|
fpu_get_state_ptr();
|
||||||
|
|
||||||
assert(!"fmovem_control");
|
~decompose(shoe.op, 1111 001 000 mmmrrr);
|
||||||
|
~decompose(shoe.op, 1111 001 000 MMMMMM);
|
||||||
|
~decompose(ext, 10d CSI 0000000000);
|
||||||
|
|
||||||
|
const uint32_t count = C + S + I;
|
||||||
|
const uint32_t size = count * 4;
|
||||||
|
uint32_t addr, buf[3];
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* I don't know if this is even a valid instruction */
|
||||||
|
if (count == 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
/* data and addr reg modes are valid, but only if count==1 */
|
||||||
|
if ((m == 0 || m == 1) && (count > 1)) {
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d) { // reg to memory
|
||||||
|
i=0;
|
||||||
|
if (C) buf[i++] = fpu->fpcr.raw;
|
||||||
|
if (S) buf[i++] = fpu->fpsr.raw;
|
||||||
|
if (I) buf[i++] = fpu->fpiar;
|
||||||
|
|
||||||
|
if (m == 0) {
|
||||||
|
if (count == 1)
|
||||||
|
shoe.d[r] = buf[0];
|
||||||
|
else
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
else if (m == 1) {
|
||||||
|
if ((count == 1) && I)
|
||||||
|
shoe.a[r] = buf[0];
|
||||||
|
else
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
else if (m == 3)
|
||||||
|
addr = shoe.a[r];
|
||||||
|
else if (m == 4)
|
||||||
|
addr = shoe.a[r] - size;
|
||||||
|
else {
|
||||||
|
if ((m==7) && (r!=0 || r!=1)) {
|
||||||
|
/* Not allowed for reg->mem */
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
call_ea_addr(M);
|
||||||
|
addr = shoe.dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
lset(addr + (i*4), 4, buf[i]);
|
||||||
|
if (shoe.abort)
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // mem to reg
|
||||||
|
if (m == 0) {// data reg
|
||||||
|
if (count == 1)
|
||||||
|
buf[0] = shoe.d[r];
|
||||||
|
else
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (m == 1) {// addr reg
|
||||||
|
if ((count == 1) && I)
|
||||||
|
buf[0] = shoe.a[r];
|
||||||
|
else
|
||||||
|
throw_illegal_instruction();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m == 3) // post-increment
|
||||||
|
addr = shoe.a[r];
|
||||||
|
else if (m == 4) // pre-decrement
|
||||||
|
addr = shoe.a[r] - size;
|
||||||
|
else if (M == 0x3c) // immediate
|
||||||
|
addr = shoe.pc;
|
||||||
|
else {
|
||||||
|
call_ea_addr(M); // call_ea_addr() should work for all other modes
|
||||||
|
addr = shoe.dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
buf[i] = lget(addr + (i*4), 4);
|
||||||
|
if (shoe.abort)
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if (C) {
|
||||||
|
uint8_t round = fpu->fpcr.b._mc_rnd;
|
||||||
|
fpu->fpcr.raw = buf[i++];
|
||||||
|
uint8_t newround = fpu->fpcr.b._mc_rnd;
|
||||||
|
|
||||||
|
if (round != newround) {
|
||||||
|
slog("inst_fmovem_control: HEY: round %u -> %u\n", round, newround);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (S) fpu->fpsr.raw = buf[i++];
|
||||||
|
if (I) fpu->fpiar = buf[i++];
|
||||||
|
|
||||||
|
// Commit immediate-EA-mode PC change
|
||||||
|
if (M == 0x3c)
|
||||||
|
shoe.pc += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit pre/post-inc/decrement
|
||||||
|
|
||||||
|
if (m == 3)
|
||||||
|
shoe.a[r] += size;
|
||||||
|
if (m == 4)
|
||||||
|
shoe.a[r] -= size;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
slog("inst_fmove_control: notice: (EA = %u/%u %08x CSI = %u%u%u)\n", m, r, (uint32_t)shoe.dat, C, S, I);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inst_fmovem (const uint16_t ext)
|
static void inst_fmovem (const uint16_t ext)
|
||||||
|
Loading…
Reference in New Issue
Block a user