-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[M68k] add 32 bit branch instrs and relaxations #117371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
fa024dc
to
9400bff
Compare
@llvm/pr-subscribers-backend-m68k Author: None (knickish) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/117371.diff 6 Files Affected:
diff --git a/llvm/lib/Target/M68k/M68kInstrControl.td b/llvm/lib/Target/M68k/M68kInstrControl.td
index 6e116d7cfe4019..4e94b2ed3a0645 100644
--- a/llvm/lib/Target/M68k/M68kInstrControl.td
+++ b/llvm/lib/Target/M68k/M68kInstrControl.td
@@ -179,6 +179,8 @@ class MxBcc<string cc, Operand TARGET, dag disp_8, dag disp_16_32>
(descend 0b0110, !cast<MxEncCondOp>("MxCC"#cc).Value, disp_8),
disp_16_32
);
+
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
@@ -190,6 +192,10 @@ foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
def B#cc#"16"
: MxBcc<cc, MxBrTarget16, (descend 0b0000, 0b0000),
(operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
+
+ def B#cc#"32"
+ : MxBcc<cc, MxBrTarget32, (descend 0b1111, 0b1111),
+ (operand "$dst", 32, (encoder "encodePCRelImm<32>"))>;
}
foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
@@ -215,6 +221,8 @@ class MxBra<Operand TARGET, dag disp_8, dag disp_16_32>
(descend 0b0110, 0b0000, disp_8),
disp_16_32
);
+
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
def BRA8 : MxBra<MxBrTarget8,
@@ -223,6 +231,10 @@ def BRA8 : MxBra<MxBrTarget8,
def BRA16 : MxBra<MxBrTarget16, (descend 0b0000, 0b0000),
(operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
+def BRA32 : MxBra<MxBrTarget32, (descend 0b1111, 0b1111),
+ (operand "$dst", 32, (encoder "encodePCRelImm<32>"),
+ (decoder "DecodeImm32"))>;
+
def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;
/// -------------------------------------------------
@@ -242,6 +254,7 @@ class MxBsr<Operand TARGET, MxType TYPE, dag disp_8, dag disp_16_32>
(descend 0b0110, 0b0001, disp_8),
disp_16_32
);
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
def BSR8 : MxBsr<MxBrTarget8, MxType8,
diff --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
index 2c52fe07bb1119..298ec1cfc7c539 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
@@ -30,18 +30,26 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+#define DEBUG_TYPE "M68k-asm-backend"
+
namespace {
class M68kAsmBackend : public MCAsmBackend {
+ bool Allows32BitBranch;
public:
- M68kAsmBackend(const Target &T) : MCAsmBackend(llvm::endianness::big) {}
+ M68kAsmBackend(const Target &T, const MCSubtargetInfo &STI)
+ : MCAsmBackend(llvm::endianness::big),
+ Allows32BitBranch(llvm::StringSwitch<bool>(STI.getCPU())
+ .CasesLower("m68020", "m68030", "m68040", true)
+ .Default(false)) {}
unsigned getNumFixupKinds() const override { return 0; }
@@ -51,14 +59,26 @@ class M68kAsmBackend : public MCAsmBackend {
const MCSubtargetInfo *STI) const override {
unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
- assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");
+ if (Fixup.getOffset() + Size > Data.size()) {
+ LLVM_DEBUG(dbgs() << "Fixup.getOffset(): " << Fixup.getOffset() << '\n');
+ LLVM_DEBUG(dbgs() << "Size: " << Size << '\n');
+ LLVM_DEBUG(dbgs() << "Data.size(): " << Data.size() << '\n');
+ assert(Fixup.getOffset() + Size <= Data.size() &&
+ "Invalid fixup offset!");
+ }
// Check that uppper bits are either all zeros or all ones.
// Specifically ignore overflow/underflow as long as the leakage is
// limited to the lower bits. This is to remain compatible with
// other assemblers.
- assert(isIntN(Size * 8 + 1, Value) &&
- "Value does not fit in the Fixup field");
+ if (!isIntN(Size * 8 + 1, Value)) {
+ LLVM_DEBUG(dbgs() << "Fixup.getOffset(): " << Fixup.getOffset() << '\n');
+ LLVM_DEBUG(dbgs() << "Size: " << Size << '\n');
+ LLVM_DEBUG(dbgs() << "Data.size(): " << Data.size() << '\n');
+ LLVM_DEBUG(dbgs() << "Value: " << Value << '\n');
+ assert(isIntN(Size * 8 + 1, Value) &&
+ "Value does not fit in the Fixup field");
+ }
// Write in Big Endian
for (unsigned i = 0; i != Size; ++i)
@@ -99,6 +119,8 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst) {
switch (Op) {
default:
return Op;
+
+ // 8 -> 16
case M68k::BRA8:
return M68k::BRA16;
case M68k::Bcc8:
@@ -129,6 +151,38 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst) {
return M68k::Ble16;
case M68k::Bvs8:
return M68k::Bvs16;
+
+ // 16 -> 32
+ case M68k::BRA16:
+ return M68k::BRA32;
+ case M68k::Bcc16:
+ return M68k::Bcc32;
+ case M68k::Bls16:
+ return M68k::Bls32;
+ case M68k::Blt16:
+ return M68k::Blt32;
+ case M68k::Beq16:
+ return M68k::Beq32;
+ case M68k::Bmi16:
+ return M68k::Bmi32;
+ case M68k::Bne16:
+ return M68k::Bne32;
+ case M68k::Bge16:
+ return M68k::Bge32;
+ case M68k::Bcs16:
+ return M68k::Bcs32;
+ case M68k::Bpl16:
+ return M68k::Bpl32;
+ case M68k::Bgt16:
+ return M68k::Bgt32;
+ case M68k::Bhi16:
+ return M68k::Bhi32;
+ case M68k::Bvc16:
+ return M68k::Bvc32;
+ case M68k::Ble16:
+ return M68k::Ble32;
+ case M68k::Bvs16:
+ return M68k::Bvs32;
}
}
@@ -167,8 +221,7 @@ bool M68kAsmBackend::mayNeedRelaxation(const MCInst &Inst,
bool M68kAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value) const {
- // TODO Newer CPU can use 32 bit offsets, so check for this when ready
- if (!isInt<16>(Value)) {
+ if (!isInt<32>(Value) || (!Allows32BitBranch && !isInt<16>(Value))) {
llvm_unreachable("Cannot relax the instruction, value does not fit");
}
// Relax if the value is too big for a (signed) i8. This means that byte-wide
@@ -178,7 +231,15 @@ bool M68kAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
// A branch to the immediately following instruction automatically
// uses the 16-bit displacement format because the 8-bit
// displacement field contains $00 (zero offset).
- return Value == 0 || !isInt<8>(Value);
+ unsigned int KindLog2Size = getFixupKindLog2Size(Fixup.getKind());
+ bool FixupFieldTooSmall = false;
+ if (!isInt<8>(Value) && KindLog2Size == 0) {
+ FixupFieldTooSmall |= true;
+ } else if (!isInt<16>(Value) && KindLog2Size <= 1) {
+ FixupFieldTooSmall |= true;
+ }
+
+ return Value == 0 || FixupFieldTooSmall;
}
// NOTE Can tblgen help at all here to verify there aren't other instructions
@@ -218,8 +279,8 @@ namespace {
class M68kELFAsmBackend : public M68kAsmBackend {
public:
uint8_t OSABI;
- M68kELFAsmBackend(const Target &T, uint8_t OSABI)
- : M68kAsmBackend(T), OSABI(OSABI) {}
+ M68kELFAsmBackend(const Target &T, const MCSubtargetInfo &STI, uint8_t OSABI)
+ : M68kAsmBackend(T, STI), OSABI(OSABI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -235,5 +296,5 @@ MCAsmBackend *llvm::createM68kAsmBackend(const Target &T,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- return new M68kELFAsmBackend(T, OSABI);
+ return new M68kELFAsmBackend(T, STI, OSABI);
}
diff --git a/llvm/test/MC/M68k/Control/bsr.s b/llvm/test/MC/M68k/Control/bsr.s
index a70c7fb9a96edf..6b7a7d5c6ecd94 100644
--- a/llvm/test/MC/M68k/Control/bsr.s
+++ b/llvm/test/MC/M68k/Control/bsr.s
@@ -8,10 +8,6 @@
; CHECK-SAME: encoding: [0x61,0x00,A,A]
; CHECK: fixup A - offset: 2, value: .LBB0_2, kind: FK_PCRel_2
bsr.w .LBB0_2
- ; CHECK: bsr.l .LBB0_3
- ; CHECK-SAME: encoding: [0x61,0xff,A,A,A,A]
- ; CHECK: fixup A - offset: 2, value: .LBB0_3, kind: FK_PCRel_4
- bsr.l .LBB0_3
.LBB0_1:
; CHECK: add.l #0, %d0
; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x00]
@@ -26,10 +22,3 @@
; CHECK: rts
; CHECK-SAME: encoding: [0x4e,0x75]
rts
-.LBB0_3:
- ; CHECK: add.l #1, %d0
- ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
- add.l #1, %d0
- ; CHECK: rts
- ; CHECK-SAME: encoding: [0x4e,0x75]
- rts
diff --git a/llvm/test/MC/M68k/Control/bsr32.s b/llvm/test/MC/M68k/Control/bsr32.s
new file mode 100644
index 00000000000000..58ed4a29a35318
--- /dev/null
+++ b/llvm/test/MC/M68k/Control/bsr32.s
@@ -0,0 +1,35 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -show-encoding %s | FileCheck %s
+
+ ; CHECK: bsr.b .LBB0_1
+ ; CHECK-SAME: encoding: [0x61,A]
+ ; CHECK: fixup A - offset: 1, value: .LBB0_1-1, kind: FK_PCRel_1
+ bsr.b .LBB0_1
+ ; CHECK: bsr.w .LBB0_2
+ ; CHECK-SAME: encoding: [0x61,0x00,A,A]
+ ; CHECK: fixup A - offset: 2, value: .LBB0_2, kind: FK_PCRel_2
+ bsr.w .LBB0_2
+ ; CHECK: bsr.l .LBB0_3
+ ; CHECK-SAME: encoding: [0x61,0xff,A,A,A,A]
+ ; CHECK: fixup A - offset: 2, value: .LBB0_3, kind: FK_PCRel_4
+ bsr.l .LBB0_3
+.LBB0_1:
+ ; CHECK: add.l #0, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x00]
+ add.l #0, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
+.LBB0_2:
+ ; CHECK: add.l #1, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
+ add.l #1, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
+.LBB0_3:
+ ; CHECK: add.l #1, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
+ add.l #1, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
diff --git a/llvm/test/MC/M68k/Relaxations/branch32.s b/llvm/test/MC/M68k/Relaxations/branch32.s
new file mode 100644
index 00000000000000..d8bb3d40e639e8
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/branch32.s
@@ -0,0 +1,63 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -motorola-integers -filetype=obj < %s \
+; RUN: | llvm-objdump -d - | FileCheck %s
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+ ; CHECK: bra $78
+ bra .LBB0_2
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+.LBB0_2:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <RELAXED>:
+RELAXED:
+ ; CHECK: bra $84
+ bra .LBB1_2
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+.LBB1_2:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <RELAXED_32>:
+RELAXED_32:
+ ; CHECK: bra $ff
+ ; CHECK-NEXT: 00 02
+ ; CHECK-NEXT: 00 00
+ bra .LBB3_1
+ .space 0x20000 ; Greater than u16::MAX.
+.LBB2_1:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <ZERO>:
+ZERO:
+ ; CHECK: bra $2
+ bra .LBB3_1
+.LBB3_1:
+ add.l #0, %d0
+ rts
+
diff --git a/llvm/test/MC/M68k/Relocations/text-plt.s b/llvm/test/MC/M68k/Relocations/text-plt.s
index 9513519c33c670..7de04b8b2182a5 100644
--- a/llvm/test/MC/M68k/Relocations/text-plt.s
+++ b/llvm/test/MC/M68k/Relocations/text-plt.s
@@ -1,6 +1,6 @@
-; RUN: llvm-mc -triple m68k -filetype=obj %s -o - \
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -filetype=obj %s -o - \
; RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
-; RUN: llvm-mc -triple m68k -show-encoding %s -o - \
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -show-encoding %s -o - \
; RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
; RELOC: R_68K_PLT16 target 0x0
|
@llvm/pr-subscribers-mc Author: None (knickish) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/117371.diff 6 Files Affected:
diff --git a/llvm/lib/Target/M68k/M68kInstrControl.td b/llvm/lib/Target/M68k/M68kInstrControl.td
index 6e116d7cfe4019..4e94b2ed3a0645 100644
--- a/llvm/lib/Target/M68k/M68kInstrControl.td
+++ b/llvm/lib/Target/M68k/M68kInstrControl.td
@@ -179,6 +179,8 @@ class MxBcc<string cc, Operand TARGET, dag disp_8, dag disp_16_32>
(descend 0b0110, !cast<MxEncCondOp>("MxCC"#cc).Value, disp_8),
disp_16_32
);
+
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
@@ -190,6 +192,10 @@ foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
def B#cc#"16"
: MxBcc<cc, MxBrTarget16, (descend 0b0000, 0b0000),
(operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
+
+ def B#cc#"32"
+ : MxBcc<cc, MxBrTarget32, (descend 0b1111, 0b1111),
+ (operand "$dst", 32, (encoder "encodePCRelImm<32>"))>;
}
foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
@@ -215,6 +221,8 @@ class MxBra<Operand TARGET, dag disp_8, dag disp_16_32>
(descend 0b0110, 0b0000, disp_8),
disp_16_32
);
+
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
def BRA8 : MxBra<MxBrTarget8,
@@ -223,6 +231,10 @@ def BRA8 : MxBra<MxBrTarget8,
def BRA16 : MxBra<MxBrTarget16, (descend 0b0000, 0b0000),
(operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
+def BRA32 : MxBra<MxBrTarget32, (descend 0b1111, 0b1111),
+ (operand "$dst", 32, (encoder "encodePCRelImm<32>"),
+ (decoder "DecodeImm32"))>;
+
def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;
/// -------------------------------------------------
@@ -242,6 +254,7 @@ class MxBsr<Operand TARGET, MxType TYPE, dag disp_8, dag disp_16_32>
(descend 0b0110, 0b0001, disp_8),
disp_16_32
);
+ let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);
}
def BSR8 : MxBsr<MxBrTarget8, MxType8,
diff --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
index 2c52fe07bb1119..298ec1cfc7c539 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
@@ -30,18 +30,26 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+#define DEBUG_TYPE "M68k-asm-backend"
+
namespace {
class M68kAsmBackend : public MCAsmBackend {
+ bool Allows32BitBranch;
public:
- M68kAsmBackend(const Target &T) : MCAsmBackend(llvm::endianness::big) {}
+ M68kAsmBackend(const Target &T, const MCSubtargetInfo &STI)
+ : MCAsmBackend(llvm::endianness::big),
+ Allows32BitBranch(llvm::StringSwitch<bool>(STI.getCPU())
+ .CasesLower("m68020", "m68030", "m68040", true)
+ .Default(false)) {}
unsigned getNumFixupKinds() const override { return 0; }
@@ -51,14 +59,26 @@ class M68kAsmBackend : public MCAsmBackend {
const MCSubtargetInfo *STI) const override {
unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
- assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");
+ if (Fixup.getOffset() + Size > Data.size()) {
+ LLVM_DEBUG(dbgs() << "Fixup.getOffset(): " << Fixup.getOffset() << '\n');
+ LLVM_DEBUG(dbgs() << "Size: " << Size << '\n');
+ LLVM_DEBUG(dbgs() << "Data.size(): " << Data.size() << '\n');
+ assert(Fixup.getOffset() + Size <= Data.size() &&
+ "Invalid fixup offset!");
+ }
// Check that uppper bits are either all zeros or all ones.
// Specifically ignore overflow/underflow as long as the leakage is
// limited to the lower bits. This is to remain compatible with
// other assemblers.
- assert(isIntN(Size * 8 + 1, Value) &&
- "Value does not fit in the Fixup field");
+ if (!isIntN(Size * 8 + 1, Value)) {
+ LLVM_DEBUG(dbgs() << "Fixup.getOffset(): " << Fixup.getOffset() << '\n');
+ LLVM_DEBUG(dbgs() << "Size: " << Size << '\n');
+ LLVM_DEBUG(dbgs() << "Data.size(): " << Data.size() << '\n');
+ LLVM_DEBUG(dbgs() << "Value: " << Value << '\n');
+ assert(isIntN(Size * 8 + 1, Value) &&
+ "Value does not fit in the Fixup field");
+ }
// Write in Big Endian
for (unsigned i = 0; i != Size; ++i)
@@ -99,6 +119,8 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst) {
switch (Op) {
default:
return Op;
+
+ // 8 -> 16
case M68k::BRA8:
return M68k::BRA16;
case M68k::Bcc8:
@@ -129,6 +151,38 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst) {
return M68k::Ble16;
case M68k::Bvs8:
return M68k::Bvs16;
+
+ // 16 -> 32
+ case M68k::BRA16:
+ return M68k::BRA32;
+ case M68k::Bcc16:
+ return M68k::Bcc32;
+ case M68k::Bls16:
+ return M68k::Bls32;
+ case M68k::Blt16:
+ return M68k::Blt32;
+ case M68k::Beq16:
+ return M68k::Beq32;
+ case M68k::Bmi16:
+ return M68k::Bmi32;
+ case M68k::Bne16:
+ return M68k::Bne32;
+ case M68k::Bge16:
+ return M68k::Bge32;
+ case M68k::Bcs16:
+ return M68k::Bcs32;
+ case M68k::Bpl16:
+ return M68k::Bpl32;
+ case M68k::Bgt16:
+ return M68k::Bgt32;
+ case M68k::Bhi16:
+ return M68k::Bhi32;
+ case M68k::Bvc16:
+ return M68k::Bvc32;
+ case M68k::Ble16:
+ return M68k::Ble32;
+ case M68k::Bvs16:
+ return M68k::Bvs32;
}
}
@@ -167,8 +221,7 @@ bool M68kAsmBackend::mayNeedRelaxation(const MCInst &Inst,
bool M68kAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value) const {
- // TODO Newer CPU can use 32 bit offsets, so check for this when ready
- if (!isInt<16>(Value)) {
+ if (!isInt<32>(Value) || (!Allows32BitBranch && !isInt<16>(Value))) {
llvm_unreachable("Cannot relax the instruction, value does not fit");
}
// Relax if the value is too big for a (signed) i8. This means that byte-wide
@@ -178,7 +231,15 @@ bool M68kAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
// A branch to the immediately following instruction automatically
// uses the 16-bit displacement format because the 8-bit
// displacement field contains $00 (zero offset).
- return Value == 0 || !isInt<8>(Value);
+ unsigned int KindLog2Size = getFixupKindLog2Size(Fixup.getKind());
+ bool FixupFieldTooSmall = false;
+ if (!isInt<8>(Value) && KindLog2Size == 0) {
+ FixupFieldTooSmall |= true;
+ } else if (!isInt<16>(Value) && KindLog2Size <= 1) {
+ FixupFieldTooSmall |= true;
+ }
+
+ return Value == 0 || FixupFieldTooSmall;
}
// NOTE Can tblgen help at all here to verify there aren't other instructions
@@ -218,8 +279,8 @@ namespace {
class M68kELFAsmBackend : public M68kAsmBackend {
public:
uint8_t OSABI;
- M68kELFAsmBackend(const Target &T, uint8_t OSABI)
- : M68kAsmBackend(T), OSABI(OSABI) {}
+ M68kELFAsmBackend(const Target &T, const MCSubtargetInfo &STI, uint8_t OSABI)
+ : M68kAsmBackend(T, STI), OSABI(OSABI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -235,5 +296,5 @@ MCAsmBackend *llvm::createM68kAsmBackend(const Target &T,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- return new M68kELFAsmBackend(T, OSABI);
+ return new M68kELFAsmBackend(T, STI, OSABI);
}
diff --git a/llvm/test/MC/M68k/Control/bsr.s b/llvm/test/MC/M68k/Control/bsr.s
index a70c7fb9a96edf..6b7a7d5c6ecd94 100644
--- a/llvm/test/MC/M68k/Control/bsr.s
+++ b/llvm/test/MC/M68k/Control/bsr.s
@@ -8,10 +8,6 @@
; CHECK-SAME: encoding: [0x61,0x00,A,A]
; CHECK: fixup A - offset: 2, value: .LBB0_2, kind: FK_PCRel_2
bsr.w .LBB0_2
- ; CHECK: bsr.l .LBB0_3
- ; CHECK-SAME: encoding: [0x61,0xff,A,A,A,A]
- ; CHECK: fixup A - offset: 2, value: .LBB0_3, kind: FK_PCRel_4
- bsr.l .LBB0_3
.LBB0_1:
; CHECK: add.l #0, %d0
; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x00]
@@ -26,10 +22,3 @@
; CHECK: rts
; CHECK-SAME: encoding: [0x4e,0x75]
rts
-.LBB0_3:
- ; CHECK: add.l #1, %d0
- ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
- add.l #1, %d0
- ; CHECK: rts
- ; CHECK-SAME: encoding: [0x4e,0x75]
- rts
diff --git a/llvm/test/MC/M68k/Control/bsr32.s b/llvm/test/MC/M68k/Control/bsr32.s
new file mode 100644
index 00000000000000..58ed4a29a35318
--- /dev/null
+++ b/llvm/test/MC/M68k/Control/bsr32.s
@@ -0,0 +1,35 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -show-encoding %s | FileCheck %s
+
+ ; CHECK: bsr.b .LBB0_1
+ ; CHECK-SAME: encoding: [0x61,A]
+ ; CHECK: fixup A - offset: 1, value: .LBB0_1-1, kind: FK_PCRel_1
+ bsr.b .LBB0_1
+ ; CHECK: bsr.w .LBB0_2
+ ; CHECK-SAME: encoding: [0x61,0x00,A,A]
+ ; CHECK: fixup A - offset: 2, value: .LBB0_2, kind: FK_PCRel_2
+ bsr.w .LBB0_2
+ ; CHECK: bsr.l .LBB0_3
+ ; CHECK-SAME: encoding: [0x61,0xff,A,A,A,A]
+ ; CHECK: fixup A - offset: 2, value: .LBB0_3, kind: FK_PCRel_4
+ bsr.l .LBB0_3
+.LBB0_1:
+ ; CHECK: add.l #0, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x00]
+ add.l #0, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
+.LBB0_2:
+ ; CHECK: add.l #1, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
+ add.l #1, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
+.LBB0_3:
+ ; CHECK: add.l #1, %d0
+ ; CHECK-SAME: encoding: [0xd0,0xbc,0x00,0x00,0x00,0x01]
+ add.l #1, %d0
+ ; CHECK: rts
+ ; CHECK-SAME: encoding: [0x4e,0x75]
+ rts
diff --git a/llvm/test/MC/M68k/Relaxations/branch32.s b/llvm/test/MC/M68k/Relaxations/branch32.s
new file mode 100644
index 00000000000000..d8bb3d40e639e8
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/branch32.s
@@ -0,0 +1,63 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -motorola-integers -filetype=obj < %s \
+; RUN: | llvm-objdump -d - | FileCheck %s
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+ ; CHECK: bra $78
+ bra .LBB0_2
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+.LBB0_2:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <RELAXED>:
+RELAXED:
+ ; CHECK: bra $84
+ bra .LBB1_2
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+ move.l $0, $0
+.LBB1_2:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <RELAXED_32>:
+RELAXED_32:
+ ; CHECK: bra $ff
+ ; CHECK-NEXT: 00 02
+ ; CHECK-NEXT: 00 00
+ bra .LBB3_1
+ .space 0x20000 ; Greater than u16::MAX.
+.LBB2_1:
+ add.l #0, %d0
+ rts
+
+; CHECK-LABEL: <ZERO>:
+ZERO:
+ ; CHECK: bra $2
+ bra .LBB3_1
+.LBB3_1:
+ add.l #0, %d0
+ rts
+
diff --git a/llvm/test/MC/M68k/Relocations/text-plt.s b/llvm/test/MC/M68k/Relocations/text-plt.s
index 9513519c33c670..7de04b8b2182a5 100644
--- a/llvm/test/MC/M68k/Relocations/text-plt.s
+++ b/llvm/test/MC/M68k/Relocations/text-plt.s
@@ -1,6 +1,6 @@
-; RUN: llvm-mc -triple m68k -filetype=obj %s -o - \
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -filetype=obj %s -o - \
; RUN: | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
-; RUN: llvm-mc -triple m68k -show-encoding %s -o - \
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -show-encoding %s -o - \
; RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
; RELOC: R_68K_PLT16 target 0x0
|
5b91167
to
ea5fef9
Compare
Copied most of the relocation tests to run them with The encoding tests themselves aren't that helpful as the assembly is emitted before fixup relaxation happens for the branches. Might be good to change the branch instructions to pattern match based on size at some point instead of always matching the 8bit version and relaxing |
Ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM w/ minor comments
thanks
uint64_t UnsignedValue) const { | ||
int64_t Value = static_cast<int64_t>(UnsignedValue); | ||
|
||
if (!isInt<32>(Value) || (!Allows32BitBranch && !isInt<16>(Value))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I know the curly braces were already here, but could you drop them? (single statement shouldn't have curly braces)
// that byte-wide instructions have to matched by default | ||
unsigned KindLog2Size = getFixupKindLog2Size(Fixup.getKind()); | ||
bool FixupFieldTooSmall = false; | ||
if (!isInt<8>(Value) && KindLog2Size == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
single statement should not have curly braces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed braces from both
… to 32 bit versions
ea5fef9
to
b125c0f
Compare
Please don't force push unless necessary, append new commits instead (all commits will be squashed into one upon merging) |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/3331 Here is the relevant piece of the build log for the reference
|
I guess llvm-lit doesn't run that test by default. The actual result looks fine, will make a follow-up pr to adjust the test |
Understood, didn't realize they get squashed |
@knickish Your change has made the buildbot unhappy, unfortunately: https://lab.llvm.org/buildbot/#/builders/27/builds/3331 Can you have a look? |
Here is the error message from the testsuite:
|
@glaubitz I can fix it in a few hours, does it need to be reverted before then? |
Nah, I think that should be fine. I assume you're currently getting error mails because of it. |
Have a PR up to fix this now. #119758 |
Local branch amd-gfx 3a0701c Merged main:5e007afa9d4f into amd-gfx:4c17e1c71592 Remote branch main 44c05a6 [M68k] add 32 bit branch instrs and relaxations (llvm#117371)
uint64_t UnsignedValue) const { | ||
int64_t Value = static_cast<int64_t>(UnsignedValue); | ||
|
||
if (!isInt<32>(Value) || (!Allows32BitBranch && !isInt<16>(Value))) | ||
llvm_unreachable("Cannot relax the instruction, value does not fit"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably should be a cleaner error than an unreachable? You can trip this easily by compiling 32-bit-okay code for a 16-bit-only device
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you prefer it to be an assert
instead of llvm_unreachable
, or something more detailed?
The
Bcc
andBRA
32-bit variants were all either not present or not used, and theBSR32
instruction was incorrectly being used on <M68020
cpu types. This PR adds missing 32 bit branch instructions (with theAtLeastM68020
predicate) and updatesM68kAsmBackend
to allow relaxation to these instructions when anM68020
or greater is targeted