Add DIVU/DIVS

This commit is contained in:
Rodolphe de Saint Léger 2025-05-20 11:47:11 +02:00
parent ac5497e797
commit 5d4b8809d0
8 changed files with 423 additions and 254 deletions

View file

@ -2202,7 +2202,7 @@ public class CoreGenerator {
if ("imm3".equals(src)) {
addFormattedMicroInsn("alub = (ir >> 9) & 0x0007"); // retrieve immediate data
addBeginFormattedControlFlow("if (alub == 0)");
addFormattedMicroInsn("alub = 8"); // when immediate data if zero... use 8
addFormattedMicroInsn("alub = 8"); // when immediate data is zero... use 8
addEndControlFlow();
rsrc = "alub";
@ -2338,6 +2338,13 @@ public class CoreGenerator {
} else if ("w".equals(size) && exsrc) {
addFormattedMicroInsn("dt = long_%s((short) %s, %s)", op, rsrc, rdst); // perform long word operation
} else if ("w".equals(size)) {
if ("w".equals(size) && ("divu".equals(op) || "divs".equals(op))) {
addBeginFormattedControlFlow("if ((%s & 0xffff) == 0)", rsrc);
settvn(5); // set div by zero exception trap
addFormattedMicroInsn("mpc = (sswi & 0x%04x) != 0 ? trap2000 : trap0000", SSWI_FMT2);
addFormattedMicroInsn("continue"); // branch to trap subroutine
addEndControlFlow();
}
addFormattedMicroInsn("dt = word_%s(%s, %s)", op, rsrc, rdst); // perform word operation
} else {
throw new IllegalStateException();
@ -2360,7 +2367,7 @@ public class CoreGenerator {
addFormattedMicroInsn("dar[rx] = (dar[rx] & ~0xff) | (dt & 0xff)"); // update register with result
} else if ("l".equals(size)) {
addFormattedMicroInsn("dar[rx] = dt"); // update register with result
} else if ("w".equals(size) && ("mulu".equals(op) || "muls".equals(op))) {
} else if ("w".equals(size) && ("mulu".equals(op) || "muls".equals(op) || "divu".equals(op) || "divs".equals(op))) {
addFormattedMicroInsn("dar[rx] = dt"); // update register with result
} else if ("w".equals(size)) {
addFormattedMicroInsn("dar[rx] = (dar[rx] & ~0xffff) | (dt & 0xffff)"); // update register with result

View file

@ -601,6 +601,20 @@ public class CorePLAGenerator {
appendOP_eas(0x8180, 0xf1c0, "or_l_dd", EA_FETCH | EA_MALT, "32", (opcode, opmask, opname, n1, mode) -> {
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", dyadic(gen, "or", "l", "dd", "ea"));
});
appendOP_eas(0x80c0, 0xf1c0, "divu_w", EA_FETCH | EA_ALL, "16", dyadic(gen, "divu", "w", "ds", "dd"), null, (opcode, opmask, opname, n1, mode) -> {
if ((mode & EA_ALL ) == 0) {
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "dbrr");
} else {
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", dyadic(gen, "divu", "w", "ea", "dd"));
}
});
appendOP_eas(0x81c0, 0xf1c0, "divs_w", EA_FETCH | EA_ALL, "16", dyadic(gen, "divs", "w", "ds", "dd"), null, (opcode, opmask, opname, n1, mode) -> {
if ((mode & EA_ALL ) == 0) {
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", "dbrr");
} else {
appendOP(gen, entries, array, opcode, opmask, opname, n1, "dbrr", dyadic(gen, "divs", "w", "ea", "dd"));
}
});
appendOP_eas(0x9000, 0xf1c0, "sub_b", EA_FETCH | EA_ALL, "8", dyadic(gen, "sub", "b", "ds", "dd"), null, (opcode, opmask, opname, n1, mode) -> {
opname = String.format("%s_dd", opname);

File diff suppressed because it is too large Load diff

View file

@ -1240,6 +1240,50 @@ public class CoreALU {
sr ^= (sr ^ (c | v | z | n)) & (FL_C | FL_V | FL_Z | FL_N);
}
public final int word_divs(int src, int dst) {
src = (short) src;
int q = dst / src;
int v = q == (short) q ? 0 : FL_V;
if (v == 0) {
int r = dst % src;
int n = (q >> 28) & FL_N;
int z = (~((q | -q) >> 31)) & FL_Z;
sr ^= (sr ^ (v | z | n)) & (FL_C | FL_V | FL_Z | FL_N);
return (r << 16) | (q & 0xffff);
}
sr ^= (sr ^ (v | FL_N)) & (FL_C | FL_V | FL_Z | FL_N);
return dst;
}
public final int word_divu(int src, int dst) {
src = src & 0xffff;
int q = Integer.divideUnsigned(dst, src);
int v = q == (q & 0xffff) ? 0 : FL_V;
if (v == 0) {
q = (short) q;
int r = Integer.remainderUnsigned(dst, src);
int n = (q >> 28) & FL_N;
int z = (~((q | -q) >> 31)) & FL_Z;
sr ^= (sr ^ (v | z | n)) & (FL_C | FL_V | FL_Z | FL_N);
return (r << 16) | (q & 0xffff);
}
sr ^= (sr ^ (v | FL_N)) & (FL_C | FL_V | FL_Z | FL_N);
return dst;
}
public final byte byte_eor(int src, int dst) {
src = (byte) src;
dst = (byte) dst;

View file

@ -193,6 +193,10 @@ import static miggy.cpupoet.Core.gen_cmpw_dt_ad;
import static miggy.cpupoet.Core.gen_cmpw_dt_dd;
import static miggy.cpupoet.Core.gen_cmpw_dt_ds;
import static miggy.cpupoet.Core.gen_cmpw_im_ea;
import static miggy.cpupoet.Core.gen_divsw_ds_dd;
import static miggy.cpupoet.Core.gen_divsw_dt_dd;
import static miggy.cpupoet.Core.gen_divuw_ds_dd;
import static miggy.cpupoet.Core.gen_divuw_dt_dd;
import static miggy.cpupoet.Core.gen_eorb_dd_ds;
import static miggy.cpupoet.Core.gen_eorb_dd_ea;
import static miggy.cpupoet.Core.gen_eorb_dt_ccr;
@ -2203,6 +2207,28 @@ public enum MacroPLA {
or_l_imm32_dd(0x80bc, 0xf1ff, ea_imm32_read, dbrr, gen_orl_dt_dd),
divu_w_ds(0x80c0, 0xf1f8, gen_divuw_ds_dd, dbrr, dbrr),
divu_w_ais(0x80d0, 0xf1f8, ea_ais16_read, dbrr, gen_divuw_dt_dd),
divu_w_aips(0x80d8, 0xf1f8, ea_aips16_read, dbrr, gen_divuw_dt_dd),
divu_w_pais(0x80e0, 0xf1f8, ea_pais16_read, dbrr, gen_divuw_dt_dd),
divu_w_das(0x80e8, 0xf1f8, ea_das16_read, dbrr, gen_divuw_dt_dd),
divu_w_dais(0x80f0, 0xf1f8, ea_dais16_read, dbrr, gen_divuw_dt_dd),
divu_w_adr16(0x80f8, 0xf1ff, ea_adr16s16_read, dbrr, gen_divuw_dt_dd),
divu_w_adr32(0x80f9, 0xf1ff, ea_adr32s16_read, dbrr, gen_divuw_dt_dd),
divu_w_dpc(0x80fa, 0xf1ff, ea_dpc16_read, dbrr, gen_divuw_dt_dd),
divu_w_dpci(0x80fb, 0xf1ff, ea_dpci16_read, dbrr, gen_divuw_dt_dd),
divu_w_imm16(0x80fc, 0xf1ff, ea_imm16_read, dbrr, gen_divuw_dt_dd),
sbcd_ds_dd(0x8100, 0xf1f8, gen_sbcdb_ds_dd, dbrr, dbrr),
sbcd_pais_paid(0x8108, 0xf1f8, ea_pais8_read, gen_sbcdb_im_ea, ea_paid8_read),
@ -2249,6 +2275,28 @@ public enum MacroPLA {
or_l_dd_adr32(0x81b9, 0xf1ff, ea_adr32s32_read, dbrr, gen_orl_dd_ea),
divs_w_ds(0x81c0, 0xf1f8, gen_divsw_ds_dd, dbrr, dbrr),
divs_w_ais(0x81d0, 0xf1f8, ea_ais16_read, dbrr, gen_divsw_dt_dd),
divs_w_aips(0x81d8, 0xf1f8, ea_aips16_read, dbrr, gen_divsw_dt_dd),
divs_w_pais(0x81e0, 0xf1f8, ea_pais16_read, dbrr, gen_divsw_dt_dd),
divs_w_das(0x81e8, 0xf1f8, ea_das16_read, dbrr, gen_divsw_dt_dd),
divs_w_dais(0x81f0, 0xf1f8, ea_dais16_read, dbrr, gen_divsw_dt_dd),
divs_w_adr16(0x81f8, 0xf1ff, ea_adr16s16_read, dbrr, gen_divsw_dt_dd),
divs_w_adr32(0x81f9, 0xf1ff, ea_adr32s16_read, dbrr, gen_divsw_dt_dd),
divs_w_dpc(0x81fa, 0xf1ff, ea_dpc16_read, dbrr, gen_divsw_dt_dd),
divs_w_dpci(0x81fb, 0xf1ff, ea_dpci16_read, dbrr, gen_divsw_dt_dd),
divs_w_imm16(0x81fc, 0xf1ff, ea_imm16_read, dbrr, gen_divsw_dt_dd),
sub_b_ds_dd(0x9000, 0xf1f8, gen_subb_ds_dd, dbrr, dbrr),
sub_b_ais_dd(0x9010, 0xf1f8, ea_ais8_read, dbrr, gen_subb_dt_dd),

View file

@ -20,6 +20,8 @@ public class InstructionTests extends TestCase {
test.executeBinTest("MULU");
test.executeBinTest("MULS");
test.executeBinTest("DIVU");
test.executeBinTest("DIVS");
}
public void testADD() {