--- nono/m88xx0/m88100ops.cpp 2026/04/29 17:05:15 1.1.1.13 +++ nono/m88xx0/m88100ops.cpp 2026/04/29 17:05:26 1.1.1.15 @@ -70,7 +70,7 @@ do { \ } while (0) // ブランチ命令 -inline void +void MPU88xx0Device::DoBranch(uint32 toaddr, bool next_exec) { // ジャンプ先アドレスの下位2bitはマスクされる @@ -137,20 +137,6 @@ MPU88xx0Device::DoBranch(uint32 toaddr, } } -// ロードストアユニットの usr の処理。 -// 正常なら true を返す (ので呼び出し側は実行継続)、 -// 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 -inline bool -MPU88xx0Device::ldst_usr(uint32& usr) -{ - usr = (reg.opX & (1 << 8)) ? DM_USR : 0; - if (IsUser() && usr) { - Exception(EXCEP_PRIV); - return false; - } - return true; -} - // MEMO: ロードストアでの usr の処理で、CMMU に対して // usr を引数ではなくSetSuper() の呼び出しで渡すようにしている。 // データのロードストアだけがあるのなら usr を引数で渡すほうが @@ -171,34 +157,30 @@ MPU88xx0Device::ldst_scale(uint32 size) } } -// ロードストアユニットの align の処理。 -// 正常なら true を返す (ので呼び出し側は実行継続)、 -// 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 -inline bool -MPU88xx0Device::ldst_align(uint32 size, uint32& addr) -{ - if ((addr & (size - 1)) != 0) { - if (IsMXM()) { - addr &= ~(size - 1); - } else { - Exception(EXCEP_MISALIGNED); - return false; - } - } - return true; -} - -// ロードストアユニットの usr と scale の処理 (呼び出し用マクロ) +// ロードストアユニットの usr と scale の処理。 +// 正常な場合は usr と addr を更新する。 +// 例外の場合は例外を処理してこのマクロが展開してある関数から return する。 #define LDST_USR_SCALE(size) do { \ - if (ldst_usr(usr) == false) \ + usr = (reg.opX & (1U << 8)) ? DM_USR : 0; \ + if (IsUser() && usr) { \ + Exception(EXCEP_PRIV); \ return; \ + } \ addr = ldst_scale(size); \ } while (0) -// ロードストアユニットの align の処理 (呼び出し用マクロ) +// ロードストアユニットの align の処理。 +// 正常な場合は addr を更新する可能性がある。 +// 例外の場合は例外を処理してこのマクロが展開されてる関数から return する。 #define LDST_ALIGN(size) do { \ - if (ldst_align(size, addr) == false) \ - return; \ + if ((addr & (size - 1)) != 0) { \ + if (IsMXM()) { \ + addr &= ~(size - 1); \ + } else { \ + Exception(EXCEP_MISALIGNED); \ + return; \ + } \ + } \ } while (0) // ロードストアユニットのまとめたもの @@ -207,6 +189,18 @@ MPU88xx0Device::ldst_align(uint32 size, LDST_ALIGN(size); \ } while (0) +// .usr 開始。 +#define ENTER_USR() do { \ + if (__predict_false(usr)) \ + cmmu[1]->SetSuper(false); \ +} while (0) + +// .usr 終了。 +#define LEAVE_USR() do { \ + if (__predict_false(usr)) \ + cmmu[1]->SetSuper(true); \ +} while (0) + // 幅規制付き算術左シフト static inline uint32 ASL(uint32 a, int n) @@ -224,7 +218,7 @@ ASR(uint32 a, int n) { if (n <= 0) return a; - if (n >= 32) + if (n >= 31) return (int32)a < 0 ? -1 : 0; // XXX: 負数の右シフト return (int32)a >> n; @@ -255,10 +249,10 @@ isovf_sub(uint32 s1, uint32 s2, uint32 r } // bcnd のやつ -static inline int +static inline uint acc_cnd(uint32 r) { - int rv; + uint rv; if ((r & 0x80000000) != 0) { if (r == 0x80000000) { rv = 0x8; @@ -312,7 +306,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_1(addr, rD & 0xff); if ((int64)tmp < 0) { XmemDataException(addr, DM_BU | DM_LOCK); return; @@ -334,7 +328,7 @@ OP_DEF(xmem_w_imm) AddCycle(4); // Table.7-3 lastaddr = addr; - tmp = cmmu[1]->xmem_32(addr, rD); + tmp = cmmu[1]->xmem_4(addr, rD); if ((int64)tmp < 0) { XmemDataException(addr, DM_W | DM_LOCK); return; @@ -356,7 +350,7 @@ OP_DEF(ld_hu_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1]->load_16(addr); + data = cmmu[1]->load_2(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_HU); return; @@ -378,7 +372,7 @@ OP_DEF(ld_bu_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1]->load_8(addr); + data = cmmu[1]->load_1(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_BU); return; @@ -400,13 +394,13 @@ OP_DEF(ld_d_imm) AddCycle(4); // Table.7-3 lastaddr = addr; - data1 = cmmu[1]->load_32(addr); + data1 = cmmu[1]->load_4(addr); if ((int64)data1 < 0) { ReadDataException64(addr, DM_D1); return; } addr += 4; - data2 = cmmu[1]->load_32(addr); + data2 = cmmu[1]->load_4(addr); if ((int64)data2 < 0) { ReadDataException64(addr, DM_D2); return; @@ -429,7 +423,7 @@ OP_DEF(ld_w_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1]->load_32(addr); + data = cmmu[1]->load_4(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_W); return; @@ -451,7 +445,7 @@ OP_DEF(ld_h_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1]->load_16(addr); + data = cmmu[1]->load_2(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_H); return; @@ -473,7 +467,7 @@ OP_DEF(ld_b_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - data = cmmu[1]->load_8(addr); + data = cmmu[1]->load_1(addr); if ((int64)data < 0) { ReadDataException32(addr, DM_B); return; @@ -495,13 +489,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_4(addr, rD); if ((int64)rv < 0) { WriteDataException64(addr, DM_D1); return; } addr += 4; - rv = cmmu[1]->store_32(addr, rD2); + rv = cmmu[1]->store_4(addr, rD2); if ((int64)rv < 0) { WriteDataException64(addr, DM_D2); return; @@ -520,7 +514,7 @@ OP_DEF(st_w_imm) AddCycle(3); // Table.7-3 lastaddr = addr; - rv = cmmu[1]->store_32(addr, rD); + rv = cmmu[1]->store_4(addr, rD); if ((int64)rv < 0) { WriteDataException32(addr, DM_W); return; @@ -539,7 +533,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_2(addr, rD & 0xffff); if ((int64)rv < 0) { WriteDataException32(addr, DM_H); return; @@ -558,7 +552,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_1(addr, rD & 0xff); if ((int64)rv < 0) { WriteDataException32(addr, DM_B); return; @@ -1353,9 +1347,10 @@ 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); + ENTER_USR(); + tmp = cmmu[1]->xmem_1(addr, rD & 0xff); + LEAVE_USR(); + if ((int64)tmp < 0) { XmemDataException(addr, DM_BU | DM_LOCK | usr); return; @@ -1379,9 +1374,10 @@ 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); + ENTER_USR(); + tmp = cmmu[1]->xmem_4(addr, rD); + LEAVE_USR(); + if ((int64)tmp < 0) { XmemDataException(addr, DM_W | DM_LOCK | usr); return; @@ -1405,9 +1401,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); + ENTER_USR(); + data = cmmu[1]->load_2(addr); + LEAVE_USR(); if ((int64)data < 0) { ReadDataException32(addr, DM_HU | usr); @@ -1431,9 +1427,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); + ENTER_USR(); + data = cmmu[1]->load_1(addr); + LEAVE_USR(); if ((int64)data < 0) { ReadDataException32(addr, DM_BU | usr); @@ -1458,9 +1454,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); + ENTER_USR(); + data1 = cmmu[1]->load_4(addr); + LEAVE_USR(); if ((int64)data1 < 0) { ReadDataException64(addr, DM_D1 | usr); @@ -1468,9 +1464,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); + ENTER_USR(); + data2 = cmmu[1]->load_4(addr); + LEAVE_USR(); if ((int64)data2 < 0) { ReadDataException64(addr, DM_D2 | usr); @@ -1494,9 +1490,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); + ENTER_USR(); + data = cmmu[1]->load_4(addr); + LEAVE_USR(); if ((int64)data < 0) { ReadDataException32(addr, DM_W | usr); @@ -1520,9 +1516,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); + ENTER_USR(); + data = cmmu[1]->load_2(addr); + LEAVE_USR(); if ((int64)data < 0) { ReadDataException32(addr, DM_H | usr); @@ -1546,9 +1542,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); + ENTER_USR(); + data = cmmu[1]->load_1(addr); + LEAVE_USR(); if ((int64)data < 0) { ReadDataException32(addr, DM_B | usr); @@ -1572,9 +1568,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); + ENTER_USR(); + rv = cmmu[1]->store_4(addr, rD); + LEAVE_USR(); if ((int64)rv < 0) { WriteDataException64(addr, DM_D1 | usr); @@ -1583,9 +1579,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); + ENTER_USR(); + rv = cmmu[1]->store_4(addr, rD2); + LEAVE_USR(); if ((int64)rv < 0) { WriteDataException64(addr, DM_D2 | usr); @@ -1606,9 +1602,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); + ENTER_USR(); + rv = cmmu[1]->store_4(addr, rD); + LEAVE_USR(); if ((int64)rv < 0) { WriteDataException32(addr, DM_W | usr); @@ -1629,9 +1625,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); + ENTER_USR(); + rv = cmmu[1]->store_2(addr, rD & 0xffff); + LEAVE_USR(); if ((int64)rv < 0) { WriteDataException32(addr, DM_H | usr); @@ -1652,9 +1648,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); + ENTER_USR(); + rv = cmmu[1]->store_1(addr, rD & 0xff); + LEAVE_USR(); if ((int64)rv < 0) { WriteDataException32(addr, DM_B | usr);