mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-19 06:31:18 +00:00
Re-write part of VEX encoding logic, to be more easy to read! Also fix
a bug and add a testcase! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138123 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
87fdee6488
commit
0c9acfcb50
@ -492,76 +492,100 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
VEX_L = 1;
|
VEX_L = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NumOps = MI.getNumOperands();
|
// Classify VEX_B, VEX_4V, VEX_R, VEX_X
|
||||||
unsigned CurOp = 0;
|
unsigned CurOp = 0;
|
||||||
bool IsDestMem = false;
|
|
||||||
|
|
||||||
switch (TSFlags & X86II::FormMask) {
|
switch (TSFlags & X86II::FormMask) {
|
||||||
case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!");
|
case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!");
|
||||||
case X86II::MRMDestMem:
|
case X86II::MRMDestMem: {
|
||||||
IsDestMem = true;
|
// MRMDestMem instructions forms:
|
||||||
// The important info for the VEX prefix is never beyond the address
|
// MemAddr, src1(ModR/M)
|
||||||
// registers. Don't check beyond that.
|
// MemAddr, src1(VEX_4V), src2(ModR/M)
|
||||||
NumOps = CurOp = X86::AddrNumOperands;
|
// MemAddr, src1(ModR/M), imm8
|
||||||
|
//
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrBaseReg).getReg()))
|
||||||
|
VEX_B = 0x0;
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrIndexReg).getReg()))
|
||||||
|
VEX_X = 0x0;
|
||||||
|
|
||||||
|
CurOp = X86::AddrNumOperands;
|
||||||
|
if (HasVEX_4V)
|
||||||
|
VEX_4V = getVEXRegisterEncoding(MI, CurOp++);
|
||||||
|
|
||||||
|
const MCOperand &MO = MI.getOperand(CurOp);
|
||||||
|
if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg()))
|
||||||
|
VEX_R = 0x0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case X86II::MRMSrcMem: {
|
||||||
|
// MRMSrcMem instructions forms:
|
||||||
|
// src1(ModR/M), MemAddr
|
||||||
|
// src1(ModR/M), src2(VEX_4V), MemAddr
|
||||||
|
// src1(ModR/M), MemAddr, imm8
|
||||||
|
// src1(ModR/M), MemAddr, src2(VEX_I8IMM)
|
||||||
|
//
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
|
||||||
|
VEX_R = 0x0;
|
||||||
|
|
||||||
|
unsigned MemAddrOffset = 1;
|
||||||
|
if (HasVEX_4V) {
|
||||||
|
VEX_4V = getVEXRegisterEncoding(MI, 1);
|
||||||
|
MemAddrOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X86II::isX86_64ExtendedReg(
|
||||||
|
MI.getOperand(MemAddrOffset+X86::AddrBaseReg).getReg()))
|
||||||
|
VEX_B = 0x0;
|
||||||
|
if (X86II::isX86_64ExtendedReg(
|
||||||
|
MI.getOperand(MemAddrOffset+X86::AddrIndexReg).getReg()))
|
||||||
|
VEX_X = 0x0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case X86II::MRM0m: case X86II::MRM1m:
|
case X86II::MRM0m: case X86II::MRM1m:
|
||||||
case X86II::MRM2m: case X86II::MRM3m:
|
case X86II::MRM2m: case X86II::MRM3m:
|
||||||
case X86II::MRM4m: case X86II::MRM5m:
|
case X86II::MRM4m: case X86II::MRM5m:
|
||||||
case X86II::MRM6m: case X86II::MRM7m:
|
case X86II::MRM6m: case X86II::MRM7m:
|
||||||
case X86II::MRMSrcMem:
|
// MRM[0-9]m instructions forms:
|
||||||
|
// MemAddr
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrBaseReg).getReg()))
|
||||||
|
VEX_B = 0x0;
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrIndexReg).getReg()))
|
||||||
|
VEX_X = 0x0;
|
||||||
|
break;
|
||||||
case X86II::MRMSrcReg:
|
case X86II::MRMSrcReg:
|
||||||
if (MI.getNumOperands() > CurOp && MI.getOperand(CurOp).isReg() &&
|
// MRMSrcReg instructions forms:
|
||||||
X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
|
// dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM)
|
||||||
|
// dst(ModR/M), src1(ModR/M)
|
||||||
|
// dst(ModR/M), src1(ModR/M), imm8
|
||||||
|
//
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
|
||||||
VEX_R = 0x0;
|
VEX_R = 0x0;
|
||||||
CurOp++;
|
CurOp++;
|
||||||
|
|
||||||
if (HasVEX_4V) {
|
|
||||||
VEX_4V = getVEXRegisterEncoding(MI, IsDestMem ? CurOp-1 : CurOp);
|
|
||||||
CurOp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To only check operands before the memory address ones, start
|
|
||||||
// the search from the beginning
|
|
||||||
if (IsDestMem)
|
|
||||||
CurOp = 0;
|
|
||||||
|
|
||||||
// If the last register should be encoded in the immediate field
|
|
||||||
// do not use any bit from VEX prefix to this register, ignore it
|
|
||||||
if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM)
|
|
||||||
NumOps--;
|
|
||||||
|
|
||||||
for (; CurOp != NumOps; ++CurOp) {
|
|
||||||
const MCOperand &MO = MI.getOperand(CurOp);
|
|
||||||
if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg()))
|
|
||||||
VEX_B = 0x0;
|
|
||||||
// Only set VEX_X if the Index Register is extended
|
|
||||||
if (VEX_B || !MO.isReg())
|
|
||||||
continue;
|
|
||||||
if (!X86II::isX86_64ExtendedReg(MO.getReg()))
|
|
||||||
continue;
|
|
||||||
unsigned Frm = TSFlags & X86II::FormMask;
|
|
||||||
if ((Frm == X86II::MRMSrcMem && CurOp-1 == X86::AddrIndexReg) ||
|
|
||||||
(Frm == X86II::MRMDestMem && CurOp == X86::AddrIndexReg))
|
|
||||||
VEX_X = 0x0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: // MRMDestReg, MRM0r-MRM7r, RawFrm
|
|
||||||
if (!MI.getNumOperands())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (MI.getOperand(CurOp).isReg() &&
|
|
||||||
X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
|
|
||||||
VEX_B = 0;
|
|
||||||
|
|
||||||
if (HasVEX_4V)
|
if (HasVEX_4V)
|
||||||
VEX_4V = getVEXRegisterEncoding(MI, CurOp);
|
VEX_4V = getVEXRegisterEncoding(MI, CurOp++);
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
|
||||||
CurOp++;
|
VEX_B = 0x0;
|
||||||
for (; CurOp != NumOps; ++CurOp) {
|
break;
|
||||||
const MCOperand &MO = MI.getOperand(CurOp);
|
case X86II::MRMDestReg:
|
||||||
if (MO.isReg() && !HasVEX_4V &&
|
// MRMDestReg instructions forms:
|
||||||
X86II::isX86_64ExtendedReg(MO.getReg()))
|
// dst(ModR/M), src(ModR/M)
|
||||||
VEX_R = 0x0;
|
// dst(ModR/M), src(ModR/M), imm8
|
||||||
}
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
|
||||||
|
VEX_B = 0x0;
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(1).getReg()))
|
||||||
|
VEX_R = 0x0;
|
||||||
|
break;
|
||||||
|
case X86II::MRM0r: case X86II::MRM1r:
|
||||||
|
case X86II::MRM2r: case X86II::MRM3r:
|
||||||
|
case X86II::MRM4r: case X86II::MRM5r:
|
||||||
|
case X86II::MRM6r: case X86II::MRM7r:
|
||||||
|
// MRM0r-MRM7r instructions forms:
|
||||||
|
// dst(VEX_4V), src(ModR/M), imm8
|
||||||
|
VEX_4V = getVEXRegisterEncoding(MI, 0);
|
||||||
|
if (X86II::isX86_64ExtendedReg(MI.getOperand(1).getReg()))
|
||||||
|
VEX_B = 0x0;
|
||||||
|
break;
|
||||||
|
default: // RawFrm
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3332,3 +3332,7 @@ vdivpd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
|||||||
// CHECK: encoding: [0xc4,0xc1,0x78,0x28,0x1c,0x1e]
|
// CHECK: encoding: [0xc4,0xc1,0x78,0x28,0x1c,0x1e]
|
||||||
vmovaps (%r14,%rbx), %xmm3
|
vmovaps (%r14,%rbx), %xmm3
|
||||||
|
|
||||||
|
// CHECK: vmovaps %xmm3, (%rax,%r11)
|
||||||
|
// CHECK: encoding: [0xc4,0xa1,0x78,0x29,0x1c,0x18]
|
||||||
|
vmovaps %xmm3, (%rax,%r11)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user