Fixed MOVEM

- register list is fetched before EA resolution
- pre/post EA mode MUST use ar indirect register micro-routine
This commit is contained in:
Rodolphe de Saint Léger 2025-05-19 11:37:54 +02:00
parent cee4710070
commit 4aad8cbc96
8 changed files with 863 additions and 983 deletions

View file

@ -1703,9 +1703,9 @@ public class CoreGenerator {
private void op_movem_microcode() { private void op_movem_microcode() {
addState("op_movemw_rr_ea"); addState("op_movemw_rr_ea");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
int loop = blocks.size(); int loop = blocks.size();
@ -1731,9 +1731,9 @@ public class CoreGenerator {
addState("op_movemw_rr_pais"); addState("op_movemw_rr_pais");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1762,9 +1762,9 @@ public class CoreGenerator {
addState("op_moveml_rr_ea"); addState("op_moveml_rr_ea");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1790,9 +1790,9 @@ public class CoreGenerator {
addState("op_moveml_rr_pais"); addState("op_moveml_rr_pais");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1821,9 +1821,9 @@ public class CoreGenerator {
// XXX should have another entry for dpc/dpci to have ssw program function code // XXX should have another entry for dpc/dpci to have ssw program function code
addState("op_movemw_ea_rr"); addState("op_movemw_ea_rr");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1850,9 +1850,9 @@ public class CoreGenerator {
addState("op_movemw_aips_rr"); addState("op_movemw_aips_rr");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1882,9 +1882,9 @@ public class CoreGenerator {
// XXX should have another entry for dpc/dpci to have ssw program function code // XXX should have another entry for dpc/dpci to have ssw program function code
addState("op_moveml_ea_rr"); addState("op_moveml_ea_rr");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -1911,9 +1911,9 @@ public class CoreGenerator {
addState("op_moveml_aips_rr"); addState("op_moveml_aips_rr");
// read extension word // read extension word
anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> { //anyread16("dt", SSW_DF | SSW_P, "pc + scan", 0, false, () -> {
addFormattedMicroInsn("scan += 2"); // addFormattedMicroInsn("scan += 2");
}); //});
prefetchir(0, false); prefetchir(0, false);
addFormattedMicroInsn("alub = 0"); addFormattedMicroInsn("alub = 0");
loop = blocks.size(); loop = blocks.size();
@ -3038,7 +3038,7 @@ public class CoreGenerator {
if (block.name != null) { if (block.name != null) {
FieldSpec field = null; FieldSpec field = null;
if ((imports == null) || (imports.contains(block.name))) { if ((imports == null) || (imports.contains(block.name) || "execute_trap".equals(block.name))) {
field = FieldSpec.builder(int.class, block.name, PROTECTED, STATIC, FINAL).initializer("$L", i) field = FieldSpec.builder(int.class, block.name, PROTECTED, STATIC, FINAL).initializer("$L", i)
.build(); .build();
} else { } else {

View file

@ -425,52 +425,52 @@ public class CorePLAGenerator {
appendOP(gen, entries, array, 0x4e7a, 0xffff, "movec_cr_rz", "op_movec_cr_rz", "dbrr", "dbrr"); appendOP(gen, entries, array, 0x4e7a, 0xffff, "movec_cr_rz", "op_movec_cr_rz", "dbrr", "dbrr");
appendOP(gen, entries, array, 0x4e7b, 0xffff, "movec_rz_cr", "op_movec_rz_cr", "dbrr", "dbrr"); appendOP(gen, entries, array, 0x4e7b, 0xffff, "movec_rz_cr", "op_movec_rz_cr", "dbrr", "dbrr");
appendOP_eas(0x4890, 0xffc0, "movem_w_list", EA_CTRL, "16", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4890, 0xffc0, "movem_w_list", EA_CTRL, "16", (opcode, opmask, opname, n2, mode) -> {
//opname = String.format("%s", opname); //opname = String.format("%s", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_movemw_rr_ea"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", n2, "op_movemw_rr_ea");
}); });
appendOP_eas(0x4890, 0xffc0, "movem_w_listp", EA_PAIS, "16", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4890, 0xffc0, "movem_w_listp", EA_PAIS, "16", (opcode, opmask, opname, n2, mode) -> {
//opname = String.format("%s", opname); //opname = String.format("%s", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_movemw_rr_pais"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", "ea_ais16", "op_movemw_rr_pais");
}); });
appendOP_eas(0x48d0, 0xffc0, "movem_l_list", EA_CTRL, "32", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x48d0, 0xffc0, "movem_l_list", EA_CTRL, "32", (opcode, opmask, opname, n2, mode) -> {
//opname = String.format("%s", opname); //opname = String.format("%s", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_moveml_rr_ea"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", n2, "op_moveml_rr_ea");
}); });
appendOP_eas(0x48d0, 0xffc0, "movem_l_listp", EA_PAIS, "32", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x48d0, 0xffc0, "movem_l_listp", EA_PAIS, "32", (opcode, opmask, opname, n2, mode) -> {
//opname = String.format("%s", opname); //opname = String.format("%s", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_moveml_rr_pais"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", "ea_ais32", "op_moveml_rr_pais");
}); });
appendOP_eas(0x4c90, 0xffc0, "movem_w", EA_CTRL, "16", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4c90, 0xffc0, "movem_w", EA_CTRL, "16", (opcode, opmask, opname, n2, mode) -> {
opname = String.format("%s_list", opname); opname = String.format("%s_list", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_movemw_ea_rr"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", n2, "op_movemw_ea_rr");
}); });
appendOP_eas(0x4c90, 0xffc0, "movem_w", EA_AIPS, "16", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4c90, 0xffc0, "movem_w", EA_AIPS, "16", (opcode, opmask, opname, n2, mode) -> {
opname = String.format("%s_list", opname); opname = String.format("%s_list", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_movemw_aips_rr"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", "ea_ais16", "op_movemw_aips_rr");
}); });
appendOP_eas(0x4cd0, 0xffc0, "movem_l", EA_CTRL, "32", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4cd0, 0xffc0, "movem_l", EA_CTRL, "32", (opcode, opmask, opname, n2, mode) -> {
opname = String.format("%s_list", opname); opname = String.format("%s_list", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_moveml_ea_rr"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", n2, "op_moveml_ea_rr");
}); });
appendOP_eas(0x4cd0, 0xffc0, "movem_l", EA_AIPS, "32", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4cd0, 0xffc0, "movem_l", EA_AIPS, "32", (opcode, opmask, opname, n2, mode) -> {
opname = String.format("%s_list", opname); opname = String.format("%s_list", opname);
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "op_moveml_aips_rr"); appendOP(gen, entries, array, opcode, opmask, opname, "op_imm16", "ea_ais32", "op_moveml_aips_rr");
}); });
appendOP_eas(0x4e90, 0xffc0, "jsr", EA_CTRL, "16", (opcode, opmask, opname, n1, mode) -> { appendOP_eas(0x4e90, 0xffc0, "jsr", EA_CTRL, "16", (opcode, opmask, opname, n1, mode) -> {

File diff suppressed because it is too large Load diff

View file

@ -1812,39 +1812,39 @@ public enum MacroPLA {
ext_w_ds(0x4880, 0xfff8, op_extw_ds, dbrr, dbrr), ext_w_ds(0x4880, 0xfff8, op_extw_ds, dbrr, dbrr),
movem_w_list_ais(0x4890, 0xfff8, ea_ais16, dbrr, op_movemw_rr_ea), movem_w_list_ais(0x4890, 0xfff8, op_imm16, ea_ais16, op_movemw_rr_ea),
movem_w_listp_pais(0x48a0, 0xfff8, ea_pais16, dbrr, op_movemw_rr_pais), movem_w_listp_pais(0x48a0, 0xfff8, op_imm16, ea_ais16, op_movemw_rr_pais),
movem_w_list_das(0x48a8, 0xfff8, ea_das16, dbrr, op_movemw_rr_ea), movem_w_list_das(0x48a8, 0xfff8, op_imm16, ea_das16, op_movemw_rr_ea),
movem_w_list_dais(0x48b0, 0xfff8, ea_dais16, dbrr, op_movemw_rr_ea), movem_w_list_dais(0x48b0, 0xfff8, op_imm16, ea_dais16, op_movemw_rr_ea),
movem_w_list_adr16(0x48b8, 0xffff, ea_adr16s16, dbrr, op_movemw_rr_ea), movem_w_list_adr16(0x48b8, 0xffff, op_imm16, ea_adr16s16, op_movemw_rr_ea),
movem_w_list_adr32(0x48b9, 0xffff, ea_adr32s16, dbrr, op_movemw_rr_ea), movem_w_list_adr32(0x48b9, 0xffff, op_imm16, ea_adr32s16, op_movemw_rr_ea),
movem_w_list_dpc(0x48ba, 0xffff, ea_dpc16, dbrr, op_movemw_rr_ea), movem_w_list_dpc(0x48ba, 0xffff, op_imm16, ea_dpc16, op_movemw_rr_ea),
movem_w_list_dpci(0x48bb, 0xffff, ea_dpci16, dbrr, op_movemw_rr_ea), movem_w_list_dpci(0x48bb, 0xffff, op_imm16, ea_dpci16, op_movemw_rr_ea),
ext_l_ds(0x48c0, 0xfff8, op_extl_ds, dbrr, dbrr), ext_l_ds(0x48c0, 0xfff8, op_extl_ds, dbrr, dbrr),
movem_l_list_ais(0x48d0, 0xfff8, ea_ais32, dbrr, op_moveml_rr_ea), movem_l_list_ais(0x48d0, 0xfff8, op_imm16, ea_ais32, op_moveml_rr_ea),
movem_l_listp_pais(0x48e0, 0xfff8, ea_pais32, dbrr, op_moveml_rr_pais), movem_l_listp_pais(0x48e0, 0xfff8, op_imm16, ea_ais32, op_moveml_rr_pais),
movem_l_list_das(0x48e8, 0xfff8, ea_das32, dbrr, op_moveml_rr_ea), movem_l_list_das(0x48e8, 0xfff8, op_imm16, ea_das32, op_moveml_rr_ea),
movem_l_list_dais(0x48f0, 0xfff8, ea_dais32, dbrr, op_moveml_rr_ea), movem_l_list_dais(0x48f0, 0xfff8, op_imm16, ea_dais32, op_moveml_rr_ea),
movem_l_list_adr16(0x48f8, 0xffff, ea_adr16s32, dbrr, op_moveml_rr_ea), movem_l_list_adr16(0x48f8, 0xffff, op_imm16, ea_adr16s32, op_moveml_rr_ea),
movem_l_list_adr32(0x48f9, 0xffff, ea_adr32s32, dbrr, op_moveml_rr_ea), movem_l_list_adr32(0x48f9, 0xffff, op_imm16, ea_adr32s32, op_moveml_rr_ea),
movem_l_list_dpc(0x48fa, 0xffff, ea_dpc32, dbrr, op_moveml_rr_ea), movem_l_list_dpc(0x48fa, 0xffff, op_imm16, ea_dpc32, op_moveml_rr_ea),
movem_l_list_dpci(0x48fb, 0xffff, ea_dpci32, dbrr, op_moveml_rr_ea), movem_l_list_dpci(0x48fb, 0xffff, op_imm16, ea_dpci32, op_moveml_rr_ea),
extb_l_ds(0x49c0, 0xfff8, op_extbl_ds, dbrr, dbrr), extb_l_ds(0x49c0, 0xfff8, op_extbl_ds, dbrr, dbrr),
@ -1898,37 +1898,37 @@ public enum MacroPLA {
illegal(0x4afc, 0xffff, op_illegal, dbrr, dbrr), illegal(0x4afc, 0xffff, op_illegal, dbrr, dbrr),
movem_w_ais_list(0x4c90, 0xfff8, ea_ais16, dbrr, op_movemw_ea_rr), movem_w_ais_list(0x4c90, 0xfff8, op_imm16, ea_ais16, op_movemw_ea_rr),
movem_w_aips_list(0x4c98, 0xfff8, ea_aips16, dbrr, op_movemw_aips_rr), movem_w_aips_list(0x4c98, 0xfff8, op_imm16, ea_ais16, op_movemw_aips_rr),
movem_w_das_list(0x4ca8, 0xfff8, ea_das16, dbrr, op_movemw_ea_rr), movem_w_das_list(0x4ca8, 0xfff8, op_imm16, ea_das16, op_movemw_ea_rr),
movem_w_dais_list(0x4cb0, 0xfff8, ea_dais16, dbrr, op_movemw_ea_rr), movem_w_dais_list(0x4cb0, 0xfff8, op_imm16, ea_dais16, op_movemw_ea_rr),
movem_w_adr16_list(0x4cb8, 0xffff, ea_adr16s16, dbrr, op_movemw_ea_rr), movem_w_adr16_list(0x4cb8, 0xffff, op_imm16, ea_adr16s16, op_movemw_ea_rr),
movem_w_adr32_list(0x4cb9, 0xffff, ea_adr32s16, dbrr, op_movemw_ea_rr), movem_w_adr32_list(0x4cb9, 0xffff, op_imm16, ea_adr32s16, op_movemw_ea_rr),
movem_w_dpc_list(0x4cba, 0xffff, ea_dpc16, dbrr, op_movemw_ea_rr), movem_w_dpc_list(0x4cba, 0xffff, op_imm16, ea_dpc16, op_movemw_ea_rr),
movem_w_dpci_list(0x4cbb, 0xffff, ea_dpci16, dbrr, op_movemw_ea_rr), movem_w_dpci_list(0x4cbb, 0xffff, op_imm16, ea_dpci16, op_movemw_ea_rr),
movem_l_ais_list(0x4cd0, 0xfff8, ea_ais32, dbrr, op_moveml_ea_rr), movem_l_ais_list(0x4cd0, 0xfff8, op_imm16, ea_ais32, op_moveml_ea_rr),
movem_l_aips_list(0x4cd8, 0xfff8, ea_aips32, dbrr, op_moveml_aips_rr), movem_l_aips_list(0x4cd8, 0xfff8, op_imm16, ea_ais32, op_moveml_aips_rr),
movem_l_das_list(0x4ce8, 0xfff8, ea_das32, dbrr, op_moveml_ea_rr), movem_l_das_list(0x4ce8, 0xfff8, op_imm16, ea_das32, op_moveml_ea_rr),
movem_l_dais_list(0x4cf0, 0xfff8, ea_dais32, dbrr, op_moveml_ea_rr), movem_l_dais_list(0x4cf0, 0xfff8, op_imm16, ea_dais32, op_moveml_ea_rr),
movem_l_adr16_list(0x4cf8, 0xffff, ea_adr16s32, dbrr, op_moveml_ea_rr), movem_l_adr16_list(0x4cf8, 0xffff, op_imm16, ea_adr16s32, op_moveml_ea_rr),
movem_l_adr32_list(0x4cf9, 0xffff, ea_adr32s32, dbrr, op_moveml_ea_rr), movem_l_adr32_list(0x4cf9, 0xffff, op_imm16, ea_adr32s32, op_moveml_ea_rr),
movem_l_dpc_list(0x4cfa, 0xffff, ea_dpc32, dbrr, op_moveml_ea_rr), movem_l_dpc_list(0x4cfa, 0xffff, op_imm16, ea_dpc32, op_moveml_ea_rr),
movem_l_dpci_list(0x4cfb, 0xffff, ea_dpci32, dbrr, op_moveml_ea_rr), movem_l_dpci_list(0x4cfb, 0xffff, op_imm16, ea_dpci32, op_moveml_ea_rr),
trap_imm4(0x4e40, 0xfff0, op_trap, dbrr, dbrr), trap_imm4(0x4e40, 0xfff0, op_trap, dbrr, dbrr),

View file

@ -44,7 +44,7 @@ public class CoreTest extends Core {
for (int i = 0; i < numTests; i++) { for (int i = 0; i < numTests; i++) {
boolean skip = checkSkip(i, skips); boolean skip = checkSkip(i, skips);
if ((i == 383) && "Bcc".equals(name)) { if ((i == 40) && "MOVEM.w".equals(name)) {
toString(); toString();
} }
executeBinTest(buffer, skip); executeBinTest(buffer, skip);
@ -194,7 +194,7 @@ public class CoreTest extends Core {
core.write16(value.addr, value.data); core.write16(value.addr, value.data);
} }
core.mpc = 11; core.mpc = execute_trap;
core.sswi &= ~(SR_T1 | SR_T0); core.sswi &= ~(SR_T1 | SR_T0);
} }

View file

@ -179,8 +179,8 @@ public class InstructionTests extends TestCase {
test.executeBinTest("MOVEA.w"); test.executeBinTest("MOVEA.w");
test.executeBinTest("MOVEA.l"); test.executeBinTest("MOVEA.l");
// test.executeBinTest("MOVEM.w"); test.executeBinTest("MOVEM.w");
// test.executeBinTest("MOVEM.l"); test.executeBinTest("MOVEM.l");
test.executeBinTest("MOVEtoCCR"); test.executeBinTest("MOVEtoCCR");
test.executeBinTest("MOVEtoUSP"); test.executeBinTest("MOVEtoUSP");