Delete MCSubtargetInfo data members from target MCCodeEmitter classes

The subtarget info is explicitly passed to the EncodeInstruction
method and we should use that subtarget info to influence any
encoding decisions.

llvm-svn: 200350
This commit is contained in:
David Woodhouse 2014-01-28 23:13:25 +00:00
parent 3fa98a65e9
commit d2cca113df
6 changed files with 99 additions and 107 deletions

View File

@ -39,25 +39,22 @@ class ARMMCCodeEmitter : public MCCodeEmitter {
ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION;
void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCInstrInfo &MCII; const MCInstrInfo &MCII;
const MCSubtargetInfo &STI;
const MCContext &CTX; const MCContext &CTX;
public: public:
ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
MCContext &ctx) : MCII(mcii), CTX(ctx) {
: MCII(mcii), STI(sti), CTX(ctx) {
} }
~ARMMCCodeEmitter() {} ~ARMMCCodeEmitter() {}
bool isThumb() const { bool isThumb(const MCSubtargetInfo &STI) const {
// FIXME: Can tablegen auto-generate this?
return (STI.getFeatureBits() & ARM::ModeThumb) != 0; return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
} }
bool isThumb2() const { bool isThumb2(const MCSubtargetInfo &STI) const {
return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0; return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
} }
bool isTargetMachO() const { bool isTargetMachO(const MCSubtargetInfo &STI) const {
Triple TT(STI.getTargetTriple()); Triple TT(STI.getTargetTriple());
return TT.isOSBinFormatMachO(); return TT.isOSBinFormatMachO();
} }
@ -404,7 +401,7 @@ MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI, const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) { MCContext &Ctx) {
return new ARMMCCodeEmitter(MCII, STI, Ctx); return new ARMMCCodeEmitter(MCII, Ctx);
} }
/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
@ -413,7 +410,7 @@ MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
unsigned EncodedValue, unsigned EncodedValue,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
if (isThumb2()) { if (isThumb2(STI)) {
// NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
// to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
// set to 1111. // set to 1111.
@ -433,7 +430,7 @@ unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
unsigned EncodedValue, unsigned EncodedValue,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
if (isThumb2()) { if (isThumb2(STI)) {
EncodedValue &= 0xF0FFFFFF; EncodedValue &= 0xF0FFFFFF;
EncodedValue |= 0x09000000; EncodedValue |= 0x09000000;
} }
@ -447,7 +444,7 @@ unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
unsigned EncodedValue, unsigned EncodedValue,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
if (isThumb2()) { if (isThumb2(STI)) {
EncodedValue &= 0x00FFFFFF; EncodedValue &= 0x00FFFFFF;
EncodedValue |= 0xEE000000; EncodedValue |= 0xEE000000;
} }
@ -460,7 +457,7 @@ unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
unsigned EncodedValue, unsigned EncodedValue,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
if (isThumb2()) { if (isThumb2(STI)) {
EncodedValue |= 0xC000000; // Set bits 27-26 EncodedValue |= 0xC000000; // Set bits 27-26
} }
@ -472,7 +469,7 @@ unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
unsigned ARMMCCodeEmitter:: unsigned ARMMCCodeEmitter::
VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
if (isThumb2()) { if (isThumb2(STI)) {
EncodedValue &= 0x0FFFFFFF; EncodedValue &= 0x0FFFFFFF;
EncodedValue |= 0xE0000000; EncodedValue |= 0xE0000000;
} }
@ -661,7 +658,7 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
const MCSubtargetInfo &STI) const { const MCSubtargetInfo &STI) const {
// FIXME: This really, really shouldn't use TargetMachine. We don't want // FIXME: This really, really shouldn't use TargetMachine. We don't want
// coupling between MC and TM anywhere we can help it. // coupling between MC and TM anywhere we can help it.
if (isThumb2()) if (isThumb2(STI))
return return
::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI); ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI);
return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI);
@ -852,7 +849,7 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
isAdd = false ; // 'U' bit is set as part of the fixup. isAdd = false ; // 'U' bit is set as part of the fixup.
MCFixupKind Kind; MCFixupKind Kind;
if (isThumb2()) if (isThumb2(STI))
Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
else else
Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
@ -1018,22 +1015,22 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
switch (ARM16Expr->getKind()) { switch (ARM16Expr->getKind()) {
default: llvm_unreachable("Unsupported ARMFixup"); default: llvm_unreachable("Unsupported ARMFixup");
case ARMMCExpr::VK_ARM_HI16: case ARMMCExpr::VK_ARM_HI16:
if (!isTargetMachO() && EvaluateAsPCRel(E)) if (!isTargetMachO(STI) && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movt_hi16_pcrel ? ARM::fixup_t2_movt_hi16_pcrel
: ARM::fixup_arm_movt_hi16_pcrel); : ARM::fixup_arm_movt_hi16_pcrel);
else else
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movt_hi16 ? ARM::fixup_t2_movt_hi16
: ARM::fixup_arm_movt_hi16); : ARM::fixup_arm_movt_hi16);
break; break;
case ARMMCExpr::VK_ARM_LO16: case ARMMCExpr::VK_ARM_LO16:
if (!isTargetMachO() && EvaluateAsPCRel(E)) if (!isTargetMachO(STI) && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movw_lo16_pcrel ? ARM::fixup_t2_movw_lo16_pcrel
: ARM::fixup_arm_movw_lo16_pcrel); : ARM::fixup_arm_movw_lo16_pcrel);
else else
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movw_lo16 ? ARM::fixup_t2_movw_lo16
: ARM::fixup_arm_movw_lo16); : ARM::fixup_arm_movw_lo16);
break; break;
@ -1045,12 +1042,12 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
// it's just a plain immediate expression, and those evaluate to // it's just a plain immediate expression, and those evaluate to
// the lower 16 bits of the expression regardless of whether // the lower 16 bits of the expression regardless of whether
// we have a movt or a movw. // we have a movt or a movw.
if (!isTargetMachO() && EvaluateAsPCRel(E)) if (!isTargetMachO(STI) && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movw_lo16_pcrel ? ARM::fixup_t2_movw_lo16_pcrel
: ARM::fixup_arm_movw_lo16_pcrel); : ARM::fixup_arm_movw_lo16_pcrel);
else else
Kind = MCFixupKind(isThumb2() Kind = MCFixupKind(isThumb2(STI)
? ARM::fixup_t2_movw_lo16 ? ARM::fixup_t2_movw_lo16
: ARM::fixup_arm_movw_lo16); : ARM::fixup_arm_movw_lo16);
Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
@ -1259,7 +1256,7 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
assert(MO.isExpr() && "Unexpected machine operand type!"); assert(MO.isExpr() && "Unexpected machine operand type!");
const MCExpr *Expr = MO.getExpr(); const MCExpr *Expr = MO.getExpr();
MCFixupKind Kind; MCFixupKind Kind;
if (isThumb2()) if (isThumb2(STI))
Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
else else
Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
@ -1671,7 +1668,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
// Thumb 32-bit wide instructions need to emit the high order halfword // Thumb 32-bit wide instructions need to emit the high order halfword
// first. // first.
if (isThumb() && Size == 4) { if (isThumb(STI) && Size == 4) {
EmitConstant(Binary >> 16, 2, OS); EmitConstant(Binary >> 16, 2, OS);
EmitConstant(Binary & 0xffff, 2, OS); EmitConstant(Binary & 0xffff, 2, OS);
} else } else

View File

@ -37,16 +37,15 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCInstrInfo &MCII; const MCInstrInfo &MCII;
MCContext &Ctx; MCContext &Ctx;
const MCSubtargetInfo &STI;
bool IsLittleEndian; bool IsLittleEndian;
bool IsMicroMips;
bool isMicroMips(const MCSubtargetInfo &STI) const {
return STI.getFeatureBits() & Mips::FeatureMicroMips;
}
public: public:
MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, bool IsLittle) :
const MCSubtargetInfo &sti, bool IsLittle) : MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) { }
MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {
IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
}
~MipsMCCodeEmitter() {} ~MipsMCCodeEmitter() {}
@ -54,14 +53,15 @@ public:
OS << (char)C; OS << (char)C;
} }
void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const { void EmitInstruction(uint64_t Val, unsigned Size, const MCSubtargetInfo &STI,
raw_ostream &OS) const {
// Output the instruction encoding in little endian byte order. // Output the instruction encoding in little endian byte order.
// Little-endian byte ordering: // Little-endian byte ordering:
// mips32r2: 4 | 3 | 2 | 1 // mips32r2: 4 | 3 | 2 | 1
// microMIPS: 2 | 1 | 4 | 3 // microMIPS: 2 | 1 | 4 | 3
if (IsLittleEndian && Size == 4 && IsMicroMips) { if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
EmitInstruction(Val>>16, 2, OS); EmitInstruction(Val>>16, 2, STI, OS);
EmitInstruction(Val, 2, OS); EmitInstruction(Val, 2, STI, OS);
} else { } else {
for (unsigned i = 0; i < Size; ++i) { for (unsigned i = 0; i < Size; ++i) {
unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
@ -148,7 +148,7 @@ MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) MCContext &Ctx)
{ {
return new MipsMCCodeEmitter(MCII, Ctx, STI, false); return new MipsMCCodeEmitter(MCII, Ctx, false);
} }
MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
@ -156,7 +156,7 @@ MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) MCContext &Ctx)
{ {
return new MipsMCCodeEmitter(MCII, Ctx, STI, true); return new MipsMCCodeEmitter(MCII, Ctx, true);
} }
@ -280,7 +280,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
if (!Size) if (!Size)
llvm_unreachable("Desc.getSize() returns 0"); llvm_unreachable("Desc.getSize() returns 0");
EmitInstruction(Binary, Size, OS); EmitInstruction(Binary, Size, STI, OS);
} }
/// getBranchTargetOpValue - Return binary encoding of the branch /// getBranchTargetOpValue - Return binary encoding of the branch
@ -398,65 +398,65 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
FixupKind = Mips::fixup_Mips_GPOFF_LO; FixupKind = Mips::fixup_Mips_GPOFF_LO;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT_PAGE : case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_PAGE FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
: Mips::fixup_Mips_GOT_PAGE; : Mips::fixup_Mips_GOT_PAGE;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT_OFST : case MCSymbolRefExpr::VK_Mips_GOT_OFST :
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_OFST FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
: Mips::fixup_Mips_GOT_OFST; : Mips::fixup_Mips_GOT_OFST;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT_DISP : case MCSymbolRefExpr::VK_Mips_GOT_DISP :
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_DISP FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
: Mips::fixup_Mips_GOT_DISP; : Mips::fixup_Mips_GOT_DISP;
break; break;
case MCSymbolRefExpr::VK_Mips_GPREL: case MCSymbolRefExpr::VK_Mips_GPREL:
FixupKind = Mips::fixup_Mips_GPREL16; FixupKind = Mips::fixup_Mips_GPREL16;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT_CALL: case MCSymbolRefExpr::VK_Mips_GOT_CALL:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_CALL16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
: Mips::fixup_Mips_CALL16; : Mips::fixup_Mips_CALL16;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT16: case MCSymbolRefExpr::VK_Mips_GOT16:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
: Mips::fixup_Mips_GOT_Global; : Mips::fixup_Mips_GOT_Global;
break; break;
case MCSymbolRefExpr::VK_Mips_GOT: case MCSymbolRefExpr::VK_Mips_GOT:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
: Mips::fixup_Mips_GOT_Local; : Mips::fixup_Mips_GOT_Local;
break; break;
case MCSymbolRefExpr::VK_Mips_ABS_HI: case MCSymbolRefExpr::VK_Mips_ABS_HI:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_HI16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
: Mips::fixup_Mips_HI16; : Mips::fixup_Mips_HI16;
break; break;
case MCSymbolRefExpr::VK_Mips_ABS_LO: case MCSymbolRefExpr::VK_Mips_ABS_LO:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_LO16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
: Mips::fixup_Mips_LO16; : Mips::fixup_Mips_LO16;
break; break;
case MCSymbolRefExpr::VK_Mips_TLSGD: case MCSymbolRefExpr::VK_Mips_TLSGD:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_GD FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
: Mips::fixup_Mips_TLSGD; : Mips::fixup_Mips_TLSGD;
break; break;
case MCSymbolRefExpr::VK_Mips_TLSLDM: case MCSymbolRefExpr::VK_Mips_TLSLDM:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_LDM FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
: Mips::fixup_Mips_TLSLDM; : Mips::fixup_Mips_TLSLDM;
break; break;
case MCSymbolRefExpr::VK_Mips_DTPREL_HI: case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
: Mips::fixup_Mips_DTPREL_HI; : Mips::fixup_Mips_DTPREL_HI;
break; break;
case MCSymbolRefExpr::VK_Mips_DTPREL_LO: case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
: Mips::fixup_Mips_DTPREL_LO; : Mips::fixup_Mips_DTPREL_LO;
break; break;
case MCSymbolRefExpr::VK_Mips_GOTTPREL: case MCSymbolRefExpr::VK_Mips_GOTTPREL:
FixupKind = Mips::fixup_Mips_GOTTPREL; FixupKind = Mips::fixup_Mips_GOTTPREL;
break; break;
case MCSymbolRefExpr::VK_Mips_TPREL_HI: case MCSymbolRefExpr::VK_Mips_TPREL_HI:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
: Mips::fixup_Mips_TPREL_HI; : Mips::fixup_Mips_TPREL_HI;
break; break;
case MCSymbolRefExpr::VK_Mips_TPREL_LO: case MCSymbolRefExpr::VK_Mips_TPREL_LO:
FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
: Mips::fixup_Mips_TPREL_LO; : Mips::fixup_Mips_TPREL_LO;
break; break;
case MCSymbolRefExpr::VK_Mips_HIGHER: case MCSymbolRefExpr::VK_Mips_HIGHER:

View File

@ -33,14 +33,10 @@ class PPCMCCodeEmitter : public MCCodeEmitter {
PPCMCCodeEmitter(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION; PPCMCCodeEmitter(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCSubtargetInfo &STI;
const MCContext &CTX; const MCContext &CTX;
Triple TT;
public: public:
PPCMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) : CTX(ctx) {
MCContext &ctx)
: STI(sti), CTX(ctx), TT(STI.getTargetTriple()) {
} }
~PPCMCCodeEmitter() {} ~PPCMCCodeEmitter() {}
@ -123,7 +119,7 @@ MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI, const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) { MCContext &Ctx) {
return new PPCMCCodeEmitter(MCII, STI, Ctx); return new PPCMCCodeEmitter(MCII, Ctx);
} }
unsigned PPCMCCodeEmitter:: unsigned PPCMCCodeEmitter::
@ -238,6 +234,7 @@ unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
// Return the thread-pointer register's encoding. // Return the thread-pointer register's encoding.
Fixups.push_back(MCFixup::Create(0, MO.getExpr(), Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
(MCFixupKind)PPC::fixup_ppc_nofixup)); (MCFixupKind)PPC::fixup_ppc_nofixup));
Triple TT(STI.getTargetTriple());
bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le; bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le;
return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2);
} }

View File

@ -34,13 +34,11 @@ class R600MCCodeEmitter : public AMDGPUMCCodeEmitter {
void operator=(const R600MCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const R600MCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCInstrInfo &MCII; const MCInstrInfo &MCII;
const MCRegisterInfo &MRI; const MCRegisterInfo &MRI;
const MCSubtargetInfo &STI;
public: public:
R600MCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, R600MCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri)
const MCSubtargetInfo &sti) : MCII(mcii), MRI(mri) { }
: MCII(mcii), MRI(mri), STI(sti) { }
/// \brief Encode the instruction and write it to the OS. /// \brief Encode the instruction and write it to the OS.
virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS, virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
@ -85,7 +83,7 @@ enum FCInstr {
MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII, MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI, const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI) { const MCSubtargetInfo &STI) {
return new R600MCCodeEmitter(MCII, MRI, STI); return new R600MCCodeEmitter(MCII, MRI);
} }
void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,

View File

@ -48,7 +48,7 @@ class SIMCCodeEmitter : public AMDGPUMCCodeEmitter {
public: public:
SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri,
const MCSubtargetInfo &sti, MCContext &ctx) MCContext &ctx)
: MCII(mcii), MRI(mri) { } : MCII(mcii), MRI(mri) { }
~SIMCCodeEmitter() { } ~SIMCCodeEmitter() { }
@ -70,7 +70,7 @@ MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI, const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) { MCContext &Ctx) {
return new SIMCCodeEmitter(MCII, MRI, STI, Ctx); return new SIMCCodeEmitter(MCII, MRI, Ctx);
} }
bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc, bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,

View File

@ -32,39 +32,35 @@ class X86MCCodeEmitter : public MCCodeEmitter {
X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION;
void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCInstrInfo &MCII; const MCInstrInfo &MCII;
const MCSubtargetInfo &STI;
MCContext &Ctx; MCContext &Ctx;
public: public:
X86MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
MCContext &ctx) : MCII(mcii), Ctx(ctx) {
: MCII(mcii), STI(sti), Ctx(ctx) {
} }
~X86MCCodeEmitter() {} ~X86MCCodeEmitter() {}
bool is64BitMode() const { bool is64BitMode(const MCSubtargetInfo &STI) const {
// FIXME: Can tablegen auto-generate this?
return (STI.getFeatureBits() & X86::Mode64Bit) != 0; return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
} }
bool is32BitMode() const { bool is32BitMode(const MCSubtargetInfo &STI) const {
// FIXME: Can tablegen auto-generate this?
return (STI.getFeatureBits() & X86::Mode32Bit) != 0; return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
} }
bool is16BitMode() const { bool is16BitMode(const MCSubtargetInfo &STI) const {
// FIXME: Can tablegen auto-generate this?
return (STI.getFeatureBits() & X86::Mode16Bit) != 0; return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
} }
/// Is16BitMemOperand - Return true if the specified instruction has /// Is16BitMemOperand - Return true if the specified instruction has
/// a 16-bit memory operand. Op specifies the operand # of the memoperand. /// a 16-bit memory operand. Op specifies the operand # of the memoperand.
bool Is16BitMemOperand(const MCInst &MI, unsigned Op) const { bool Is16BitMemOperand(const MCInst &MI, unsigned Op,
const MCSubtargetInfo &STI) const {
const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg);
const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
if (is16BitMode() && BaseReg.getReg() == 0 && if (is16BitMode(STI) && BaseReg.getReg() == 0 &&
Disp.isImm() && Disp.getImm() < 0x10000) Disp.isImm() && Disp.getImm() < 0x10000)
return true; return true;
if ((BaseReg.getReg() != 0 && if ((BaseReg.getReg() != 0 &&
@ -149,7 +145,8 @@ public:
void EmitMemModRMByte(const MCInst &MI, unsigned Op, void EmitMemModRMByte(const MCInst &MI, unsigned Op,
unsigned RegOpcodeField, unsigned RegOpcodeField,
uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const; SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void EncodeInstruction(const MCInst &MI, raw_ostream &OS, void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups, SmallVectorImpl<MCFixup> &Fixups,
@ -164,6 +161,7 @@ public:
void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
const MCInst &MI, const MCInstrDesc &Desc, const MCInst &MI, const MCInstrDesc &Desc,
const MCSubtargetInfo &STI,
raw_ostream &OS) const; raw_ostream &OS) const;
}; };
@ -174,7 +172,7 @@ MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI, const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
MCContext &Ctx) { MCContext &Ctx) {
return new X86MCCodeEmitter(MCII, STI, Ctx); return new X86MCCodeEmitter(MCII, Ctx);
} }
/// isDisp8 - Return true if this signed displacement fits in a 8-bit /// isDisp8 - Return true if this signed displacement fits in a 8-bit
@ -375,7 +373,8 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
unsigned RegOpcodeField, unsigned RegOpcodeField,
uint64_t TSFlags, unsigned &CurByte, uint64_t TSFlags, unsigned &CurByte,
raw_ostream &OS, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const{ SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const{
const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg); const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg);
const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt); const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt);
@ -385,7 +384,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
// Handle %rip relative addressing. // Handle %rip relative addressing.
if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
assert(is64BitMode() && "Rip-relative addressing requires 64-bit mode"); assert(is64BitMode(STI) && "Rip-relative addressing requires 64-bit mode");
assert(IndexReg.getReg() == 0 && "Invalid rip-relative address"); assert(IndexReg.getReg() == 0 && "Invalid rip-relative address");
EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
@ -413,7 +412,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
// 16-bit addressing forms of the ModR/M byte have a different encoding for // 16-bit addressing forms of the ModR/M byte have a different encoding for
// the R/M field and are far more limited in which registers can be used. // the R/M field and are far more limited in which registers can be used.
if (Is16BitMemOperand(MI, Op)) { if (Is16BitMemOperand(MI, Op, STI)) {
if (BaseReg) { if (BaseReg) {
// For 32-bit addressing, the row and column values in Table 2-2 are // For 32-bit addressing, the row and column values in Table 2-2 are
// basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with
@ -484,7 +483,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
BaseRegNo != N86::ESP && BaseRegNo != N86::ESP &&
// If there is no base register and we're in 64-bit mode, we need a SIB // If there is no base register and we're in 64-bit mode, we need a SIB
// byte to emit an addr that is just 'disp32' (the non-RIP relative form). // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
(!is64BitMode() || BaseReg != 0)) { (!is64BitMode(STI) || BaseReg != 0)) {
if (BaseReg == 0) { // [disp32] in X86-32 mode if (BaseReg == 0) { // [disp32] in X86-32 mode
EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
@ -1144,6 +1143,7 @@ void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte,
void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
int MemOperand, const MCInst &MI, int MemOperand, const MCInst &MI,
const MCInstrDesc &Desc, const MCInstrDesc &Desc,
const MCSubtargetInfo &STI,
raw_ostream &OS) const { raw_ostream &OS) const {
// Emit the lock opcode prefix as needed. // Emit the lock opcode prefix as needed.
@ -1162,8 +1162,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
bool need_address_override; bool need_address_override;
// The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
// should introduce an AdSize16 bit instead of having seven special cases? // should introduce an AdSize16 bit instead of having seven special cases?
if ((!is16BitMode() && TSFlags & X86II::AdSize) || if ((!is16BitMode(STI) && TSFlags & X86II::AdSize) ||
(is16BitMode() && (MI.getOpcode() == X86::JECXZ_32 || (is16BitMode(STI) && (MI.getOpcode() == X86::JECXZ_32 ||
MI.getOpcode() == X86::MOV8o8a || MI.getOpcode() == X86::MOV8o8a ||
MI.getOpcode() == X86::MOV16o16a || MI.getOpcode() == X86::MOV16o16a ||
MI.getOpcode() == X86::MOV32o32a || MI.getOpcode() == X86::MOV32o32a ||
@ -1173,23 +1173,23 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
need_address_override = true; need_address_override = true;
} else if (MemOperand == -1) { } else if (MemOperand == -1) {
need_address_override = false; need_address_override = false;
} else if (is64BitMode()) { } else if (is64BitMode(STI)) {
assert(!Is16BitMemOperand(MI, MemOperand)); assert(!Is16BitMemOperand(MI, MemOperand, STI));
need_address_override = Is32BitMemOperand(MI, MemOperand); need_address_override = Is32BitMemOperand(MI, MemOperand);
} else if (is32BitMode()) { } else if (is32BitMode(STI)) {
assert(!Is64BitMemOperand(MI, MemOperand)); assert(!Is64BitMemOperand(MI, MemOperand));
need_address_override = Is16BitMemOperand(MI, MemOperand); need_address_override = Is16BitMemOperand(MI, MemOperand, STI);
} else { } else {
assert(is16BitMode()); assert(is16BitMode(STI));
assert(!Is64BitMemOperand(MI, MemOperand)); assert(!Is64BitMemOperand(MI, MemOperand));
need_address_override = !Is16BitMemOperand(MI, MemOperand); need_address_override = !Is16BitMemOperand(MI, MemOperand, STI);
} }
if (need_address_override) if (need_address_override)
EmitByte(0x67, CurByte, OS); EmitByte(0x67, CurByte, OS);
// Emit the operand size opcode prefix as needed. // Emit the operand size opcode prefix as needed.
if (TSFlags & (is16BitMode() ? X86II::OpSize16 : X86II::OpSize)) if (TSFlags & (is16BitMode(STI) ? X86II::OpSize16 : X86II::OpSize))
EmitByte(0x66, CurByte, OS); EmitByte(0x66, CurByte, OS);
bool Need0FPrefix = false; bool Need0FPrefix = false;
@ -1236,7 +1236,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// Handle REX prefix. // Handle REX prefix.
// FIXME: Can this come before F2 etc to simplify emission? // FIXME: Can this come before F2 etc to simplify emission?
if (is64BitMode()) { if (is64BitMode(STI)) {
if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc))
EmitByte(0x40 | REX, CurByte, OS); EmitByte(0x40 | REX, CurByte, OS);
} }
@ -1304,7 +1304,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
if (MemoryOperand != -1) MemoryOperand += CurOp; if (MemoryOperand != -1) MemoryOperand += CurOp;
if (!HasVEXPrefix) if (!HasVEXPrefix)
EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
else else
EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
@ -1329,8 +1329,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
if (MI.getOperand(2).getReg() != X86::DS) if (MI.getOperand(2).getReg() != X86::DS)
EmitSegmentOverridePrefix(CurByte, 2, MI, OS); EmitSegmentOverridePrefix(CurByte, 2, MI, OS);
// Emit OpSize prefix as needed. // Emit OpSize prefix as needed.
if ((!is32BitMode() && siReg == X86::ESI) || if ((!is32BitMode(STI) && siReg == X86::ESI) ||
(is32BitMode() && siReg == X86::SI)) (is32BitMode(STI) && siReg == X86::SI))
EmitByte(0x67, CurByte, OS); EmitByte(0x67, CurByte, OS);
CurOp += 3; // Consume operands. CurOp += 3; // Consume operands.
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
@ -1342,8 +1342,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
if (MI.getOperand(1).getReg() != X86::DS) if (MI.getOperand(1).getReg() != X86::DS)
EmitSegmentOverridePrefix(CurByte, 1, MI, OS); EmitSegmentOverridePrefix(CurByte, 1, MI, OS);
// Emit OpSize prefix as needed. // Emit OpSize prefix as needed.
if ((!is32BitMode() && siReg == X86::ESI) || if ((!is32BitMode(STI) && siReg == X86::ESI) ||
(is32BitMode() && siReg == X86::SI)) (is32BitMode(STI) && siReg == X86::SI))
EmitByte(0x67, CurByte, OS); EmitByte(0x67, CurByte, OS);
CurOp += 2; // Consume operands. CurOp += 2; // Consume operands.
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
@ -1352,8 +1352,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
case X86II::RawFrmDst: { case X86II::RawFrmDst: {
unsigned siReg = MI.getOperand(0).getReg(); unsigned siReg = MI.getOperand(0).getReg();
// Emit OpSize prefix as needed. // Emit OpSize prefix as needed.
if ((!is32BitMode() && siReg == X86::EDI) || if ((!is32BitMode(STI) && siReg == X86::EDI) ||
(is32BitMode() && siReg == X86::DI)) (is32BitMode(STI) && siReg == X86::DI))
EmitByte(0x67, CurByte, OS); EmitByte(0x67, CurByte, OS);
++CurOp; // Consume operand. ++CurOp; // Consume operand.
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
@ -1419,7 +1419,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitMemModRMByte(MI, CurOp, EmitMemModRMByte(MI, CurOp,
GetX86RegNum(MI.getOperand(SrcRegNum)), GetX86RegNum(MI.getOperand(SrcRegNum)),
TSFlags, CurByte, OS, Fixups); TSFlags, CurByte, OS, Fixups, STI);
CurOp = SrcRegNum + 1; CurOp = SrcRegNum + 1;
break; break;
@ -1467,7 +1467,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
TSFlags, CurByte, OS, Fixups); TSFlags, CurByte, OS, Fixups, STI);
CurOp += AddrOperands + 1; CurOp += AddrOperands + 1;
if (HasVEX_4VOp3) if (HasVEX_4VOp3)
++CurOp; ++CurOp;
@ -1493,7 +1493,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
++CurOp; ++CurOp;
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m,
TSFlags, CurByte, OS, Fixups); TSFlags, CurByte, OS, Fixups, STI);
CurOp += X86::AddrNumOperands; CurOp += X86::AddrNumOperands;
break; break;
case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: