Skip to content

Commit

Permalink
[MC68000] Fix floating point relative branch
Browse files Browse the repository at this point in the history
- Fix 32 bit relative overflow check
- Fix FDxx relative branch base, from instruction address + 4
  • Loading branch information
tgtakaoka committed Sep 22, 2024
1 parent 722d803 commit 1213dc9
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 174 deletions.
31 changes: 20 additions & 11 deletions src/asm_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,16 @@ void AsmMc68000::encodeDisplacement(
}

void AsmMc68000::encodeRelativeAddr(AsmInsn &insn, AddrMode mode, const Operand &op) const {
const auto base = insn.address() + 2;
// FDxx has different base address
const auto base = insn.address() + (insn.hasPostVal() ? 4 : 2);
const auto target = op.getError() ? base : op.val.getUnsigned();
insn.setErrorIf(op, checkAddr(target, true));
const auto delta = branchDelta(base, target, insn, op);
ErrorAt error;
// the branchDelta() uses addressWidth(), which is 24 bit, to
// check the range of |delta|. It is not suitable for
// M_REL32. Record errors in |error| then copy it to |insn| if
// any.
const auto delta = branchDelta(base, target, error, op);
const auto insnSize = insn.insnSize();
if (mode == M_REL8) {
if (insnSize == ISZ_NONE) {
Expand All @@ -238,20 +244,20 @@ void AsmMc68000::encodeRelativeAddr(AsmInsn &insn, AddrMode mode, const Operand
insn.embed(static_cast<uint8_t>(delta));
} else if (insnSize == ISZ_BYTE || insnSize == ISZ_SNGL) {
if (overflowDelta(delta, 8))
insn.setErrorIf(op, OPERAND_TOO_FAR);
error.setErrorIf(op, OPERAND_TOO_FAR);
insn.embed(static_cast<uint8_t>(delta));
} else if (insnSize == ISZ_WORD || insnSize == ISZ_LONG) {
goto rel16;
} else {
insn.setErrorIf(ILLEGAL_SIZE);
error.setErrorIf(ILLEGAL_SIZE);
}
} else if (mode == M_REL16) {
if (insnSize == ISZ_NONE || insnSize == ISZ_WORD || insnSize == ISZ_LONG) {
rel16:
if (overflowDelta(delta, 16))
insn.setErrorIf(op, OPERAND_TOO_FAR);
error.setErrorIf(op, OPERAND_TOO_FAR);
} else {
insn.setErrorIf(ILLEGAL_SIZE);
error.setErrorIf(ILLEGAL_SIZE);
}
insn.emitOperand16(delta);
} else if (mode == M_REL32) {
Expand All @@ -261,19 +267,22 @@ void AsmMc68000::encodeRelativeAddr(AsmInsn &insn, AddrMode mode, const Operand
goto rel32;
} else if (insnSize == ISZ_WORD || insnSize == ISZ_LONG) {
if (overflowDelta(delta, 16))
insn.setErrorIf(op, OPERAND_TOO_FAR);
error.setErrorIf(op, OPERAND_TOO_FAR);
rel32_16:
insn.setOpCode(insn.opCode() & ~(1 << 6));
insn.setOpCode(insn.opCode() & ~(1 << 6)); // M_REL16
insn.emitOperand16(static_cast<uint16_t>(delta));
} else if (insnSize == ISZ_LONG || insnSize == ISZ_XTND) {
rel32:
insn.embed(1 << 6);
insn.emitOperand32(delta);
error.setOK(); // M_REL32 never overflow.
insn.embed(1 << 6); // M_REL32
insn.emitOperand32(target - base); // 32 bit delta
} else {
insn.setErrorIf(ILLEGAL_SIZE);
error.setErrorIf(ILLEGAL_SIZE);
goto rel32_16;
}
}
// Copy error if any
insn.setErrorIf(error);
}

void AsmMc68000::encodeImmediate(AsmInsn &insn, const Operand &op, OprSize size) const {
Expand Down
3 changes: 2 additions & 1 deletion src/dis_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ void DisMc68000::decodeEffectiveAddr(
}

void DisMc68000::decodeRelative(DisInsn &insn, StrBuffer &out, AddrMode mode) const {
const auto base = insn.address() + 2;
// FDxx has different base address
const auto base = insn.address() + (insn.hasPostVal() ? 4 : 2);
if (mode == M_REL32 && (insn.opCode() & (1 << 6)) == 0)
mode = M_REL16;
if (mode == M_REL32) {
Expand Down
2 changes: 1 addition & 1 deletion test/autogen/gen_mc68000.asm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

cpu 68000
fpu on
org 0000h
org 10000h
include "gen_mc68000.inc"
end

Expand Down
128 changes: 64 additions & 64 deletions test/autogen/gen_mc68000.inc
Original file line number Diff line number Diff line change
Expand Up @@ -17743,101 +17743,101 @@
FSNGT D0
FSSNE D0
FSST D0
FDBF D0, *+$0104
FDBF D0, *-$7FFE
FDBF D0, *+$0106
FDBF D0, *-$7FFC
FDBF D0, *
FDBEQ D0, *+$0104
FDBEQ D0, *-$7FFE
FDBEQ D0, *+$0106
FDBEQ D0, *-$7FFC
FDBEQ D0, *
FDBOGT D0, *+$0106
FDBOGT D0, *-$7FFE
FDBOGT D0, *+$0108
FDBOGT D0, *-$7FFC
FDBOGT D0, *
FDBOGE D0, *+$0106
FDBOGE D0, *-$7FFE
FDBOGE D0, *+$0108
FDBOGE D0, *-$7FFC
FDBOGE D0, *
FDBOLT D0, *+$0108
FDBOLT D0, *-$7FFE
FDBOLT D0, *+$010A
FDBOLT D0, *-$7FFC
FDBOLT D0, *
FDBOLE D0, *+$0108
FDBOLE D0, *-$7FFE
FDBOLE D0, *+$010A
FDBOLE D0, *-$7FFC
FDBOLE D0, *
FDBOGL D0, *+$010A
FDBOGL D0, *-$7FFE
FDBOGL D0, *+$010C
FDBOGL D0, *-$7FFC
FDBOGL D0, *
FDBOR D0, *+$010A
FDBOR D0, *-$7FFE
FDBOR D0, *+$010C
FDBOR D0, *-$7FFC
FDBOR D0, *
FDBUN D0, *+$010C
FDBUN D0, *-$7FFE
FDBUN D0, *+$010E
FDBUN D0, *-$7FFC
FDBUN D0, *
FDBUEQ D0, *+$010C
FDBUEQ D0, *-$7FFE
FDBUEQ D0, *+$010E
FDBUEQ D0, *-$7FFC
FDBUEQ D0, *
FDBUGT D0, *+$010E
FDBUGT D0, *-$7FFE
FDBUGT D0, *+$0110
FDBUGT D0, *-$7FFC
FDBUGT D0, *
FDBUGE D0, *+$010E
FDBUGE D0, *-$7FFE
FDBUGE D0, *+$0110
FDBUGE D0, *-$7FFC
FDBUGE D0, *
FDBULT D0, *+$0110
FDBULT D0, *-$7FFE
FDBULT D0, *+$0112
FDBULT D0, *-$7FFC
FDBULT D0, *
FDBULE D0, *+$0110
FDBULE D0, *-$7FFE
FDBULE D0, *+$0112
FDBULE D0, *-$7FFC
FDBULE D0, *
FDBNE D0, *+$0112
FDBNE D0, *-$7FFE
FDBNE D0, *+$0114
FDBNE D0, *-$7FFC
FDBNE D0, *
FDBT D0, *+$0112
FDBT D0, *-$7FFE
FDBT D0, *+$0114
FDBT D0, *-$7FFC
FDBT D0, *
FDBSF D0, *+$0114
FDBSF D0, *-$7FFE
FDBSF D0, *+$0116
FDBSF D0, *-$7FFC
FDBSF D0, *
FDBSEQ D0, *+$0114
FDBSEQ D0, *-$7FFE
FDBSEQ D0, *+$0116
FDBSEQ D0, *-$7FFC
FDBSEQ D0, *
FDBGT D0, *+$0116
FDBGT D0, *-$7FFE
FDBGT D0, *+$0118
FDBGT D0, *-$7FFC
FDBGT D0, *
FDBGE D0, *+$0116
FDBGE D0, *-$7FFE
FDBGE D0, *+$0118
FDBGE D0, *-$7FFC
FDBGE D0, *
FDBLT D0, *+$0118
FDBLT D0, *-$7FFE
FDBLT D0, *+$011A
FDBLT D0, *-$7FFC
FDBLT D0, *
FDBLE D0, *+$0118
FDBLE D0, *-$7FFE
FDBLE D0, *+$011A
FDBLE D0, *-$7FFC
FDBLE D0, *
FDBGL D0, *+$011A
FDBGL D0, *-$7FFE
FDBGL D0, *+$011C
FDBGL D0, *-$7FFC
FDBGL D0, *
FDBGLE D0, *+$011A
FDBGLE D0, *-$7FFE
FDBGLE D0, *+$011C
FDBGLE D0, *-$7FFC
FDBGLE D0, *
FDBNGLE D0, *+$011C
FDBNGLE D0, *-$7FFE
FDBNGLE D0, *+$011E
FDBNGLE D0, *-$7FFC
FDBNGLE D0, *
FDBNGL D0, *+$011C
FDBNGL D0, *-$7FFE
FDBNGL D0, *+$011E
FDBNGL D0, *-$7FFC
FDBNGL D0, *
FDBNLE D0, *+$011E
FDBNLE D0, *-$7FFE
FDBNLE D0, *+$0120
FDBNLE D0, *-$7FFC
FDBNLE D0, *
FDBNLT D0, *+$011E
FDBNLT D0, *-$7FFE
FDBNLT D0, *+$0120
FDBNLT D0, *-$7FFC
FDBNLT D0, *
FDBNGE D0, *+$0120
FDBNGE D0, *-$7FFE
FDBNGE D0, *+$0122
FDBNGE D0, *-$7FFC
FDBNGE D0, *
FDBNGT D0, *+$0120
FDBNGT D0, *-$7FFE
FDBNGT D0, *+$0122
FDBNGT D0, *-$7FFC
FDBNGT D0, *
FDBSNE D0, *+$0122
FDBSNE D0, *-$7FFE
FDBSNE D0, *+$0124
FDBSNE D0, *-$7FFC
FDBSNE D0, *
FDBST D0, *+$0122
FDBST D0, *-$7FFE
FDBST D0, *+$0124
FDBST D0, *-$7FFC
FDBST D0, *
FSF (A0)
FSEQ (A0)
Expand Down
64 changes: 32 additions & 32 deletions test/reference/test_mc68000.s28
Original file line number Diff line number Diff line change
Expand Up @@ -799,100 +799,100 @@ S2140134603454F2D700123454F2D800123454F2D93C
S21401347000123454F2DA00123454F2DB00123454DF
S214013480F2DC00123454F2DD00123454F2DE001283
S2140134903454F2DF00123454F2420000F24A0000C3
S2140134A01232F2520000F25A0000F2620000F26A92
S2140134A01230F2520000F25A0000F2620000F26A94
S2140134B000001234F27200003012F278000012346A
S2140134C0F279000000123456F2420001F24A00017D
S2140134D01232F2520001F25A0001F2620001F26A5F
S2140134D01230F2520001F25A0001F2620001F26A61
S2140134E000011234F27200013012F2780001123437
S2140134F0F279000100123456F2420002F24A00024A
S2140135001232F2520002F25A0002F2620002F26A2B
S2140135001230F2520002F25A0002F2620002F26A2D
S21401351000021234F27200023012F2780002123403
S214013520F279000200123456F2420003F24A000316
S2140135301232F2520003F25A0003F2620003F26AF8
S2140135301230F2520003F25A0003F2620003F26AFA
S21401354000031234F27200033012F27800031234D0
S214013550F279000300123456F2420004F24A0004E3
S2140135601232F2520004F25A0004F2620004F26AC5
S2140135601230F2520004F25A0004F2620004F26AC7
S21401357000041234F27200043012F278000412349D
S214013580F279000400123456F2420005F24A0005B0
S2140135901232F2520005F25A0005F2620005F26A92
S2140135901230F2520005F25A0005F2620005F26A94
S2140135A000051234F27200053012F278000512346A
S2140135B0F279000500123456F2420006F24A00067D
S2140135C01232F2520006F25A0006F2620006F26A5F
S2140135C01230F2520006F25A0006F2620006F26A61
S2140135D000061234F27200063012F2780006123437
S2140135E0F279000600123456F2420007F24A00074A
S2140135F01232F2520007F25A0007F2620007F26A2C
S2140135F01230F2520007F25A0007F2620007F26A2E
S21401360000071234F27200073012F2780007123403
S214013610F279000700123456F2420008F24A000816
S2140136201232F2520008F25A0008F2620008F26AF8
S2140136201230F2520008F25A0008F2620008F26AFA
S21401363000081234F27200083012F27800081234D0
S214013640F279000800123456F2420009F24A0009E3
S2140136501232F2520009F25A0009F2620009F26AC5
S2140136501230F2520009F25A0009F2620009F26AC7
S21401366000091234F27200093012F278000912349D
S214013670F279000900123456F242000AF24A000AB0
S2140136801232F252000AF25A000AF262000AF26A92
S2140136801230F252000AF25A000AF262000AF26A94
S214013690000A1234F272000A3012F278000A12346A
S2140136A0F279000A00123456F242000BF24A000B7D
S2140136B01232F252000BF25A000BF262000BF26A5F
S2140136B01230F252000BF25A000BF262000BF26A61
S2140136C0000B1234F272000B3012F278000B123437
S2140136D0F279000B00123456F242000CF24A000C4A
S2140136E01232F252000CF25A000CF262000CF26A2C
S2140136E01230F252000CF25A000CF262000CF26A2E
S2140136F0000C1234F272000C3012F278000C123404
S214013700F279000C00123456F242000DF24A000D16
S2140137101232F252000DF25A000DF262000DF26AF8
S2140137101230F252000DF25A000DF262000DF26AFA
S214013720000D1234F272000D3012F278000D1234D0
S214013730F279000D00123456F242000EF24A000EE3
S2140137401232F252000EF25A000EF262000EF26AC5
S2140137401230F252000EF25A000EF262000EF26AC7
S214013750000E1234F272000E3012F278000E12349D
S214013760F279000E00123456F242000FF24A000FB0
S2140137701232F252000FF25A000FF262000FF26A92
S2140137701230F252000FF25A000FF262000FF26A94
S214013780000F1234F272000F3012F278000F12346A
S214013790F279000F00123456F2420010F24A00107D
S2140137A01232F2520010F25A0010F2620010F26A5F
S2140137A01230F2520010F25A0010F2620010F26A61
S2140137B000101234F27200103012F2780010123437
S2140137C0F279001000123456F2420011F24A00114A
S2140137D01232F2520011F25A0011F2620011F26A2C
S2140137D01230F2520011F25A0011F2620011F26A2E
S2140137E000111234F27200113012F2780011123404
S2140137F0F279001100123456F2420012F24A001217
S2140138001232F2520012F25A0012F2620012F26AF8
S2140138001230F2520012F25A0012F2620012F26AFA
S21401381000121234F27200123012F27800121234D0
S214013820F279001200123456F2420013F24A0013E3
S2140138301232F2520013F25A0013F2620013F26AC5
S2140138301230F2520013F25A0013F2620013F26AC7
S21401384000131234F27200133012F278001312349D
S214013850F279001300123456F2420014F24A0014B0
S2140138601232F2520014F25A0014F2620014F26A92
S2140138601230F2520014F25A0014F2620014F26A94
S21401387000141234F27200143012F278001412346A
S214013880F279001400123456F2420015F24A00157D
S2140138901232F2520015F25A0015F2620015F26A5F
S2140138901230F2520015F25A0015F2620015F26A61
S2140138A000151234F27200153012F2780015123437
S2140138B0F279001500123456F2420016F24A00164A
S2140138C01232F2520016F25A0016F2620016F26A2C
S2140138C01230F2520016F25A0016F2620016F26A2E
S2140138D000161234F27200163012F2780016123404
S2140138E0F279001600123456F2420017F24A001717
S2140138F01232F2520017F25A0017F2620017F26AF9
S2140138F01230F2520017F25A0017F2620017F26AFB
S21401390000171234F27200173012F27800171234D0
S214013910F279001700123456F2420018F24A0018E3
S2140139201232F2520018F25A0018F2620018F26AC5
S2140139201230F2520018F25A0018F2620018F26AC7
S21401393000181234F27200183012F278001812349D
S214013940F279001800123456F2420019F24A0019B0
S2140139501232F2520019F25A0019F2620019F26A92
S2140139501230F2520019F25A0019F2620019F26A94
S21401396000191234F27200193012F278001912346A
S214013970F279001900123456F242001AF24A001A7D
S2140139801232F252001AF25A001AF262001AF26A5F
S2140139801230F252001AF25A001AF262001AF26A61
S214013990001A1234F272001A3012F278001A123437
S2140139A0F279001A00123456F242001BF24A001B4A
S2140139B01232F252001BF25A001BF262001BF26A2C
S2140139B01230F252001BF25A001BF262001BF26A2E
S2140139C0001B1234F272001B3012F278001B123404
S2140139D0F279001B00123456F242001CF24A001C17
S2140139E01232F252001CF25A001CF262001CF26AF9
S2140139E01230F252001CF25A001CF262001CF26AFB
S2140139F0001C1234F272001C3012F278001C1234D1
S214013A00F279001C00123456F242001DF24A001DE3
S214013A101232F252001DF25A001DF262001DF26AC5
S214013A101230F252001DF25A001DF262001DF26AC7
S214013A20001D1234F272001D3012F278001D12349D
S214013A30F279001D00123456F242001EF24A001EB0
S214013A401232F252001EF25A001EF262001EF26A92
S214013A401230F252001EF25A001EF262001EF26A94
S214013A50001E1234F272001E3012F278001E12346A
S214013A60F279001E00123456F242001FF24A001F7D
S214013A701232F252001FF25A001FF262001FF26A5F
S214013A701230F252001FF25A001FF262001FF26A61
S214013A80001F1234F272001F3012F278001F123437
S214013A90F279001F00123456F356F358F36C1234C1
S214013AA0F3767023F3784566F3790056789AF31621
Expand Down
Loading

0 comments on commit 1213dc9

Please sign in to comment.