diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-05 22:10:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-05 22:10:22 +0000 |
commit | 39a612e6f9e63806af410a0ab0d81895391e4c79 (patch) | |
tree | 07bd8be3330e4a308ae90ec3c3692d130548af92 /lib/Target | |
parent | 58e9ee85fda5083e2eea987917e8eab6ba31fe5e (diff) | |
download | external_llvm-39a612e6f9e63806af410a0ab0d81895391e4c79.zip external_llvm-39a612e6f9e63806af410a0ab0d81895391e4c79.tar.gz external_llvm-39a612e6f9e63806af410a0ab0d81895391e4c79.tar.bz2 |
port X86InstrInfo::determineREX over to the new encoder.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95440 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.h | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86MCCodeEmitter.cpp | 100 |
3 files changed, 109 insertions, 10 deletions
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index f60432d..d420aa7 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -3015,11 +3015,10 @@ isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const { } -/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended register? -/// e.g. r8, xmm8, etc. -bool X86InstrInfo::isX86_64ExtendedReg(const MachineOperand &MO) { - if (!MO.isReg()) return false; - switch (MO.getReg()) { +/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher) +/// register? e.g. r8, xmm8, xmm13, etc. +bool X86InstrInfo::isX86_64ExtendedReg(unsigned RegNo) { + switch (RegNo) { default: break; case X86::R8: case X86::R9: case X86::R10: case X86::R11: case X86::R12: case X86::R13: case X86::R14: case X86::R15: diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 0ddb32d..a6b3863 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -18,7 +18,6 @@ #include "X86.h" #include "X86RegisterInfo.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/Target/TargetRegisterInfo.h" namespace llvm { class X86RegisterInfo; @@ -661,9 +660,16 @@ public: reg == X86::SIL || reg == X86::DIL); } - static bool isX86_64ExtendedReg(const MachineOperand &MO); + static bool isX86_64ExtendedReg(const MachineOperand &MO) { + if (!MO.isReg()) return false; + return isX86_64ExtendedReg(MO.getReg()); + } static unsigned determineREX(const MachineInstr &MI); + /// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or + /// higher) register? e.g. r8, xmm8, xmm13, etc. + static bool isX86_64ExtendedReg(unsigned RegNo); + /// GetInstSize - Returns the size of the specified MachineInstr. /// virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const; diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index 46d3889..ec0e444 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -266,6 +266,101 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, EmitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel, OS); } +/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 +/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand +/// size, and 3) use of X86-64 extended registers. +static unsigned DetermineREXPrefix(const MCInst &MI, unsigned TSFlags, + const TargetInstrDesc &Desc) { + unsigned REX = 0; + + // Pseudo instructions do not need REX prefix byte. + if ((TSFlags & X86II::FormMask) == X86II::Pseudo) + return 0; + if (TSFlags & X86II::REX_W) + REX |= 1 << 3; + + if (MI.getNumOperands() == 0) return REX; + + unsigned NumOps = MI.getNumOperands(); + // FIXME: MCInst should explicitize the two-addrness. + bool isTwoAddr = NumOps > 1 && + Desc.getOperandConstraint(1, TOI::TIED_TO) != -1; + + // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. + unsigned i = isTwoAddr ? 1 : 0; + for (; i != NumOps; ++i) { + const MCOperand &MO = MI.getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (!X86InstrInfo::isX86_64NonExtLowByteReg(Reg)) continue; + REX |= 0x40; + break; + } + + switch (TSFlags & X86II::FormMask) { + case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!"); + case X86II::MRMSrcReg: + if (MI.getOperand(0).isReg() && + X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + REX |= 1 << 2; + i = isTwoAddr ? 2 : 1; + for (; i != NumOps; ++i) { + const MCOperand &MO = MI.getOperand(i); + if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg())) + REX |= 1 << 0; + } + break; + case X86II::MRMSrcMem: { + if (MI.getOperand(0).isReg() && + X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + REX |= 1 << 2; + unsigned Bit = 0; + i = isTwoAddr ? 2 : 1; + for (; i != NumOps; ++i) { + const MCOperand &MO = MI.getOperand(i); + if (MO.isReg()) { + if (X86InstrInfo::isX86_64ExtendedReg(MO.getReg())) + REX |= 1 << Bit; + Bit++; + } + } + break; + } + case X86II::MRM0m: case X86II::MRM1m: + case X86II::MRM2m: case X86II::MRM3m: + case X86II::MRM4m: case X86II::MRM5m: + case X86II::MRM6m: case X86II::MRM7m: + case X86II::MRMDestMem: { + unsigned e = (isTwoAddr ? X86AddrNumOperands+1 : X86AddrNumOperands); + i = isTwoAddr ? 1 : 0; + if (NumOps > e && MI.getOperand(e).isReg() && + X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(e).getReg())) + REX |= 1 << 2; + unsigned Bit = 0; + for (; i != e; ++i) { + const MCOperand &MO = MI.getOperand(i); + if (MO.isReg()) { + if (X86InstrInfo::isX86_64ExtendedReg(MO.getReg())) + REX |= 1 << Bit; + Bit++; + } + } + break; + } + default: + if (MI.getOperand(0).isReg() && + X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + REX |= 1 << 0; + i = isTwoAddr ? 2 : 1; + for (unsigned e = NumOps; i != e; ++i) { + const MCOperand &MO = MI.getOperand(i); + if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg())) + REX |= 1 << 2; + } + break; + } + return REX; +} void X86MCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS) const { @@ -337,12 +432,11 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS) const { } // Handle REX prefix. -#if 0 // FIXME: Add in, also, can this come before F2 etc to simplify emission? + // FIXME: Can this come before F2 etc to simplify emission? if (Is64BitMode) { - if (unsigned REX = X86InstrInfo::determineREX(MI)) + if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) EmitByte(0x40 | REX, OS); } -#endif // 0x0F escape code must be emitted just before the opcode. if (Need0FPrefix) |