diff options
author | Craig Topper <craig.topper@gmail.com> | 2012-05-19 08:28:17 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2012-05-19 08:28:17 +0000 |
commit | 769237bb92515cc8680538f95dfb2eef76ecadd2 (patch) | |
tree | 31a2adf57db95dcef7de7e672389700539ce008f /lib/Target/X86/X86CodeEmitter.cpp | |
parent | 1dc6d7cbb5affee14a2fc5e7269616f3b7b4b6fa (diff) | |
download | llvm-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.cpp | 46 |
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"; |