[llvm] [M68k] add 32 bit branch instrs and relaxations (PR #117371)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 2 10:41:41 PST 2024


https://github.com/knickish updated https://github.com/llvm/llvm-project/pull/117371

>From 5b91167925f7adf1c82c82a65a39d1dacc163fde Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Fri, 22 Nov 2024 20:16:53 +0000
Subject: [PATCH] [M68k] add 32 bit branch instrs and allow x20 and later CPUs
 to relax to 32 bit versions

---
 llvm/lib/Target/M68k/M68kInstrControl.td      |  13 +++
 .../M68k/MCTargetDesc/M68kAsmBackend.cpp      | 102 +++++++++++++++---
 llvm/test/MC/M68k/Control/bsr.s               |  11 --
 llvm/test/MC/M68k/Control/bsr32.s             |  35 ++++++
 llvm/test/MC/M68k/Relaxations/PIC/branch.s    |  38 +++++++
 llvm/test/MC/M68k/Relaxations/PIC/branch32.s  |  53 +++++++++
 llvm/test/MC/M68k/Relaxations/PIC/bsr.s       |  51 +++++++++
 llvm/test/MC/M68k/Relaxations/branch32.s      |  50 +++++++++
 llvm/test/MC/M68k/Relocations/PIC/data-abs.s  |  26 +++++
 .../MC/M68k/Relocations/PIC/data-gotoff.s     |  19 ++++
 .../MC/M68k/Relocations/PIC/data-gotpcrel.s   |  14 +++
 .../MC/M68k/Relocations/PIC/data-pc-rel.s     |  20 ++++
 llvm/test/MC/M68k/Relocations/PIC/text-plt.s  |  14 +++
 llvm/test/MC/M68k/Relocations/text-plt.s      |   4 +-
 14 files changed, 421 insertions(+), 29 deletions(-)
 create mode 100644 llvm/test/MC/M68k/Control/bsr32.s
 create mode 100644 llvm/test/MC/M68k/Relaxations/PIC/branch.s
 create mode 100644 llvm/test/MC/M68k/Relaxations/PIC/branch32.s
 create mode 100644 llvm/test/MC/M68k/Relaxations/PIC/bsr.s
 create mode 100644 llvm/test/MC/M68k/Relaxations/branch32.s
 create mode 100644 llvm/test/MC/M68k/Relocations/PIC/data-abs.s
 create mode 100644 llvm/test/MC/M68k/Relocations/PIC/data-gotoff.s
 create mode 100644 llvm/test/MC/M68k/Relocations/PIC/data-gotpcrel.s
 create mode 100644 llvm/test/MC/M68k/Relocations/PIC/data-pc-rel.s
 create mode 100644 llvm/test/MC/M68k/Relocations/PIC/text-plt.s

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..b2678a2bbe9fb3 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kAsmBackend.cpp
@@ -29,19 +29,28 @@
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCValue.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,18 +60,34 @@ 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, static_cast<int64_t>(Value)) || IsResolved)) {
+      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');
+      LLVM_DEBUG(dbgs() << "Target: ");
+      LLVM_DEBUG(Target.print(dbgs()));
+      LLVM_DEBUG(dbgs() << '\n');
+      assert(isIntN(Size * 8 + 1, static_cast<int64_t>(Value)) &&
+             "Value does not fit in the Fixup field");
+    }
 
     // Write in Big Endian
     for (unsigned i = 0; i != Size; ++i)
-      Data[Fixup.getOffset() + i] = uint8_t(Value >> ((Size - i - 1) * 8));
+      Data[Fixup.getOffset() + i] =
+          uint8_t(static_cast<int64_t>(Value) >> ((Size - i - 1) * 8));
   }
 
   bool mayNeedRelaxation(const MCInst &Inst,
@@ -99,6 +124,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 +156,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;
   }
 }
 
@@ -166,26 +225,37 @@ 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)) {
+                                          uint64_t UnsignedValue) const {
+  int64_t Value = static_cast<int64_t>(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
-  // instructions have to matched by default
-  //
+
+  // Relax if the value is too big for a (signed) i8
+  // (or signed i16 if 32 bit branches can be used). This means
+  // that byte-wide instructions have to matched by default
+  unsigned KindLog2Size = getFixupKindLog2Size(Fixup.getKind());
+  bool FixupFieldTooSmall = false;
+  if (!isInt<8>(Value) && KindLog2Size == 0) {
+    FixupFieldTooSmall = true;
+  } else if (!isInt<16>(Value) && KindLog2Size <= 1) {
+    FixupFieldTooSmall = true;
+  }
+
   // NOTE
   // 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);
+  bool ZeroDisplacementNeedsFixup = Value == 0 && KindLog2Size == 0;
+
+  return ZeroDisplacementNeedsFixup || FixupFieldTooSmall;
 }
 
 // NOTE Can tblgen help at all here to verify there aren't other instructions
 // we can relax?
 void M68kAsmBackend::relaxInstruction(MCInst &Inst,
                                       const MCSubtargetInfo &STI) const {
-  // The only relaxations M68k does is from a 1byte pcrel to a 2byte PCRel.
   unsigned RelaxedOp = getRelaxedOpcode(Inst);
 
   if (RelaxedOp == Inst.getOpcode()) {
@@ -218,8 +288,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 +305,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/PIC/branch.s b/llvm/test/MC/M68k/Relaxations/PIC/branch.s
new file mode 100644
index 00000000000000..5035ca3ce50a7b
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/PIC/branch.s
@@ -0,0 +1,38 @@
+; RUN: llvm-mc -triple=m68k -motorola-integers -filetype=obj --position-independent < %s \
+; RUN:     | llvm-objdump -d - | FileCheck %s
+; RUN: llvm-mc -triple m68k -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+	; CHECK: bra  $7f
+	; INSTR: bra .LBB0_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB0_2-1, kind: FK_PCRel_1
+	bra	.LBB0_2
+	.space 0x7F  ; i8::MAX
+.LBB0_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <RELAXED>:
+RELAXED:
+	; CHECK: bra  $82
+	; INSTR: bra .LBB1_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1
+	bra	.LBB1_2
+	.space 0x80  ; Greater than i8::MAX
+.LBB1_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <ZERO>:
+ZERO:
+	; CHECK: bra  $2
+	; INSTR: bra .LBB3_1 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1
+	bra	.LBB3_1
+.LBB3_1:
+	add.l	#0, %d0
+	rts
+
+
diff --git a/llvm/test/MC/M68k/Relaxations/PIC/branch32.s b/llvm/test/MC/M68k/Relaxations/PIC/branch32.s
new file mode 100644
index 00000000000000..7e40f055aff13d
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/PIC/branch32.s
@@ -0,0 +1,53 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -motorola-integers -filetype=obj --position-independent < %s \
+; RUN:     | llvm-objdump -d - | FileCheck %s
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; Branch relocations are relaxed as part of object layout, so -show-encoding still 
+; shows them as 1-byte relocactions 
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+	; CHECK: bra  $7f
+	; INSTR: bra .LBB0_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB0_2-1, kind: FK_PCRel_1
+	bra	.LBB0_2
+	.space 0x7F  ; i8::MAX
+.LBB0_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <RELAXED>:
+RELAXED:
+	; CHECK: bra  $82
+	; INSTR: bra .LBB1_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1
+	bra	.LBB1_2
+	.space 0x80  ; Greater than i8::MAX
+.LBB1_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <RELAXED_32>:
+RELAXED_32:
+	; CHECK: bra  $ff
+	; CHECK-NEXT: 00 00
+	; CHECK-NEXT: 80 04
+	; INSTR: bra .LBB2_1 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB2_1-1, kind: FK_PCRel_1
+	bra	.LBB2_1
+	.space 0x8000  ; Greater than i16::MAX.
+.LBB2_1:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <ZERO>:
+ZERO:
+	; CHECK: bra  $2
+	; INSTR: bra .LBB3_1 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1
+	bra	.LBB3_1
+.LBB3_1:
+	add.l	#0, %d0
+	rts
+
diff --git a/llvm/test/MC/M68k/Relaxations/PIC/bsr.s b/llvm/test/MC/M68k/Relaxations/PIC/bsr.s
new file mode 100644
index 00000000000000..67adcd545450e9
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/PIC/bsr.s
@@ -0,0 +1,51 @@
+; RUN: llvm-mc -triple=m68k -motorola-integers -filetype=obj --position-independent < %s \
+; RUN:     | llvm-objdump -d - | FileCheck %s
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+  ; CHECK: bsr.w   $7a
+	bsr.w	.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: bsr.b   $82
+	bsr.b	.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: <ZERO>:
+ZERO:
+  ; CHECK: bsr.w    $2
+	bsr.w	.LBB2_1
+.LBB2_1:
+	add.l	#0, %d0
+	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..ba5c371dada8de
--- /dev/null
+++ b/llvm/test/MC/M68k/Relaxations/branch32.s
@@ -0,0 +1,50 @@
+; RUN: llvm-mc -triple=m68k --mcpu=M68020 -motorola-integers -filetype=obj < %s \
+; RUN:     | llvm-objdump -d - | FileCheck %s
+; RUN: llvm-mc -triple m68k --mcpu=M68020 -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; CHECK-LABEL: <TIGHT>:
+TIGHT:
+	; CHECK: bra  $7f
+	; INSTR: bra .LBB0_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB0_2-1, kind: FK_PCRel_1
+	bra	.LBB0_2
+	.space 0x7F  ; i8::MAX
+.LBB0_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <RELAXED>:
+RELAXED:
+	; CHECK: bra  $82
+	; INSTR: bra .LBB1_2 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1
+	bra	.LBB1_2
+	.space 0x80  ; Greater than i8::MAX
+.LBB1_2:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <RELAXED_32>:
+RELAXED_32:
+	; CHECK: bra  $ff
+	; CHECK-NEXT: 00 00
+	; CHECK-NEXT: 80 04
+	; INSTR: bra .LBB2_1 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB2_1-1, kind: FK_PCRel_1
+	bra	.LBB2_1
+	.space 0x8000  ; Greater than i16::MAX.
+.LBB2_1:
+	add.l	#0, %d0
+	rts
+
+; CHECK-LABEL: <ZERO>:
+ZERO:
+	; CHECK: bra  $2
+	; INSTR: bra .LBB3_1 ; encoding: [0x60,A]
+	; FIXUP: fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1
+	bra	.LBB3_1
+.LBB3_1:
+	add.l	#0, %d0
+	rts
+
diff --git a/llvm/test/MC/M68k/Relocations/PIC/data-abs.s b/llvm/test/MC/M68k/Relocations/PIC/data-abs.s
new file mode 100644
index 00000000000000..0df09c8cb5ccb5
--- /dev/null
+++ b/llvm/test/MC/M68k/Relocations/PIC/data-abs.s
@@ -0,0 +1,26 @@
+; RUN: llvm-mc -triple m68k -filetype=obj --position-independent %s -o - \
+; RUN:   | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+; RUN: llvm-mc -triple m68k -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; RELOC: R_68K_32 dst 0x0
+; INSTR: move.l dst, %d0
+; FIXUP: fixup A - offset: 2, value: dst, kind: FK_Data_4
+move.l	dst, %d0
+
+; Relocating immediate values
+
+; RELOC: R_68K_8 str8 0x0
+; INSTR: move.b  #str8,  (4,%sp)
+; FIXUP: fixup A - offset: 3, value: str8, kind: FK_Data_1
+move.b  #str8,  (4,%sp)
+
+; RELOC: R_68K_16 str16 0x0
+; INSTR: move.w  #str16,  (4,%sp)
+; FIXUP: fixup A - offset: 2, value: str16, kind: FK_Data_2
+move.w  #str16, (4,%sp)
+
+; RELOC: R_68K_32 str32 0x0
+; INSTR: move.l  #str32,  (4,%sp)
+; FIXUP: fixup A - offset: 2, value: str32, kind: FK_Data_4
+move.l  #str32, (4,%sp)
diff --git a/llvm/test/MC/M68k/Relocations/PIC/data-gotoff.s b/llvm/test/MC/M68k/Relocations/PIC/data-gotoff.s
new file mode 100644
index 00000000000000..ca1ce52de1ca75
--- /dev/null
+++ b/llvm/test/MC/M68k/Relocations/PIC/data-gotoff.s
@@ -0,0 +1,19 @@
+; RUN: llvm-mc -triple m68k -filetype=obj --position-independent %s -o - \
+; RUN:   | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+; RUN: llvm-mc -triple m68k -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; RELOC: R_68K_GOTOFF8 dst1 0x0
+; INSTR: move.l  (dst1 at GOTOFF,%a5,%d0), %d0
+; FIXUP: fixup A - offset: 3, value: dst1 at GOTOFF, kind: FK_Data_1
+move.l	(dst1 at GOTOFF,%a5,%d0), %d0
+
+; RELOC: R_68K_GOTOFF16 dst2 0x0
+; INSTR: move.l  (dst2 at GOTOFF,%a5), %d0
+; FIXUP: fixup A - offset: 2, value: dst2 at GOTOFF, kind: FK_Data_2
+move.l	(dst2 at GOTOFF,%a5), %d0
+
+; RELOC: R_68K_GOTPCREL16 dst3 0x0
+; INSTR: lea     (dst3 at GOTPCREL,%pc), %a5
+; FIXUP: fixup A - offset: 2, value: dst3 at GOTPCREL, kind: FK_PCRel_2
+lea	(dst3 at GOTPCREL,%pc), %a5
diff --git a/llvm/test/MC/M68k/Relocations/PIC/data-gotpcrel.s b/llvm/test/MC/M68k/Relocations/PIC/data-gotpcrel.s
new file mode 100644
index 00000000000000..9f79dd94f8198a
--- /dev/null
+++ b/llvm/test/MC/M68k/Relocations/PIC/data-gotpcrel.s
@@ -0,0 +1,14 @@
+; RUN: llvm-mc -triple m68k -filetype=obj --position-independent %s -o - \
+; RUN:   | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+; RUN: llvm-mc -triple m68k -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; RELOC: R_68K_GOTPCREL8 dst1 0x1
+; INSTR: move.l  (dst1 at GOTPCREL,%pc,%d0), %a0
+; FIXUP: fixup A - offset: 3, value: dst1 at GOTPCREL+1, kind: FK_PCRel_1
+move.l	(dst1 at GOTPCREL,%pc,%d0), %a0
+
+; RELOC: R_68K_GOTPCREL16 dst2 0x0
+; INSTR: move.l  (dst2 at GOTPCREL,%pc), %a0
+; FIXUP: fixup A - offset: 2, value: dst2 at GOTPCREL, kind: FK_PCRel_2
+move.l	(dst2 at GOTPCREL,%pc), %a0
diff --git a/llvm/test/MC/M68k/Relocations/PIC/data-pc-rel.s b/llvm/test/MC/M68k/Relocations/PIC/data-pc-rel.s
new file mode 100644
index 00000000000000..ef57ca589e64fe
--- /dev/null
+++ b/llvm/test/MC/M68k/Relocations/PIC/data-pc-rel.s
@@ -0,0 +1,20 @@
+; RUN: llvm-mc -triple m68k -filetype=obj --position-independent %s -o - \
+; RUN:   | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+; RUN: llvm-mc -triple m68k -show-encoding --position-independent %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; RELOC: R_68K_PC8 dst1 0x1
+; INSTR: move.l  (dst1,%pc,%a0), %a0
+; FIXUP: fixup A - offset: 3, value: dst1+1, kind: FK_PCRel_1
+move.l	(dst1,%pc,%a0), %a0
+
+; RELOC: R_68K_PC16 dst2 0x0
+; INSTR: move.l  (dst2,%pc), %a0
+; FIXUP: fixup A - offset: 2, value: dst2, kind: FK_PCRel_2
+move.l	(dst2,%pc), %a0
+
+; Shouldn't have any relocation
+; RELOC-NOT: R_68K_PC
+; INSTR: move.l  (0,%pc), %a0
+; FIXUP-NOT: fixup
+move.l	(0,%pc), %a0
diff --git a/llvm/test/MC/M68k/Relocations/PIC/text-plt.s b/llvm/test/MC/M68k/Relocations/PIC/text-plt.s
new file mode 100644
index 00000000000000..0ccd1758004a97
--- /dev/null
+++ b/llvm/test/MC/M68k/Relocations/PIC/text-plt.s
@@ -0,0 +1,14 @@
+; RUN: llvm-mc -triple m68k --mcpu=M68020 --position-independent -filetype=obj %s -o - \
+; RUN:   | llvm-readobj -r - | FileCheck -check-prefix=RELOC %s
+; RUN: llvm-mc -triple m68k --mcpu=M68020 --position-independent -show-encoding %s -o - \
+; RUN:   | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+
+; RELOC: R_68K_PLT16 target 0x0
+; INSTR: jsr     (target at PLT,%pc)
+; FIXUP: fixup A - offset: 2, value: target at PLT, kind: FK_PCRel_2
+jsr	(target at PLT,%pc)
+
+; RELOC: R_68K_PLT32  __tls_get_addr 0x0
+; INSTR: bsr.l   __tls_get_addr at PLT
+; FIXUP: fixup A - offset: 2, value: __tls_get_addr at PLT, kind: FK_PCRel_4
+bsr.l __tls_get_addr at PLT
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



More information about the llvm-commits mailing list