From 633ce3426c9c21afcf61ee7bf55c0c2f3f79b461 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 6 Dec 2011 00:47:03 +0000 Subject: [PATCH] Move target-specific logic out of generic MCAssembler. Whether a fixup needs relaxation for the associated instruction is a target-specific function, as the FIXME indicated. Create a hook for that and use it. llvm-svn: 145881 --- include/llvm/MC/MCAsmBackend.h | 9 +++++++++ include/llvm/MC/MCAssembler.h | 2 +- lib/MC/MCAssembler.cpp | 7 ++----- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 16 ++++++++++++++++ .../MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp | 17 +++++++++++++++++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 10 ++++++++++ .../PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 9 +++++++++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 13 +++++++++++++ 8 files changed, 77 insertions(+), 6 deletions(-) diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 4a0cf37a6eb..b841ddb9f5a 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -16,9 +16,11 @@ #include "llvm/Support/DataTypes.h" namespace llvm { +class MCAsmLayout; class MCELFObjectTargetWriter; class MCFixup; class MCInst; +class MCInstFragment; class MCObjectWriter; class MCSection; template @@ -104,6 +106,13 @@ public: /// \param Inst - The instruction to test. virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0; + /// fixupNeedsRelaxation - Target specific predicate for whether a given + /// fixup requires the associated instruction to be relaxed. + virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const = 0; + /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. /// diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 7d840923c8d..687dd0c1407 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -717,7 +717,7 @@ private: /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, + bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 2de6d04f8ba..c5bf6b9f875 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -646,7 +646,7 @@ void MCAssembler::Finish() { } bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, - const MCFragment *DF, + const MCInstFragment *DF, const MCAsmLayout &Layout) const { if (getRelaxAll()) return true; @@ -657,10 +657,7 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, if (!evaluateFixup(Layout, Fixup, DF, Target, Value)) return true; - // Otherwise, relax if the value is too big for a (signed) i8. - // - // FIXME: This is target dependent! - return int64_t(Value) != int64_t(int8_t(Value)); + return getBackend().fixupNeedsRelaxation(Fixup, Value, DF, Layout); } bool MCAssembler::fragmentNeedsRelaxation(const MCInstFragment *IF, diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 0eed821b767..59fae27a081 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; @@ -137,6 +142,17 @@ bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const { return false; } +bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // FIXME: This isn't correct for ARM. Just moving the "generic" logic + // into the targets for now. + // + // Relax if the value is too big for a (signed) i8. + return int64_t(Value) != int64_t(int8_t(Value)); +} + void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); diff --git a/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp b/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp index 08f7d46a58f..d5acbe97493 100644 --- a/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp +++ b/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp @@ -58,6 +58,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; @@ -87,6 +92,18 @@ bool MBlazeAsmBackend::MayNeedRelaxation(const MCInst &Inst) const { return hasExprOrImm; } +bool MBlazeAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // FIXME: Is this right? It's what the "generic" code was doing before, + // but is X86 specific. Is it actually true for MBlaze also, or was it + // just close enough to not be a big deal? + // + // Relax if the value is too big for a (signed) i8. + return int64_t(Value) != int64_t(int8_t(Value)); +} + void MBlazeAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { Res = Inst; Res.setOpcode(getRelaxedOpcode(Inst.getOpcode())); diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 7bc5fe4a6e4..20e16368f87 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -173,6 +173,16 @@ public: return false; } + /// fixupNeedsRelaxation - Target specific predicate for whether a given + /// fixup requires the associated instruction to be relaxed. + bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // FIXME. + assert(0 && "RelaxInstruction() unimplemented"); + } + /// RelaxInstruction - Relax the instruction in the given fragment /// to the next wider instruction. /// diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 9f2fd6d01b8..12e0b3d436d 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -93,6 +93,15 @@ public: // FIXME. return false; } + + bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // FIXME. + assert(0 && "RelaxInstruction() unimplemented"); + } + void RelaxInstruction(const MCInst &Inst, MCInst &Res) const { // FIXME. diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 69ad7d7b6b3..87b2b055ab2 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -107,6 +107,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; @@ -244,6 +249,14 @@ bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst) const { return hasExp && !hasRIP; } +bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const { + // Relax if the value is too big for a (signed) i8. + return int64_t(Value) != int64_t(int8_t(Value)); +} + // FIXME: Can tblgen help at all here to verify there aren't other instructions // we can relax? void X86AsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {