--- nono/m680x0/m68030ea.h 2026/04/29 17:04:28 1.1 +++ nono/m680x0/m68030ea.h 2026/04/29 17:05:15 1.1.1.3 @@ -1,434 +1,168 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // + // EA -// #pragma once -// EA は大別して5種類。 -// -// |d m rxwp | 制御 CalcCtrl サイズ不問 -// |dam+-rxw | 可変 CalcData B/W/L -// | m rxwp | MMU CalcMMU サイズ不問 -// |dam+-rxwpi| FPU CalcFPU B/W/L/S/D/X/P -// |d m+-rxwpi| データ FetchData B/W/L -// |dam+-rxwpi| All FetchAll B/W/L -// -// CalcCtrl はユーザーズマニュアルで「制御(Control)」と呼ばれている -// グループで、デスティネーション側のため EA の計算のみ。 -// また (An)+/-(An) を含まないため、サイズに関係なく1種類だけでよい。 -// -// CalcData はユーザーズマニュアルで「可変」と呼ばれているグループで、 -// デスティネーション側のため EA の計算のみ。B/W/L -// -// CalcMMU は対 MMU 用に勝手に用意したもの。 -// -// CalcFPU は対 FPU 用。ソースであっても CalcFPU を使用する。 -// サイズは B/W/L/S/D/X/P。 -// フェッチサイクルは別途存在するはずだが不詳。 -// -// FetchData はユーザーズマニュアルで「データ(Data)」と呼ばれている -// グループで、ソース側のため EA 計算および値の取得。B/W/L -// -// FetchAll はユーザーズマニュアルのここには記載がないグループで、 -// ソース側のため EA 計算および値の取得。B/W/L -// -// CalcCtrl、CalcData でアドレッシングモードに D や A が含まれている場合は -// その命令のデスティネーションに Dn、An が指定できるという意味であり、 -// EA 処理であるここには関係ない。 -// EA 計算より前に呼出側で条件分けして処理すること。 -// -// CalcCtrl、CalcData と FetchData には (*) 印の例外があるので留意。 -// -// (CalcCtrl) -// | m rxwp | CMP2/CHK2 -// | m rxwp | JMP/JSR -// | m rxwp | LEA/PEA -// |d m rxwp | BFEXT*/BFFFO/BFTST -// |d m rxw | (*) BFCHG/BFCLR/BFINS/BFSET {#o:#w} -// -// (CalcData) -// | m+-rxw | ADD/SUB/CMP Dx, -// | m+-rxw | CAS/TAS -// | m+-rxw | MOVES ,Rn -// | m+-rxw | shift/rotate.W -// | m+-rxw | BCHG/BCLR/BSET src, -// |d m+-rxw | ADDI/SUBI Dx, -// |d m+-rwx | NBCD -// |d m+-rxw | AND/OR/EOR Dx, -// |d m+-rxw | CLR/NEG/NEGX/NOT/TST/Scc -// |d m+-rxw | MOVE CCR/SR, -// |dam+-rxw | ADDQ/SUBQ #qqq, -// |dam+-rxw | (*) MOVE の dst 側。EA の分類的には CalcData だが、 -// 下位6ビットの IR ではないので、cea_data_NN() ではなく -// 各々 cea_XXXX() のほうを個別に呼ぶこと。 -// -// (CalcMMU) -// | m rxw | MMU -// -// (CalcFPU) -// |d m+-rxw | FScc.B -// |dam+-rxw | FMOVE.f FPn, -// |dam+-rxw | FMOVE.L ctl, -// |dam+-rxw | FMOVEM.L ctl, -// |d m+-rxwpi| Fgen ,FPn -// |d m+-rxwpi| FMOVE.f ,FPn -// |dam+-rwxpi| FMOVE.L ,ctl -// |dam+-rxwpi| FMOVEM.L ,ctl -// 実際にどのアドレッシングモードが有効かどうかは極力個別の命令内で判断する? -// ここは実行サイクル数的な分類。 -// -// (FetchData) -// |d m+-rxwpi| AND/OR/CHK ,Dn -// |d m+-rxwpi| MOVE.B ,dst -// |d m+-rxwpi| MOVE ,CCR/SR -// |d m+-rxwpi| MUL*/DIV* ,Dn -// |d m+-rxwp | (*) TST.B -// |d m+-rxwp | (*) CMPI #, -// | m+-rxwp | (*) BTST.B #, -// | m+-rxwpi| (*) BTST.B Dx, -// -// (FetchAll) -// |dam+-rxwpi| ADD/SUB/CMP ,Dn -// |dam+-rxwpi| MOVEA/ADDA/SUBA/CMPA ,An -// |dam+-rxwpi| TST.WL -// |dam+-rxwpi| MOVE.WL ,dst -// -// (たぶん別対応) -// | m -rxw | MOVEM list, -// | m -rxw | FMOVEM.X reg, -// | m -rxw | FSAVE -// | m+ rxwp | MOVEM ,list -// | m+ rxwp | FMOVEM.X ,reg -// | m+ rxwp | FRESTORE - -extern uint32 internal_ea_ix(m68kcpu *cpu, uint32 anpc); - -extern uint32 cea_ctrl(m68kcpu *); -extern uint32 cea_data_8(m68kcpu *); -extern uint32 cea_data_16(m68kcpu *); -extern uint32 cea_data_32(m68kcpu *); -extern uint32 cea_copro(m68kcpu *); -extern uint32 fea_data_8(m68kcpu *); -extern uint32 fea_data_16(m68kcpu *); -extern uint32 fea_data_32(m68kcpu *); -extern uint32 fea_all_8(m68kcpu *); -extern uint32 fea_all_16(m68kcpu *); -extern uint32 fea_all_32(m68kcpu *); + // 命令ワードの下位6ビット mmmrrr のうち mmm の部分を取り出す + static inline int eamode(uint x) { return (x >> 3) & 7; } + // 命令ワードの下位6ビット mmmrrr のうち rrr の部分を取り出す + static inline int eanum(uint x) { return x & 7; } + + // internal_ea_*() は EA を計算だけする部分。CYCLE はここでは加算しない。 + // MOVE の DST 側からも呼ばれる。 + + // (An) + inline uint32 internal_ea_anin(int n) + { + return reg.A[n]; + } -// mmmrrr のうち mmm の部分を取り出す -#define eamode(x) (((x) >> 3) & 7) + // (An)+ .B + inline uint32 internal_ea_anpi_8(int n) + { + save_reg_pi(n); + if (n == 7) { + reg.A[n] += 2; + return reg.A[n] - 2; + } else { + reg.A[n] += 1; + return reg.A[n] - 1; + } + } -// mmmrrr のうち rrr の部分を取り出す -#define eanum(x) ((x) & 7) + // (An)+ .W + inline uint32 internal_ea_anpi_16(int n) + { + save_reg_pi(n); + reg.A[n] += 2; + return reg.A[n] - 2; + } -// -// EA を計算だけするマクロ -// MOVE の DST 側からも呼ばれる -// + // (An)+ .L + inline uint32 internal_ea_anpi_32(int n) + { + save_reg_pi(n); + reg.A[n] += 4; + return reg.A[n] - 4; + } -// (An) -static inline uint32 internal_ea_anin(m68kcpu *cpu, int n) -{ - return RegA(n); -} - -// (An)+ .B -static inline uint32 internal_ea_anpi_8(m68kcpu *cpu, int n) -{ - m68030_save_reg_pi(cpu, n); - if (n == 7) { - RegA(n) += 2; - return RegA(n) - 2; - } else { - RegA(n) += 1; - return RegA(n) - 1; - } -} - -// (An)+ .W -static inline uint32 internal_ea_anpi_16(m68kcpu *cpu, int n) -{ - m68030_save_reg_pi(cpu, n); - RegA(n) += 2; - return RegA(n) - 2; -} - -// (An)+ .L -static inline uint32 internal_ea_anpi_32(m68kcpu *cpu, int n) -{ - m68030_save_reg_pi(cpu, n); - RegA(n) += 4; - return RegA(n) - 4; -} - -// -(An) .B -static inline uint32 internal_ea_anpd_8(m68kcpu *cpu, int n) -{ - m68030_save_reg_pd(cpu, n); - if (n == 7) { - RegA(n) -= 2; - } else { - RegA(n) -= 1; - } - return RegA(n); -} - -// -(An) .W -static inline uint32 internal_ea_anpd_16(m68kcpu *cpu, int n) -{ - m68030_save_reg_pd(cpu, n); - RegA(n) -= 2; - return RegA(n); -} - -// -(An) .L -static inline uint32 internal_ea_anpd_32(m68kcpu *cpu, int n) -{ - m68030_save_reg_pd(cpu, n); - RegA(n) -= 4; - return RegA(n); -} - -// d16(An) -static inline uint32 internal_ea_andi(m68kcpu *cpu, int n) -{ - int32 disp = (int32)(int16)m68030_fetch_16(cpu); - return RegA(n) + disp; -} - -// (An,IX) -static inline uint32 internal_ea_anix(m68kcpu *cpu, int n) -{ - return internal_ea_ix(cpu, RegA(n)); -} - -// Abs.W -static inline uint32 internal_ea_absw(m68kcpu *cpu) -{ - return (int32)(int16)m68030_fetch_16(cpu); -} - -// Abs.L -static inline uint32 internal_ea_absl(m68kcpu *cpu) -{ - return m68030_fetch_32(cpu); -} - -// d16(PC) -static inline uint32 internal_ea_pcdi(m68kcpu *cpu) -{ - int32 pc = RegPC; - int32 disp = (int32)(int16)m68030_fetch_16(cpu); - return pc + disp; -} - -// (PC,IX) -static inline uint32 internal_ea_pcix(m68kcpu *cpu) -{ - return internal_ea_ix(cpu, RegPC); -} + // -(An) .B + inline uint32 internal_ea_anpd_8(int n) + { + save_reg_pd(n); + if (n == 7) { + reg.A[n] -= 2; + } else { + reg.A[n] -= 1; + } + return reg.A[n]; + } -// -// Calc EA -// + // -(An) .W + inline uint32 internal_ea_anpd_16(int n) + { + save_reg_pd(n); + reg.A[n] -= 2; + return reg.A[n]; + } -static inline uint32 -cea_anin(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anin(cpu, n); -} - -static inline uint32 -cea_anpi_8(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpi_8(cpu, n); -} - -static inline uint32 -cea_anpi_16(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpi_16(cpu, n); -} - -static inline uint32 -cea_anpi_32(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpi_32(cpu, n); -} - -static inline uint32 -cea_anpd_8(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpd_8(cpu, n); -} - -static inline uint32 -cea_anpd_16(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpd_16(cpu, n); -} - -static inline uint32 -cea_anpd_32(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_anpd_32(cpu, n); -} - -static inline uint32 -cea_andi(m68kcpu *cpu, int n) -{ - CYCLE(2); - return internal_ea_andi(cpu, n); -} - -static inline uint32 -cea_anix(m68kcpu *cpu, int n) -{ - CYCLE(10); // XXX 4,4-18,20 - return internal_ea_anix(cpu, n); -} - -static inline uint32 -cea_absw(m68kcpu *cpu) -{ - CYCLE(2); - return internal_ea_absw(cpu); -} - -static inline uint32 -cea_absl(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_absl(cpu); -} - -static inline uint32 -cea_pcdi(m68kcpu *cpu) -{ - CYCLE(2); - return internal_ea_pcdi(cpu); -} - -static inline uint32 -cea_pcix(m68kcpu *cpu) -{ - CYCLE(10); // XXX 4,4-18,20 - return internal_ea_pcix(cpu); -} + // -(An) .L + inline uint32 internal_ea_anpd_32(int n) + { + save_reg_pd(n); + reg.A[n] -= 4; + return reg.A[n]; + } -// -// Fetch EA -// + // d16(An) + inline uint32 internal_ea_andi(int n) + { + int32 disp = (int32)(int16)fetch_16(); + return reg.A[n] + disp; + } + + // (An,IX) + inline uint32 internal_ea_anix(int n) + { + return internal_ea_ix(reg.A[n]); + } + + // Abs.W + inline uint32 internal_ea_absw() + { + return (int32)(int16)fetch_16(); + } + + // Abs.L + inline uint32 internal_ea_absl() + { + return fetch_32(); + } + + // d16(PC) + inline uint32 internal_ea_pcdi() + { + int32 origin = reg.pc; + int32 disp = (int32)(int16)fetch_16(); + return origin + disp; + } + + // (PC,IX) + inline uint32 internal_ea_pcix() + { + return internal_ea_ix(reg.pc); + } + + uint32 internal_ea_ix(uint32); -static inline uint32 -fea_anin(m68kcpu *cpu) -{ - CYCLE(3); - return internal_ea_anin(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpi_8(m68kcpu *cpu) -{ - CYCLE(3); - return internal_ea_anpi_8(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpi_16(m68kcpu *cpu) -{ - CYCLE(3); - return internal_ea_anpi_16(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpi_32(m68kcpu *cpu) -{ - CYCLE(3); - return internal_ea_anpi_32(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpd_8(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_anpd_8(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpd_16(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_anpd_16(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anpd_32(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_anpd_32(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_andi(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_andi(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_anix(m68kcpu *cpu) -{ - CYCLE2(12, 14); // XXX 6,6-18,21 - return internal_ea_anix(cpu, eanum(RegIR)); -} - -static inline uint32 -fea_absw(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_absw(cpu); -} - -static inline uint32 -fea_absl(m68kcpu *cpu) -{ - CYCLE2(4, 5); - return internal_ea_absl(cpu); -} - -static inline uint32 -fea_pcdi(m68kcpu *cpu) -{ - CYCLE(4); - return internal_ea_pcdi(cpu); -} - -static inline uint32 -fea_pcix(m68kcpu *cpu) -{ - CYCLE2(12, 14); // XXX 6,6-18,21 - return internal_ea_pcix(cpu); -} - -static inline void -fea_imm_16(m68kcpu *cpu) -{ - CYCLE(2); -} - -static inline void -fea_imm_32(m68kcpu *cpu) -{ - CYCLE(4); -} + // CEA (個別) + uint32 cea_anin(int n); + uint32 cea_anpi_8(int n); + uint32 cea_anpi_16(int n); + uint32 cea_anpi_32(int n); + uint32 cea_anpd_8(int n); + uint32 cea_anpd_16(int n); + uint32 cea_anpd_32(int n); + uint32 cea_andi(int n); + uint32 cea_anix(int n); + uint32 cea_absw(); + uint32 cea_absl(); + uint32 cea_pcdi(); + uint32 cea_pcix(); + + // FEA (個別) + uint32 fea_anin(); + uint32 fea_anpi_8(); + uint32 fea_anpi_16(); + uint32 fea_anpi_32(); + uint32 fea_anpd_8(); + uint32 fea_anpd_16(); + uint32 fea_anpd_32(); + uint32 fea_andi(); + uint32 fea_anix(); + uint32 fea_absw(); + uint32 fea_absl(); + uint32 fea_pcdi(); + uint32 fea_pcix(); + void fea_imm_16(); + void fea_imm_32(); + + // CEA (グループ) + uint32 cea_ctrl(); + uint32 cea_data_8(); + uint32 cea_data_16(); + uint32 cea_data_32(); + uint32 cea_copro(); + + // FEA (グループ) + uint32 fea_data_8(); + uint32 fea_data_16(); + uint32 fea_data_32(); + uint32 fea_all_8(); + uint32 fea_all_16(); + uint32 fea_all_32();