@@ -39,9 +39,14 @@ using namespace llvm;
3939namespace {
4040
4141class M68kAsmBackend : public MCAsmBackend {
42+ bool Allows32BitBranch;
4243
4344public:
44- M68kAsmBackend (const Target &T) : MCAsmBackend(llvm::endianness::big) {}
45+ M68kAsmBackend (const Target &T, const MCSubtargetInfo &STI)
46+ : MCAsmBackend(llvm::endianness::big),
47+ Allows32BitBranch (llvm::StringSwitch<bool >(STI.getCPU())
48+ .CasesLower(" m68020" , " m68030" , " m68040" , true )
49+ .Default(false )) {}
4550
4651 unsigned getNumFixupKinds () const override { return 0 ; }
4752
@@ -129,6 +134,36 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst) {
129134 return M68k::Ble16;
130135 case M68k::Bvs8:
131136 return M68k::Bvs16;
137+ case M68k::BRA16:
138+ return M68k::BRA32;
139+ case M68k::Bcc16:
140+ return M68k::Bcc32;
141+ case M68k::Bls16:
142+ return M68k::Bls32;
143+ case M68k::Blt16:
144+ return M68k::Blt32;
145+ case M68k::Beq16:
146+ return M68k::Beq32;
147+ case M68k::Bmi16:
148+ return M68k::Bmi32;
149+ case M68k::Bne16:
150+ return M68k::Bne32;
151+ case M68k::Bge16:
152+ return M68k::Bge32;
153+ case M68k::Bcs16:
154+ return M68k::Bcs32;
155+ case M68k::Bpl16:
156+ return M68k::Bpl32;
157+ case M68k::Bgt16:
158+ return M68k::Bgt32;
159+ case M68k::Bhi16:
160+ return M68k::Bhi32;
161+ case M68k::Bvc16:
162+ return M68k::Bvc32;
163+ case M68k::Ble16:
164+ return M68k::Ble32;
165+ case M68k::Bvs16:
166+ return M68k::Bvs32;
132167 }
133168}
134169
@@ -168,7 +203,7 @@ bool M68kAsmBackend::mayNeedRelaxation(const MCInst &Inst,
168203bool M68kAsmBackend::fixupNeedsRelaxation (const MCFixup &Fixup,
169204 uint64_t Value) const {
170205 // TODO Newer CPU can use 32 bit offsets, so check for this when ready
171- if (!isInt<16 >(Value)) {
206+ if (!isInt<32 >(Value) || (!Allows32BitBranch && !isInt< 16 >(Value) )) {
172207 llvm_unreachable (" Cannot relax the instruction, value does not fit" );
173208 }
174209 // Relax if the value is too big for a (signed) i8. This means that byte-wide
@@ -178,7 +213,13 @@ bool M68kAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
178213 // A branch to the immediately following instruction automatically
179214 // uses the 16-bit displacement format because the 8-bit
180215 // displacement field contains $00 (zero offset).
181- return Value == 0 || !isInt<8 >(Value);
216+ unsigned int KindLog2Size = getFixupKindLog2Size (Fixup.getKind ());
217+ bool FixupFieldTooSmall = false ;
218+ if (!isInt<8 >(Value) && KindLog2Size == 0 )
219+ FixupFieldTooSmall |= true ;
220+ if (!isInt<16 >(Value) && KindLog2Size <= 1 )
221+ FixupFieldTooSmall |= true ;
222+ return Value == 0 || FixupFieldTooSmall;
182223}
183224
184225// NOTE Can tblgen help at all here to verify there aren't other instructions
@@ -218,8 +259,8 @@ namespace {
218259class M68kELFAsmBackend : public M68kAsmBackend {
219260public:
220261 uint8_t OSABI;
221- M68kELFAsmBackend (const Target &T, uint8_t OSABI)
222- : M68kAsmBackend(T), OSABI(OSABI) {}
262+ M68kELFAsmBackend (const Target &T, const MCSubtargetInfo &STI, uint8_t OSABI)
263+ : M68kAsmBackend(T, STI ), OSABI(OSABI) {}
223264
224265 std::unique_ptr<MCObjectTargetWriter>
225266 createObjectTargetWriter () const override {
@@ -235,5 +276,5 @@ MCAsmBackend *llvm::createM68kAsmBackend(const Target &T,
235276 const MCTargetOptions &Options) {
236277 const Triple &TheTriple = STI.getTargetTriple ();
237278 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI (TheTriple.getOS ());
238- return new M68kELFAsmBackend (T, OSABI);
279+ return new M68kELFAsmBackend (T, STI, OSABI);
239280}
0 commit comments