summaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86CodeEmitter.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-05-19 08:28:17 +0000
committerCraig Topper <craig.topper@gmail.com>2012-05-19 08:28:17 +0000
commit769237bb92515cc8680538f95dfb2eef76ecadd2 (patch)
tree31a2adf57db95dcef7de7e672389700539ce008f /lib/Target/X86/X86CodeEmitter.cpp
parent1dc6d7cbb5affee14a2fc5e7269616f3b7b4b6fa (diff)
downloadllvm-769237bb92515cc8680538f95dfb2eef76ecadd2.tar.gz
llvm-769237bb92515cc8680538f95dfb2eef76ecadd2.tar.bz2
llvm-769237bb92515cc8680538f95dfb2eef76ecadd2.tar.xz
Copy some AVX support from MCJIT to JIT. Maybe will fix PR12748.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157109 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86CodeEmitter.cpp')
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp46
1 files changed, 29 insertions, 17 deletions
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 57af7bb43f..6757043bc0 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -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";