--- nono/m88xx0/m88100ops.cpp 2026/04/29 17:05:07 1.1.1.12 +++ nono/m88xx0/m88100ops.cpp 2026/04/29 17:05:22 1.1.1.14 @@ -10,44 +10,44 @@ #include // 命令のフィールド取り出し -#define FLD_D m88100opf_D(opX) -#define FLD_S1 m88100opf_S1(opX) -#define FLD_S2 m88100opf_S2(opX) -#define FLD_CR m88100opf_CR(opX) -#define B5 m88100opf_B5(opX) -#define M5 m88100opf_M5(opX) -#define W5 m88100opf_W5(opX) -#define O5 m88100opf_O5(opX) -#define IMM16 m88100opf_IMM16(opX) -#define VEC9 m88100opf_VEC9(opX) +#define FLD_D m88100opf_D(reg.opX) +#define FLD_S1 m88100opf_S1(reg.opX) +#define FLD_S2 m88100opf_S2(reg.opX) +#define FLD_CR m88100opf_CR(reg.opX) +#define B5 m88100opf_B5(reg.opX) +#define M5 m88100opf_M5(reg.opX) +#define W5 m88100opf_W5(reg.opX) +#define O5 m88100opf_O5(reg.opX) +#define IMM16 m88100opf_IMM16(reg.opX) +#define VEC9 m88100opf_VEC9(reg.opX) // 符号拡張・シフト済みのディスプレースメント // XXX: (負数の右シフト)GCC only -#define D16 (((int32)(int16)opX) << 2) -#define D26 (((int32)(opX << 6) >> 4)) -#define IsCO ((opX >> 8) & 1) -#define IsCI ((opX >> 9) & 1) +#define D16 (((int32)(int16)reg.opX) << 2) +#define D26 (((int32)(reg.opX << 6) >> 4)) +#define IsCO ((reg.opX >> 8) & 1) +#define IsCI ((reg.opX >> 9) & 1) // レジスタアクセス -#define rD (r[FLD_D]) -#define rS1 (r[FLD_S1]) -#define rS2 (r[FLD_S2]) +#define rD (reg.r[FLD_D]) +#define rS1 (reg.r[FLD_S1]) +#define rS2 (reg.r[FLD_S2]) // ダブルワードの2ワード目 #define FLD_D2 ((FLD_D + 1) & 0x1f) -#define rD2 (r[FLD_D2]) +#define rD2 (reg.r[FLD_D2]) // FP フィールド -#define FP_T1 m88100opf_FP_T1(opX) -#define FP_T2 m88100opf_FP_T2(opX) -#define FP_TD m88100opf_FP_TD(opX) +#define FP_T1 m88100opf_FP_T1(reg.opX) +#define FP_T2 m88100opf_FP_T2(reg.opX) +#define FP_TD m88100opf_FP_TD(reg.opX) // XXX t(サイズ)が原因で Reserved Operand になった時の S1, S2 はどうなる? #define FP_GET(v, t, n) \ do { \ if (t == 0) { \ - v = u2f(r[n]); \ + v = u2f(reg.r[n]); \ } else if (t == 1) { \ - v = u2d(((uint64)r[n] << 32) | r[(n + 1) & 31]); \ + v = u2d(((uint64)reg.r[n] << 32) | reg.r[(n + 1) & 31]); \ } else { \ FPPreciseException(FPECR_FROP); \ return; \ @@ -57,28 +57,28 @@ do { \ #define FP_SET(t, n, v) \ do { \ if (t == 0) { \ - r[n] = f2u(v); \ + reg.r[n] = f2u(v); \ } else if (t == 1) { \ uint64 tmp = d2u(v); \ - r[n] = tmp >> 32; \ + reg.r[n] = tmp >> 32; \ if (__predict_true(n != 31)) \ - r[n + 1] = (uint32)tmp; \ + reg.r[n + 1] = (uint32)tmp; \ } else { \ FPPreciseException(FPECR_FROP); \ return; \ } \ } while (0) -// ブランチ命令入り口 -inline void -m88kcpu::EnterBranch(uint32 toaddr) +// ブランチ命令 +void +MPU88xx0Device::DoBranch(uint32 toaddr, bool next_exec) { // ジャンプ先アドレスの下位2bitはマスクされる toaddr &= ~3; // ブランチヒストリに登録しつつ、 // ブランチヒストリからブランチ状況を取得 - auto e = brhist.AddEntry(xip | (IsSuper() ? 1 : 0), toaddr, opX); - fip = toaddr; + auto e = brhist.AddEntry(reg.xip | (IsSuper() ? 1 : 0), toaddr, reg.opX); + reg.fip = toaddr; // STOP 検出。 // m88k には STOP 状態 (何もせず割り込みだけ待つ状態。m68k の STOP 命令 @@ -109,9 +109,9 @@ m88kcpu::EnterBranch(uint32 toaddr) // e.count == 2 のときだけ STOP の検証をすれば良い。 // d はブランチ間の命令数 - uint32 d = (xip - toaddr) / sizeof(uint32); + uint32 d = (reg.xip - toaddr) / sizeof(uint32); // 遅延ブランチなら 1 命令余分に実行するはずなので 1 足す - if ((opX & (1 << 26)) != 0) { + if (next_exec) { d++; } // ブランチ間の命令がすべて NOP なら STOP ということにする。 @@ -129,34 +129,23 @@ m88kcpu::EnterBranch(uint32 toaddr) } // STOP ではなかったら、あとは放置していい } -} - -// 通常(即時)ブランチ出口 -inline void -m88kcpu::ExitBranch() -{ - // re-fetch branched instruction - fetch(); -} -// 遅延ブランチ出口 -// 速度を稼ぐため、ビット反転だけでこれを区別しているので、 -// 同じ op 中で複数回呼び出さないこと。 -inline void -m88kcpu::ExitDelayBranch() -{ - opF ^= DELAYSLOT; + if (next_exec == false) { + // 通常(即時)ブランチ出口 + // re-fetch branched instruction + fetch(); + } } // ロードストアユニットの usr の処理。 // 正常なら true を返す (ので呼び出し側は実行継続)、 // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 inline bool -m88kcpu::ldst_usr(uint32& usr) +MPU88xx0Device::ldst_usr(uint32& usr) { - usr = (opX & (1 << 8)) ? DM_USR : 0; + usr = (reg.opX & (1 << 8)) ? DM_USR : 0; if (IsUser() && usr) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return false; } return true; @@ -173,9 +162,9 @@ m88kcpu::ldst_usr(uint32& usr) // ロードストアユニットの scale の処理。addr を返す。 inline uint32 -m88kcpu::ldst_scale(uint32 size) +MPU88xx0Device::ldst_scale(uint32 size) { - if ((opX & (1 << 9)) != 0) { + if ((reg.opX & (1 << 9)) != 0) { return rS1 + rS2 * size; } else { return rS1 + rS2; @@ -186,13 +175,13 @@ m88kcpu::ldst_scale(uint32 size) // 正常なら true を返す (ので呼び出し側は実行継続)、 // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 inline bool -m88kcpu::ldst_align(uint32 size, uint32& addr) +MPU88xx0Device::ldst_align(uint32 size, uint32& addr) { if ((addr & (size - 1)) != 0) { if (IsMXM()) { addr &= ~(size - 1); } else { - Exception(M88K_EXCEP_MISALIGNED); + Exception(EXCEP_MISALIGNED); return false; } } @@ -323,7 +312,7 @@ OP_DEF(xmem_bu_imm) AddCycle(4); // Table.7-3 lastaddr = addr; - tmp = cmmu[1].xmem_8(addr, rD & 0xff); + tmp = cmmu[1]->xmem_8(addr, rD & 0xff); if ((int64)tmp < 0) { XmemDataException(addr, DM_BU | DM_LOCK); return; @@ -345,7 +334,7 @@ OP_DEF(xmem_w_imm) AddCycle(4); // Table.7-3 lastaddr = addr; - tmp = cmmu[1].xmem_32(addr, rD); + tmp = cmmu[1]->xmem_32(addr, rD); if ((int64)tmp < 0) { XmemDataException(addr, DM_W | DM_LOCK); return; @@ -367,7 +356,7 @@ OP_DEF(ld_hu_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1].load_16(addr); + data = cmmu[1]->load_16(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_HU); return; @@ -389,7 +378,7 @@ OP_DEF(ld_bu_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1].load_8(addr); + data = cmmu[1]->load_8(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_BU); return; @@ -411,13 +400,13 @@ OP_DEF(ld_d_imm) AddCycle(4); // Table.7-3 lastaddr = addr; - data1 = cmmu[1].load_32(addr); + data1 = cmmu[1]->load_32(addr); if ((int64)data1 < 0) { ReadDataException64(addr, DM_D1); return; } addr += 4; - data2 = cmmu[1].load_32(addr); + data2 = cmmu[1]->load_32(addr); if ((int64)data2 < 0) { ReadDataException64(addr, DM_D2); return; @@ -425,7 +414,7 @@ OP_DEF(ld_d_imm) rD = data1; rD2 = data2; - r[0] = 0; + reg.r[0] = 0; } // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn @@ -440,7 +429,7 @@ OP_DEF(ld_w_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1].load_32(addr); + data = cmmu[1]->load_32(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_W); return; @@ -462,7 +451,7 @@ OP_DEF(ld_h_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1].load_16(addr); + data = cmmu[1]->load_16(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_H); return; @@ -484,7 +473,7 @@ OP_DEF(ld_b_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1].load_8(addr); + data = cmmu[1]->load_8(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_B); return; @@ -506,13 +495,13 @@ OP_DEF(st_d_imm) AddCycle(1 + 4); // Table.7-3 lastaddr = addr; - rv = cmmu[1].store_32(addr, rD); + rv = cmmu[1]->store_32(addr, rD); if ((int64)rv < 0) { WriteDataException64(addr, DM_D1); return; } addr += 4; - rv = cmmu[1].store_32(addr, rD2); + rv = cmmu[1]->store_32(addr, rD2); if ((int64)rv < 0) { WriteDataException64(addr, DM_D2); return; @@ -531,7 +520,7 @@ OP_DEF(st_w_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - rv = cmmu[1].store_32(addr, rD); + rv = cmmu[1]->store_32(addr, rD); if ((int64)rv < 0) { WriteDataException32(addr, DM_W); return; @@ -550,7 +539,7 @@ OP_DEF(st_h_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - rv = cmmu[1].store_16(addr, rD & 0xffff); + rv = cmmu[1]->store_16(addr, rD & 0xffff); if ((int64)rv < 0) { WriteDataException32(addr, DM_H); return; @@ -569,7 +558,7 @@ OP_DEF(st_b_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - rv = cmmu[1].store_8(addr, rD & 0xff); + rv = cmmu[1]->store_8(addr, rD & 0xff); if ((int64)rv < 0) { WriteDataException32(addr, DM_B); return; @@ -699,7 +688,7 @@ OP_DEF(divu_imm) AddCycle(38); // Table.7-6 (ただしざっくり) if (IMM16 == 0) { - Exception(M88K_EXCEP_INT_DIV); + Exception(EXCEP_INT_DIV); return; } if (FLD_D == 0) @@ -728,7 +717,7 @@ OP_DEF(add_imm) uint32 imm = IMM16; uint32 res = rS1 + imm; if (isovf_add(rS1, imm, res)) { - Exception(M88K_EXCEP_INT_OVF); + Exception(EXCEP_INT_OVF); return; } if (FLD_D == 0) @@ -742,7 +731,7 @@ OP_DEF(sub_imm) uint32 imm = IMM16; uint32 res = rS1 - imm; if (isovf_sub(rS1, imm, res)) { - Exception(M88K_EXCEP_INT_OVF); + Exception(EXCEP_INT_OVF); return; } if (FLD_D == 0) @@ -761,7 +750,7 @@ OP_DEF(div_imm) AddCycle(38); // Table.7-6 (ただしざっくり) if ((int32)rS1 < 0 || IMM16 == 0) { - Exception(M88K_EXCEP_INT_DIV); + Exception(EXCEP_INT_DIV); return; } if (FLD_D == 0) @@ -781,19 +770,19 @@ OP_DEF(cmp_imm) OP_DEF(ldcr) { if (IsUser()) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } - if (FLD_CR > countof(cr)) { + if (FLD_CR > countof(reg.cr)) { // 制御レジスタ番号が範囲外の時は // 88100 では undocumented、 // 88110 では Unimplemented Opcode 例外。 - Exception(M88K_EXCEP_UNIMPL_OP); + Exception(EXCEP_UNIMPL_OP); return; } if (FLD_D == 0) return; - rD = cr[FLD_CR]; + rD = reg.cr[FLD_CR]; } // 100000_DDDDDzzzzz_01001n_nnnnnzzzzz @@ -825,24 +814,24 @@ OP_DEF(fldcr) return; // XXX 内部がバグってなければ読み出す時にマスクする必要はないが、一応 - rD = fcr[n] & fcr_mask[n]; + rD = reg.fcr[n] & reg.fcr_mask[n]; } // 100000_zzzzzSSSSS_10000n_nnnnnsssss OP_DEF(stcr) { if (IsUser()) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } - if (FLD_CR > countof(cr)) { + if (FLD_CR > countof(reg.cr)) { // 制御レジスタ番号が範囲外の時は // 88100 では undocumented、 // 88110 では Unimplemented Opcode 例外。 - Exception(M88K_EXCEP_UNIMPL_OP); + Exception(EXCEP_UNIMPL_OP); return; } - cr[FLD_CR] = rS1; + reg.cr[FLD_CR] = rS1; if (FLD_CR == 1) { SetPSR(); } @@ -874,11 +863,11 @@ OP_DEF(fstcr) } } - fcr[n] = rS1 & fcr_mask[n]; + reg.fcr[n] = rS1 & reg.fcr_mask[n]; // FPCR が変更されたら、ホストの丸めモードも更新 if (n == 10) { - uint32 rm = (fpcr >> 14) & 3; + uint32 rm = (reg.fpcr >> 14) & 3; std::fesetround(rm_to_round[rm]); } } @@ -889,23 +878,23 @@ OP_DEF(xcr) uint32 tmp; if (IsUser()) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } - if (FLD_CR > countof(cr)) { + if (FLD_CR > countof(reg.cr)) { // 制御レジスタ番号が範囲外の時は // 88100 では undocumented、 // 88110 では Unimplemented Opcode 例外。 - Exception(M88K_EXCEP_UNIMPL_OP); + Exception(EXCEP_UNIMPL_OP); return; } tmp = rS1; - rD = cr[FLD_CR]; - cr[FLD_CR] = tmp; + rD = reg.cr[FLD_CR]; + reg.cr[FLD_CR] = tmp; if (FLD_CR == 1) { SetPSR(); } - r[0] = 0; + reg.r[0] = 0; } // 100000_DDDDDSSSSS_11001n_nnnnnsssss @@ -930,8 +919,8 @@ OP_DEF(fxcr) goto exchange; } else if (__predict_false(n < 9)) { // FCR1..8 は読み込み専用レジスタなので、読み出す側のみ - rD = fcr[n] & fcr_mask[n]; - r[0] = 0; + rD = reg.fcr[n] & reg.fcr_mask[n]; + reg.r[0] = 0; return; } else if (__predict_false(n < 62)) { // FCR9..61 は未実装レジスタなので、0 が読み出せるのみ @@ -943,10 +932,10 @@ OP_DEF(fxcr) exchange: uint32 tmp = rS1; - rD = fcr[n] & fcr_mask[n]; - fcr[n] = tmp & fcr_mask[n]; + rD = reg.fcr[n] & reg.fcr_mask[n]; + reg.fcr[n] = tmp & reg.fcr_mask[n]; - r[0] = 0; + reg.r[0] = 0; } // 100001_DDDDDSSSSS_00000n_nnnnnsssss @@ -1069,7 +1058,7 @@ OP_DEF(fcmp) // int, nint, trnc 命令の共通部 void -m88kcpu::ops_int(int rndmode) +MPU88xx0Device::ops_int(int rndmode) { double src; double res; @@ -1144,34 +1133,30 @@ OP_DEF(fdiv) OP_DEF(br) { AddCycle(1); // Table.7-5 - EnterBranch(xip + D26); - ExitBranch(); + DoBranch(reg.xip + D26, false); } // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(br_n) { AddCycle(0); // Table.7-5 - EnterBranch(xip + D26); - ExitDelayBranch(); + DoBranch(reg.xip + D26, true); } // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(bsr) { AddCycle(1); // Table.7-5 - EnterBranch(xip + D26); - r[1] = nip; - ExitBranch(); + reg.r[1] = reg.nip; + DoBranch(reg.xip + D26, false); } // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(bsr_n) { AddCycle(0); // Table.7-5 - EnterBranch(xip + D26); - r[1] = nip + 4; - ExitDelayBranch(); + reg.r[1] = reg.nip + 4; + DoBranch(reg.xip + D26, true); } // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn @@ -1179,8 +1164,7 @@ OP_DEF(bb0) { if ((rS1 & (1 << B5)) == 0) { AddCycle(1); // Table.7-5 - EnterBranch(xip + D16); - ExitBranch(); + DoBranch(reg.xip + D16, false); } } @@ -1188,8 +1172,7 @@ OP_DEF(bb0) OP_DEF(bb0_n) { if ((rS1 & (1 << B5)) == 0) { - EnterBranch(xip + D16); - ExitDelayBranch(); + DoBranch(reg.xip + D16, true); } } @@ -1198,8 +1181,7 @@ OP_DEF(bb1) { if ((rS1 & (1 << B5)) != 0) { AddCycle(1); // Table.7-5 - EnterBranch(xip + D16); - ExitBranch(); + DoBranch(reg.xip + D16, false); } } @@ -1207,8 +1189,7 @@ OP_DEF(bb1) OP_DEF(bb1_n) { if ((rS1 & (1 << B5)) != 0) { - EnterBranch(xip + D16); - ExitDelayBranch(); + DoBranch(reg.xip + D16, true); } } @@ -1217,8 +1198,7 @@ OP_DEF(bcnd) { if ((acc_cnd(rS1) & M5) != 0) { AddCycle(1); // Table.7-5 - EnterBranch(xip + D16); - ExitBranch(); + DoBranch(reg.xip + D16, false); } } @@ -1226,8 +1206,7 @@ OP_DEF(bcnd) OP_DEF(bcnd_n) { if ((acc_cnd(rS1) & M5) != 0) { - EnterBranch(xip + D16); - ExitDelayBranch(); + DoBranch(reg.xip + D16, true); } } @@ -1303,7 +1282,7 @@ OP_DEF(rot_1) OP_DEF(tb0) { if (IsUser() && VEC9 < 128) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } if ((rS1 & (1 << B5)) == 0) { @@ -1315,7 +1294,7 @@ OP_DEF(tb0) OP_DEF(tb1) { if (IsUser() && VEC9 < 128) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } if ((rS1 & (1 << B5)) != 0) { @@ -1340,7 +1319,7 @@ OP_DEF(tb1) if (IsSuper() && VEC9 == 0xff) { const auto& e = brhist.entry[brhist.top]; if (e.count == 3 - && e.to == xip + && e.to == reg.xip && e.from - e.to < 16) { ChangeState(CPU_STATE_STOP); } @@ -1352,7 +1331,7 @@ OP_DEF(tb1) OP_DEF(tcnd) { if (IsUser() && VEC9 < 128) { - Exception(M88K_EXCEP_PRIV); + Exception(EXCEP_PRIV); return; } if ((acc_cnd(rS1) & M5) != 0) { @@ -1374,9 +1353,9 @@ OP_DEF(xmem_bu) lastaddr = addr; // 例外安全のために都度 S/U ビットを制御 - if (__predict_false(usr)) cmmu[1].SetSuper(false); - tmp = cmmu[1].xmem_8(addr, rD & 0xff); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + tmp = cmmu[1]->xmem_8(addr, rD & 0xff); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)tmp < 0) { XmemDataException(addr, DM_BU | DM_LOCK | usr); return; @@ -1400,9 +1379,9 @@ OP_DEF(xmem_w) lastaddr = addr; // 例外安全のために都度 S/U ビットを制御 - if (__predict_false(usr)) cmmu[1].SetSuper(false); - tmp = cmmu[1].xmem_32(addr, rD); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + tmp = cmmu[1]->xmem_32(addr, rD); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)tmp < 0) { XmemDataException(addr, DM_W | DM_LOCK | usr); return; @@ -1426,9 +1405,9 @@ OP_DEF(ld_hu) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data = cmmu[1].load_16(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data = cmmu[1]->load_16(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data < 0) { ReadDataException32(addr, DM_HU | usr); @@ -1452,9 +1431,9 @@ OP_DEF(ld_bu) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data = cmmu[1].load_8(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data = cmmu[1]->load_8(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data < 0) { ReadDataException32(addr, DM_BU | usr); @@ -1479,9 +1458,9 @@ OP_DEF(ld_d) lastaddr = addr; // 例外安全のために都度 S/U ビットを制御 - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data1 = cmmu[1].load_32(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data1 = cmmu[1]->load_32(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data1 < 0) { ReadDataException64(addr, DM_D1 | usr); @@ -1489,9 +1468,9 @@ OP_DEF(ld_d) } addr += 4; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data2 = cmmu[1].load_32(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data2 = cmmu[1]->load_32(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data2 < 0) { ReadDataException64(addr, DM_D2 | usr); @@ -1499,7 +1478,7 @@ OP_DEF(ld_d) } rD = data1; rD2 = data2; - r[0] = 0; + reg.r[0] = 0; } // 111101_DDDDDSSSSS_000101_xU000sssss @@ -1515,9 +1494,9 @@ OP_DEF(ld_w) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data = cmmu[1].load_32(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data = cmmu[1]->load_32(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data < 0) { ReadDataException32(addr, DM_W | usr); @@ -1541,9 +1520,9 @@ OP_DEF(ld_h) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data = cmmu[1].load_16(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data = cmmu[1]->load_16(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data < 0) { ReadDataException32(addr, DM_H | usr); @@ -1567,9 +1546,9 @@ OP_DEF(ld_b) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - data = cmmu[1].load_8(addr); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + data = cmmu[1]->load_8(addr); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)data < 0) { ReadDataException32(addr, DM_B | usr); @@ -1593,9 +1572,9 @@ OP_DEF(st_d) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - rv = cmmu[1].store_32(addr, rD); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + rv = cmmu[1]->store_32(addr, rD); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)rv < 0) { WriteDataException64(addr, DM_D1 | usr); @@ -1604,9 +1583,9 @@ OP_DEF(st_d) addr += 4; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - rv = cmmu[1].store_32(addr, rD2); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + rv = cmmu[1]->store_32(addr, rD2); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)rv < 0) { WriteDataException64(addr, DM_D2 | usr); @@ -1627,9 +1606,9 @@ OP_DEF(st_w) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - rv = cmmu[1].store_32(addr, rD); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + rv = cmmu[1]->store_32(addr, rD); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)rv < 0) { WriteDataException32(addr, DM_W | usr); @@ -1650,9 +1629,9 @@ OP_DEF(st_h) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - rv = cmmu[1].store_16(addr, rD & 0xffff); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + rv = cmmu[1]->store_16(addr, rD & 0xffff); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)rv < 0) { WriteDataException32(addr, DM_H | usr); @@ -1673,9 +1652,9 @@ OP_DEF(st_b) lastaddr = addr; - if (__predict_false(usr)) cmmu[1].SetSuper(false); - rv = cmmu[1].store_8(addr, rD & 0xff); - if (__predict_false(usr)) cmmu[1].SetSuper(true); + if (__predict_false(usr)) cmmu[1]->SetSuper(false); + rv = cmmu[1]->store_8(addr, rD & 0xff); + if (__predict_false(usr)) cmmu[1]->SetSuper(true); if ((int64)rv < 0) { WriteDataException32(addr, DM_B | usr); @@ -1831,7 +1810,7 @@ OP_DEF(divu) AddCycle(38); // Table.7-6 (ただしざっくり) if (rS2 == 0) { - Exception(M88K_EXCEP_INT_DIV); + Exception(EXCEP_INT_DIV); return; } if (FLD_D == 0) @@ -1862,7 +1841,7 @@ OP_DEF(add) res += GetCY(); } if (isovf_add(rS1, rS2, res)) { - Exception(M88K_EXCEP_INT_OVF); + Exception(EXCEP_INT_OVF); return; } @@ -1888,7 +1867,7 @@ OP_DEF(sub) res += 1; } if (isovf_sub(rS1, rS2, res)) { - Exception(M88K_EXCEP_INT_OVF); + Exception(EXCEP_INT_OVF); return; } @@ -1912,7 +1891,7 @@ OP_DEF(div) AddCycle(38); // Table.7-6 (ただしざっくり) if ((int32)rS1 < 0 || (int32)rS2 <= 0) { - Exception(M88K_EXCEP_INT_DIV); + Exception(EXCEP_INT_DIV); return; } if (FLD_D == 0) @@ -2003,34 +1982,32 @@ OP_DEF(rot_2) OP_DEF(jmp) { AddCycle(1); // Table.7-5 - EnterBranch(rS2); - ExitBranch(); + DoBranch(rS2, false); } // 111101_zzzzzzzzzz_110001_00000sssss OP_DEF(jmp_n) { AddCycle(0); // Table.7-5 - EnterBranch(rS2); - ExitDelayBranch(); + DoBranch(rS2, true); } // 111101_zzzzzzzzzz_110010_00000sssss OP_DEF(jsr) { AddCycle(1); // Table.7-5 - EnterBranch(rS2); - r[1] = nip; - ExitBranch(); + uint32 toaddr = rS2; + reg.r[1] = reg.nip; + DoBranch(toaddr, false); } // 111101_zzzzzzzzzz_110011_00000sssss OP_DEF(jsr_n) { AddCycle(0); // Table.7-5 - EnterBranch(rS2); - r[1] = nip + 4; - ExitDelayBranch(); + uint32 toaddr = rS2; + reg.r[1] = reg.nip + 4; + DoBranch(toaddr, true); } // 111101_DDDDDzzzzz_111010_00000sssss @@ -2081,10 +2058,10 @@ OP_DEF(rte) { AddCycle(2); // Table.7-5 - SetPSR(epsr); + SetPSR(reg.epsr); - // LUNA88K の ROM1.2 は sxip, snip, sfip を制御してくる。 - // ROM1.2 の DAE ハンドラは、 + // LUNA-88K の PROM 1.20 は sxip, snip, sfip を制御してくる。 + // PROM 1.20 の DAE ハンドラは、 // sxip = INVALID // snip = 0 (INVALID) // sfip = original sxip @@ -2092,20 +2069,11 @@ OP_DEF(rte) // CPU は sxip は評価しない。snip は 0 なので、無効として nop 扱い。 // (実際はクロックが消費されるかも?) // sfip が VALID なので、そこから実行を再開する。 - if ((snip & SIP_V)) { - EnterBranch(snip & SIP_MASK); - ExitBranch(); - fip = sfip & SIP_MASK; + if ((reg.snip & SIP_V)) { + DoBranch(reg.snip & SIP_MASK, false); + reg.fip = reg.sfip & SIP_MASK; } else { - EnterBranch(sfip & SIP_MASK); - ExitBranch(); - } - - // ディレイスロットにいた命令かどうかをやんわり復元する。 - // 88110 ではこの情報が E?IP に保持されているが - // 88100 にはない。 - if (nip + 4 != fip) { - ExitDelayBranch(); + DoBranch(reg.sfip & SIP_MASK, false); } } @@ -2113,7 +2081,7 @@ OP_DEF(rte) OP_DEF(tbnd_1) { if (rS1 > rS2) { - Exception(M88K_EXCEP_BOUNDS); + Exception(EXCEP_BOUNDS); } } @@ -2121,7 +2089,7 @@ OP_DEF(tbnd_1) OP_DEF(tbnd_2) { if (rS1 > IMM16) { - Exception(M88K_EXCEP_BOUNDS); + Exception(EXCEP_BOUNDS); } }