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
This commit is contained in:
Jim Grosbach 2011-12-06 00:47:03 +00:00
parent d59dcc5ddb
commit 633ce3426c
8 changed files with 77 additions and 6 deletions

View File

@ -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<typename T>
@ -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.
///

View File

@ -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.

View File

@ -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,

View File

@ -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());

View File

@ -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()));

View File

@ -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.
///

View File

@ -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.

View File

@ -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 {