Copy some AVX support from MCJIT to JIT. Maybe will fix PR12748.

llvm-svn: 157109
This commit is contained in:
Craig Topper 2012-05-19 08:28:17 +00:00
parent a336f5e645
commit 6166178573
1 changed files with 29 additions and 17 deletions

View File

@ -749,10 +749,6 @@ void Emitter<CodeEmitter>::emitOpcodePrefix(uint64_t TSFlags,
}
}
static unsigned GetX86RegNum(const MachineOperand &MO) {
return X86_MC::getX86RegNum(MO.getReg());
}
// On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range
// 0-7 and the difference between the 2 groups is given by the REX prefix.
// In the VEX prefix, registers are seen sequencially from 0-15 and encoded
@ -765,7 +761,7 @@ static unsigned GetX86RegNum(const MachineOperand &MO) {
static unsigned char getVEXRegisterEncoding(const MachineInstr &MI,
unsigned OpNum) {
unsigned SrcReg = MI.getOperand(OpNum).getReg();
unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum));
unsigned SrcRegNum = X86_MC::getX86RegNum(MI.getOperand(OpNum).getReg());
if (X86II::isX86_64ExtendedReg(SrcReg))
SrcRegNum |= 8;
@ -1132,6 +1128,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V;
bool HasVEX_4VOp3 = (TSFlags >> X86II::VEXShift) & X86II::VEX_4VOp3;
bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4;
const unsigned MemOp4_I8IMMOperand = 2;
// Determine where the memory operand starts, if present.
int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode);
@ -1273,9 +1270,6 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
emitRegModRMByte(MI.getOperand(CurOp).getReg(),
X86_MC::getX86RegNum(MI.getOperand(CurOp+1).getReg()));
CurOp += 2;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
X86II::getSizeOfImm(Desc->TSFlags));
break;
}
case X86II::MRMDestMem: {
@ -1287,9 +1281,6 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
emitMemModRMByte(MI, CurOp,
X86_MC::getX86RegNum(MI.getOperand(SrcRegNum).getReg()));
CurOp = SrcRegNum + 1;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@ -1309,9 +1300,6 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1;
if (HasVEX_4VOp3)
++CurOp;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
X86II::getSizeOfImm(Desc->TSFlags));
break;
}
case X86II::MRMSrcMem: {
@ -1333,9 +1321,6 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
CurOp += AddrOperands + 1;
if (HasVEX_4VOp3)
++CurOp;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@ -1448,6 +1433,33 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
break;
}
if (CurOp != NumOps) {
// The last source register of a 4 operand instruction in AVX is encoded
// in bits[7:4] of a immediate byte.
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM) {
const MachineOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand
: CurOp);
CurOp++;
bool IsExtReg = X86II::isX86_64ExtendedReg(MO.getReg());
unsigned RegNum = (IsExtReg ? (1 << 7) : 0);
RegNum |= X86_MC::getX86RegNum(MO.getReg()) << 4;
// If there is an additional 5th operand it must be an immediate, which
// is encoded in bits[3:0]
if(CurOp != NumOps) {
const MachineOperand &MIMM = MI.getOperand(CurOp++);
if(MIMM.isImm()) {
unsigned Val = MIMM.getImm();
assert(Val < 16 && "Immediate operand value out of range");
RegNum |= Val;
}
}
emitConstant(RegNum, 1);
} else {
emitConstant(MI.getOperand(CurOp++).getImm(),
X86II::getSizeOfImm(Desc->TSFlags));
}
}
if (!MI.isVariadic() && CurOp != NumOps) {
#ifndef NDEBUG
dbgs() << "Cannot encode all operands of: " << MI << "\n";