mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
port X86InstrInfo::determineREX over to the new encoder.
llvm-svn: 95440
This commit is contained in:
parent
670458b3be
commit
8db3500688
@ -3015,11 +3015,10 @@ isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended register?
|
/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher)
|
||||||
/// e.g. r8, xmm8, etc.
|
/// register? e.g. r8, xmm8, xmm13, etc.
|
||||||
bool X86InstrInfo::isX86_64ExtendedReg(const MachineOperand &MO) {
|
bool X86InstrInfo::isX86_64ExtendedReg(unsigned RegNo) {
|
||||||
if (!MO.isReg()) return false;
|
switch (RegNo) {
|
||||||
switch (MO.getReg()) {
|
|
||||||
default: break;
|
default: break;
|
||||||
case X86::R8: case X86::R9: case X86::R10: case X86::R11:
|
case X86::R8: case X86::R9: case X86::R10: case X86::R11:
|
||||||
case X86::R12: case X86::R13: case X86::R14: case X86::R15:
|
case X86::R12: case X86::R13: case X86::R14: case X86::R15:
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "X86RegisterInfo.h"
|
#include "X86RegisterInfo.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class X86RegisterInfo;
|
class X86RegisterInfo;
|
||||||
@ -661,9 +660,16 @@ public:
|
|||||||
reg == X86::SIL || reg == X86::DIL);
|
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);
|
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.
|
/// GetInstSize - Returns the size of the specified MachineInstr.
|
||||||
///
|
///
|
||||||
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
|
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
|
||||||
|
@ -266,6 +266,101 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
|
|||||||
EmitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel, OS);
|
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::
|
void X86MCCodeEmitter::
|
||||||
EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
|
EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
|
||||||
@ -337,12 +432,11 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle REX prefix.
|
// 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 (Is64BitMode) {
|
||||||
if (unsigned REX = X86InstrInfo::determineREX(MI))
|
if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc))
|
||||||
EmitByte(0x40 | REX, OS);
|
EmitByte(0x40 | REX, OS);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x0F escape code must be emitted just before the opcode.
|
// 0x0F escape code must be emitted just before the opcode.
|
||||||
if (Need0FPrefix)
|
if (Need0FPrefix)
|
||||||
|
Loading…
Reference in New Issue
Block a user