/** * This is called after completion of each VDI call */ unsigned long OpCode_VDI(uae_u32 opcode) { Uint32 pc = M68000_GetPC(); /* this is valid only after VDI trap, called from cartridge code */ if (VDI_OldPC && pc >= 0xfa0000 && pc < 0xfc0000) { VDI_Complete(); /* Set PC back to where originated from to continue instruction decoding */ m68k_setpc(VDI_OldPC); VDI_OldPC = 0; } else { /* illegal instruction */ op_illg(opcode); } get_word_prefetch (0); regs.ir = regs.irc; get_word_prefetch(2); return 4 * CYCLE_UNIT / 2; }
static void fpu_op_illg (uae_u32 opcode, int pcoffset) { if ((currprefs.cpu_model == 68060 && (currprefs.fpu_model == 0 || (regs.pcr & 2))) || (currprefs.cpu_model == 68040 && currprefs.fpu_model == 0)) { /* 68040 unimplemented/68060 FPU disabled exception. * Line F exception with different stack frame.. */ uaecptr newpc = m68k_getpc (); uaecptr oldpc = newpc - pcoffset; MakeSR (); if (!regs.s) { regs.usp = m68k_areg (regs, 7); m68k_areg (regs, 7) = regs.isp; } regs.s = 1; m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), oldpc); m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), oldpc); m68k_areg (regs, 7) -= 2; put_word (m68k_areg (regs, 7), 0x4000 + 11 * 4); m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), newpc); m68k_areg (regs, 7) -= 2; put_word (m68k_areg (regs, 7), regs.sr); write_log ("68040/060 FPU disabled exception PC=%x\n", newpc); newpc = get_long (regs.vbr + 11 * 4); m68k_setpc (newpc); return; } op_illg (opcode); }
void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) { int reg; int sreg, prec = 0; int dreg = (extra >> 7) & 7; int source = (extra >> 13) & 7; int opmode = extra & 0x7f; if (!currprefs.compfpu) { FAIL(1); return; } switch (source) { case 3: /* FMOVE FPx, <EA> */ if (comp_fp_put(opcode,extra) < 0) FAIL(1); return; case 4: /* FMOVE.L <EA>, ControlReg */ if (!(opcode & 0x30)) { /* Dn or An */ if (extra & 0x1000) { /* FPCR */ mov_l_mr((uae_u32)®s.fpcr,opcode & 15); #if USE_X86_FPUCW mov_l_rr(S1,opcode & 15); and_l_ri(S1,0xf0); fldcw_m_indexed(S1,(uae_u32)x86_fpucw); #endif return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; // set_fpsr(m68k_dreg (regs, opcode & 15)); } if (extra & 0x0400) { /* FPIAR */ mov_l_mr((uae_u32)®s.fpiar,opcode & 15); return; } } else if ((opcode & 0x3f) == 0x3c) { if (extra & 0x1000) { /* FPCR */ uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); mov_l_mi((uae_u32)®s.fpcr,val); #if USE_X86_FPUCW mov_l_ri(S1,val&0xf0); fldcw_m_indexed(S1,(uae_u32)x86_fpucw); #endif return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; } if (extra & 0x0400) { /* FPIAR */ uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); mov_l_mi((uae_u32)®s.fpiar,val); return; } } FAIL(1); return; case 5: /* FMOVE.L ControlReg, <EA> */ if (!(opcode & 0x30)) { /* Dn or An */ if (extra & 0x1000) { /* FPCR */ mov_l_rm(opcode & 15,(uae_u32)®s.fpcr); return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; } if (extra & 0x0400) { /* FPIAR */ mov_l_rm(opcode & 15,(uae_u32)®s.fpiar); return; } } FAIL(1); return; case 6: case 7: { uae_u32 list = 0; int incr = 0; if (extra & 0x2000) { uae_u32 ad; /* FMOVEM FPP->memory */ switch ((extra >> 11) & 3) { /* Get out early if failure */ case 0: case 2: break; case 1: case 3: default: FAIL(1); return; } ad = comp_fp_adr (opcode); if (ad < 0) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode); return; } switch ((extra >> 11) & 3) { case 0: /* static pred */ list = extra & 0xff; incr = -1; break; case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; case 1: /* dynamic pred */ case 3: /* dynamic postinc */ abort(); } if (incr < 0) { /* Predecrement */ for (reg = 7; reg >= 0; reg--) { if (list & 0x80) { fmov_ext_mr((uintptr)temp_fp,reg); sub_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp); writelong_clobber(ad,S2,S3); sub_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp+4); writelong_clobber(ad,S2,S3); sub_l_ri(ad,4); mov_w_rm(S2,(uintptr)temp_fp+8); writeword_clobber(ad,S2,S3); } list <<= 1; } } else { /* Postincrement */ for (reg = 0; reg <= 7; reg++) { if (list & 0x80) { fmov_ext_mr((uintptr)temp_fp,reg); mov_w_rm(S2,(uintptr)temp_fp+8); writeword_clobber(ad,S2,S3); add_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp+4); writelong_clobber(ad,S2,S3); add_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp); writelong_clobber(ad,S2,S3); add_l_ri(ad,4); } list <<= 1; } } if ((opcode & 0x38) == 0x18) mov_l_rr((opcode & 7)+8,ad); if ((opcode & 0x38) == 0x20) mov_l_rr((opcode & 7)+8,ad); } else { /* FMOVEM memory->FPP */ uae_u32 ad; switch ((extra >> 11) & 3) { /* Get out early if failure */ case 0: case 2: break; case 1: case 3: default: FAIL(1); return; } ad=comp_fp_adr (opcode); if (ad < 0) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode); return; } switch ((extra >> 11) & 3) { case 0: /* static pred */ list = extra & 0xff; incr = -1; break; case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; case 1: /* dynamic pred */ case 3: /* dynamic postinc */ abort(); } if (incr < 0) { // not reached for (reg = 7; reg >= 0; reg--) { if (list & 0x80) { sub_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp),S2); sub_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp)+4,S2); sub_l_ri(ad,4); readword(ad,S2,S3); mov_w_mr(((uintptr)temp_fp)+8,S2); fmov_ext_rm(reg,(uintptr)(temp_fp)); } list <<= 1; } } else { for (reg = 0; reg <= 7; reg++) { if (list & 0x80) { readword(ad,S2,S3); mov_w_mr(((uintptr)temp_fp)+8,S2); add_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp)+4,S2); add_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp),S2); add_l_ri(ad,4); fmov_ext_rm(reg,(uintptr)(temp_fp)); } list <<= 1; } } if ((opcode & 0x38) == 0x18) mov_l_rr((opcode & 7)+8,ad); if ((opcode & 0x38) == 0x20) mov_l_rr((opcode & 7)+8,ad); } }
void comp_fscc_opp (uae_u32 opcode, uae_u16 extra) { uae_u32 ad; int cc; int reg; if (!currprefs.compfpu) { FAIL(1); return; } #if DEBUG_FPP write_log (_T("JIT: fscc_opp at %08lx\n"), M68K_GETPC); #endif if (extra & 0x20) { /* only cc from 00 to 1f are defined */ FAIL(1); return; } if ((opcode & 0x38) != 0) { /* We can only do to integer register */ FAIL(1); return; } fflags_into_flags(S2); reg = (opcode & 7); mov_l_ri(S1,255); mov_l_ri(S4,0); switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */ case 0: break; /* set never */ case 1: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S2,10); break; case 2: cmov_l_rr(S4,S1,7); break; case 3: cmov_l_rr(S4,S1,3); break; case 4: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,2); cmov_l_rr(S4,S2,10); break; case 5: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,6); cmov_l_rr(S4,S2,10); break; case 6: cmov_l_rr(S4,S1,5); break; case 7: cmov_l_rr(S4,S1,11); break; case 8: cmov_l_rr(S4,S1,10); break; case 9: cmov_l_rr(S4,S1,4); break; case 10: cmov_l_rr(S4,S1,10); cmov_l_rr(S4,S1,7); break; case 11: cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S1,3); break; case 12: cmov_l_rr(S4,S1,2); break; case 13: cmov_l_rr(S4,S1,6); break; case 14: cmov_l_rr(S4,S1,5); cmov_l_rr(S4,S1,10); break; case 15: mov_l_rr(S4,S1); break; } if (!(opcode & 0x38)) mov_b_rr(reg,S4); #if 0 else { abort(); if (!comp_fp_adr (opcode)) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode, regs); } else put_byte (ad, cc ? 0xff : 0x00); } #endif }