diff options
Diffstat (limited to 'lib/Target/ARM/MCTargetDesc')
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 46 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp | 9 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/CMakeLists.txt | 7 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/LLVMBuild.txt | 1 |
5 files changed, 52 insertions, 13 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 62d04c4..bf1f0e8 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -102,6 +102,11 @@ public: bool MayNeedRelaxation(const MCInst &Inst) const; + bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const; + void RelaxInstruction(const MCInst &Inst, MCInst &Res) const; bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const; @@ -124,14 +129,49 @@ public: }; } // end anonymous namespace +static unsigned getRelaxedOpcode(unsigned Op) { + switch (Op) { + default: return Op; + case ARM::tBcc: return ARM::t2Bcc; + } +} + bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const { - // FIXME: Thumb targets, different move constant targets.. + if (getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode()) + return true; return false; } +bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the + // low bit being an implied zero. There's an implied +4 offset for the + // branch, so we adjust the other way here to determine what's + // encodable. + // + // Relax if the value is too big for a (signed) i8. + int64_t Offset = int64_t(Value) - 4; + return Offset > 254 || Offset < -256; +} + void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { - assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented"); - return; + unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); + + // Sanity check w/ diagnostic if we get here w/ a bogus instruction. + if (RelaxedOp == Inst.getOpcode()) { + SmallString<256> Tmp; + raw_svector_ostream OS(Tmp); + Inst.dump_pretty(OS); + OS << "\n"; + report_fatal_error("unexpected instruction to relax: " + OS.str()); + } + + // The instructions we're relaxing have (so far) the same operands. + // We just need to update to the proper opcode. + Res = Inst; + Res.setOpcode(RelaxedOp); } bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 865c3e2..c38a882 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -1412,7 +1412,7 @@ getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const { const MCOperand &MO = MI.getOperand(Op); if (MO.getReg() == 0) return 0x0D; - return MO.getReg(); + return getARMRegisterNumbering(MO.getReg()); } unsigned ARMMCCodeEmitter:: diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 352c73e..f394b4f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCMachOSymbolFlags.h" #include "llvm/MC/MCValue.h" #include "llvm/Object/MachOFormat.h" #include "llvm/Support/ErrorHandling.h" @@ -178,9 +179,16 @@ RecordARMMovwMovtRelocation(MachObjectWriter *Writer, case ARM::fixup_arm_movt_hi16: case ARM::fixup_arm_movt_hi16_pcrel: MovtBit = 1; + // The thumb bit shouldn't be set in the 'other-half' bit of the + // relocation, but it will be set in FixedValue if the base symbol + // is a thumb function. Clear it out here. + if (A_SD->getFlags() & SF_ThumbFunc) + FixedValue &= 0xfffffffe; break; case ARM::fixup_t2_movt_hi16: case ARM::fixup_t2_movt_hi16_pcrel: + if (A_SD->getFlags() & SF_ThumbFunc) + FixedValue &= 0xfffffffe; MovtBit = 1; // Fallthrough case ARM::fixup_t2_movw_lo16: @@ -189,7 +197,6 @@ RecordARMMovwMovtRelocation(MachObjectWriter *Writer, break; } - if (Type == macho::RIT_ARM_HalfDifference) { uint32_t OtherHalf = MovtBit ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16); diff --git a/lib/Target/ARM/MCTargetDesc/CMakeLists.txt b/lib/Target/ARM/MCTargetDesc/CMakeLists.txt index f529314..f2cf78a 100644 --- a/lib/Target/ARM/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/ARM/MCTargetDesc/CMakeLists.txt @@ -10,10 +10,3 @@ add_dependencies(LLVMARMDesc ARMCommonTableGen) # Hack: we need to include 'main' target directory to grab private headers include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..) - -add_llvm_library_dependencies(LLVMARMDesc - LLVMARMAsmPrinter - LLVMARMInfo - LLVMMC - LLVMSupport - ) diff --git a/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt b/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt index 46b11c7..2a7fe61 100644 --- a/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt +++ b/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt @@ -21,4 +21,3 @@ name = ARMDesc parent = ARM required_libraries = ARMAsmPrinter ARMInfo MC Support add_to_library_groups = ARM - |