[llvm] r279423 - [X86] Create a new instruction format to handle MemOp4 encoding. This saves one bit in TSFlags and simplifies MRMSrcMem/MRMSrcReg format handling.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 22 00:38:45 PDT 2016
Author: ctopper
Date: Mon Aug 22 02:38:45 2016
New Revision: 279423
URL: http://llvm.org/viewvc/llvm-project?rev=279423&view=rev
Log:
[X86] Create a new instruction format to handle MemOp4 encoding. This saves one bit in TSFlags and simplifies MRMSrcMem/MRMSrcReg format handling.
Modified:
llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/trunk/lib/Target/X86/X86InstrFMA.td
llvm/trunk/lib/Target/X86/X86InstrFormats.td
llvm/trunk/lib/Target/X86/X86InstrXOP.td
llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
llvm/trunk/utils/TableGen/X86RecognizableInstr.h
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h Mon Aug 22 02:38:45 2016
@@ -277,6 +277,11 @@ namespace X86II {
///
MRMSrcMem = 33,
+ /// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM
+ /// byte to specify the fourth source, which in this case is memory.
+ ///
+ MRMSrcMemOp4 = 34,
+
/// MRMXm - This form is used for instructions that use the Mod/RM byte
/// to specify a memory source, but doesn't use the middle field.
///
@@ -296,6 +301,11 @@ namespace X86II {
///
MRMSrcReg = 49,
+ /// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM
+ /// byte to specify the fourth source, which in this case is a register.
+ ///
+ MRMSrcRegOp4 = 50,
+
/// MRMXr - This form is used for instructions that use the Mod/RM byte
/// to specify a register source, but doesn't use the middle field.
///
@@ -536,13 +546,8 @@ namespace X86II {
Has3DNow0F0FOpcodeShift = CD8_Scale_Shift + 7,
Has3DNow0F0FOpcode = 1ULL << Has3DNow0F0FOpcodeShift,
- /// MemOp4 - Used to indicate swapping of operand 3 and 4 to be encoded in
- /// ModRM or I8IMM. This is used for FMA4 and XOP instructions.
- MemOp4Shift = Has3DNow0F0FOpcodeShift + 1,
- MemOp4 = 1ULL << MemOp4Shift,
-
/// Explicitly specified rounding control
- EVEX_RCShift = MemOp4Shift + 1,
+ EVEX_RCShift = Has3DNow0F0FOpcodeShift + 1,
EVEX_RC = 1ULL << EVEX_RCShift
};
@@ -649,7 +654,6 @@ namespace X86II {
///
inline int getMemoryOperandNo(uint64_t TSFlags) {
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
- bool HasMemOp4 = TSFlags & X86II::MemOp4;
bool HasEVEX_K = TSFlags & X86II::EVEX_K;
switch (TSFlags & X86II::FormMask) {
@@ -669,9 +673,13 @@ namespace X86II {
case X86II::MRMSrcMem:
// Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a
// mask register.
- return 1 + HasVEX_4V + HasMemOp4 + HasEVEX_K;
+ return 1 + HasVEX_4V + HasEVEX_K;
+ case X86II::MRMSrcMemOp4:
+ // Skip registers encoded in reg, VEX_VVVV, and I8IMM.
+ return 3;
case X86II::MRMDestReg:
case X86II::MRMSrcReg:
+ case X86II::MRMSrcRegOp4:
case X86II::MRMXr:
case X86II::MRM0r: case X86II::MRM1r:
case X86II::MRM2r: case X86II::MRM3r:
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp Mon Aug 22 02:38:45 2016
@@ -603,7 +603,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
bool HasEVEX_K = TSFlags & X86II::EVEX_K;
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3;
- bool HasMemOp4 = TSFlags & X86II::MemOp4;
bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
// VEX_R: opcode externsion equivalent to REX.R in
@@ -749,7 +748,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
//
// FMA4:
// dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
- // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
VEX_R = ~(RegEnc >> 3) & 1;
EVEX_R2 = ~(RegEnc >> 4) & 1;
@@ -779,6 +777,20 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
VEX_4V = ~getX86RegEncoding(MI, CurOp + X86::AddrNumOperands) & 0xf;
break;
}
+ case X86II::MRMSrcMemOp4: {
+ // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+
+ unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
+ VEX_B = ~(BaseRegEnc >> 3) & 1;
+ unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
+ VEX_X = ~(IndexRegEnc >> 3) & 1;
+ break;
+ }
case X86II::MRM0m: case X86II::MRM1m:
case X86II::MRM2m: case X86II::MRM3m:
case X86II::MRM4m: case X86II::MRM5m:
@@ -808,7 +820,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
// dst(ModR/M), src1(ModR/M), imm8
//
// FMA4:
- // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
// dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
VEX_R = ~(RegEnc >> 3) & 1;
@@ -823,9 +834,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
- if (HasMemOp4) // Skip second register source (encoded in Imm[7:4])
- CurOp++;
-
RegEnc = getX86RegEncoding(MI, CurOp++);
VEX_B = ~(RegEnc >> 3) & 1;
VEX_X = ~(RegEnc >> 4) & 1;
@@ -841,6 +849,22 @@ void X86MCCodeEmitter::EmitVEXOpcodePref
}
break;
}
+ case X86II::MRMSrcRegOp4: {
+ // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+
+ // Skip second register source (encoded in Imm[7:4])
+ ++CurOp;
+
+ RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_B = ~(RegEnc >> 3) & 1;
+ VEX_X = ~(RegEnc >> 4) & 1;
+ break;
+ }
case X86II::MRMDestReg: {
// MRMDestReg instructions forms:
// dst(ModR/M), src(ModR/M)
@@ -1134,9 +1158,7 @@ encodeInstruction(const MCInst &MI, raw_
// It uses the VEX.VVVV field?
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3;
- bool HasMemOp4 = TSFlags & X86II::MemOp4;
bool HasVEX_I8Reg = (TSFlags & X86II::ImmMask) == X86II::Imm8Reg;
- assert((!HasMemOp4 || HasVEX_I8Reg) && "MemOp4 should imply VEX_I8Reg");
// It uses the EVEX.aaa field?
bool HasEVEX_K = TSFlags & X86II::EVEX_K;
@@ -1312,21 +1334,34 @@ encodeInstruction(const MCInst &MI, raw_
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
- if (HasMemOp4) // Capture 2nd src (which is encoded in Imm[7:4])
- I8RegNum = getX86RegEncoding(MI, SrcRegNum++);
-
EmitRegModRMByte(MI.getOperand(SrcRegNum),
GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
CurOp = SrcRegNum + 1;
if (HasVEX_4VOp3)
++CurOp;
- if (!HasMemOp4 && HasVEX_I8Reg)
+ if (HasVEX_I8Reg)
I8RegNum = getX86RegEncoding(MI, CurOp++);
// do not count the rounding control operand
if (HasEVEX_RC)
--NumOps;
break;
}
+ case X86II::MRMSrcRegOp4: {
+ EmitByte(BaseOpcode, CurByte, OS);
+ unsigned SrcRegNum = CurOp + 1;
+
+ // Skip 1st src (which is encoded in VEX_VVVV)
+ ++SrcRegNum;
+
+ // Capture 2nd src (which is encoded in Imm[7:4])
+ assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
+ I8RegNum = getX86RegEncoding(MI, SrcRegNum++);
+
+ EmitRegModRMByte(MI.getOperand(SrcRegNum),
+ GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
+ CurOp = SrcRegNum + 1;
+ break;
+ }
case X86II::MRMSrcMem: {
unsigned FirstMemOp = CurOp+1;
@@ -1336,9 +1371,6 @@ encodeInstruction(const MCInst &MI, raw_
if (HasVEX_4V)
++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
- if (HasMemOp4) // Capture second register source (encoded in Imm[7:4])
- I8RegNum = getX86RegEncoding(MI, FirstMemOp++);
-
EmitByte(BaseOpcode, CurByte, OS);
emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
@@ -1346,10 +1378,26 @@ encodeInstruction(const MCInst &MI, raw_
CurOp = FirstMemOp + X86::AddrNumOperands;
if (HasVEX_4VOp3)
++CurOp;
- if (!HasMemOp4 && HasVEX_I8Reg)
+ if (HasVEX_I8Reg)
I8RegNum = getX86RegEncoding(MI, CurOp++);
break;
}
+ case X86II::MRMSrcMemOp4: {
+ unsigned FirstMemOp = CurOp+1;
+
+ ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
+
+ // Capture second register source (encoded in Imm[7:4])
+ assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
+ I8RegNum = getX86RegEncoding(MI, FirstMemOp++);
+
+ EmitByte(BaseOpcode, CurByte, OS);
+
+ emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
+ TSFlags, Rex, CurByte, OS, Fixups, STI);
+ CurOp = FirstMemOp + X86::AddrNumOperands;
+ break;
+ }
case X86II::MRMXr:
case X86II::MRM0r: case X86II::MRM1r:
Modified: llvm/trunk/lib/Target/X86/X86InstrFMA.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFMA.td?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFMA.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFMA.td Mon Aug 22 02:38:45 2016
@@ -269,18 +269,18 @@ multiclass fma4s<bits<8> opc, string Opc
X86MemOperand x86memop, ValueType OpVT, SDNode OpNode,
PatFrag mem_frag> {
let isCommutable = 1 in
- def rr : FMA4<opc, MRMSrcReg, (outs RC:$dst),
+ def rr : FMA4<opc, MRMSrcRegOp4, (outs RC:$dst),
(ins RC:$src1, RC:$src2, RC:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set RC:$dst,
- (OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>, VEX_W, VEX_LIG, MemOp4;
- def rm : FMA4<opc, MRMSrcMem, (outs RC:$dst),
+ (OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>, VEX_W, VEX_LIG;
+ def rm : FMA4<opc, MRMSrcMemOp4, (outs RC:$dst),
(ins RC:$src1, RC:$src2, x86memop:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set RC:$dst, (OpNode RC:$src1, RC:$src2,
- (mem_frag addr:$src3)))]>, VEX_W, VEX_LIG, MemOp4;
+ (mem_frag addr:$src3)))]>, VEX_W, VEX_LIG;
def mr : FMA4<opc, MRMSrcMem, (outs RC:$dst),
(ins RC:$src1, x86memop:$src2, RC:$src3),
!strconcat(OpcodeStr,
@@ -300,18 +300,18 @@ multiclass fma4s_int<bits<8> opc, string
ComplexPattern mem_cpat, Intrinsic Int> {
let isCodeGenOnly = 1 in {
let isCommutable = 1 in
- def rr_Int : FMA4<opc, MRMSrcReg, (outs VR128:$dst),
+ def rr_Int : FMA4<opc, MRMSrcRegOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, VR128:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
- (Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_W, VEX_LIG, MemOp4;
- def rm_Int : FMA4<opc, MRMSrcMem, (outs VR128:$dst),
+ (Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_W, VEX_LIG;
+ def rm_Int : FMA4<opc, MRMSrcMemOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, memop:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst, (Int VR128:$src1, VR128:$src2,
- mem_cpat:$src3))]>, VEX_W, VEX_LIG, MemOp4;
+ mem_cpat:$src3))]>, VEX_W, VEX_LIG;
def mr_Int : FMA4<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, memop:$src2, VR128:$src3),
!strconcat(OpcodeStr,
@@ -325,19 +325,19 @@ multiclass fma4p<bits<8> opc, string Opc
ValueType OpVT128, ValueType OpVT256,
PatFrag ld_frag128, PatFrag ld_frag256> {
let isCommutable = 1 in
- def rr : FMA4<opc, MRMSrcReg, (outs VR128:$dst),
+ def rr : FMA4<opc, MRMSrcRegOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, VR128:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
(OpVT128 (OpNode VR128:$src1, VR128:$src2, VR128:$src3)))]>,
- VEX_W, MemOp4;
- def rm : FMA4<opc, MRMSrcMem, (outs VR128:$dst),
+ VEX_W;
+ def rm : FMA4<opc, MRMSrcMemOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, f128mem:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst, (OpNode VR128:$src1, VR128:$src2,
- (ld_frag128 addr:$src3)))]>, VEX_W, MemOp4;
+ (ld_frag128 addr:$src3)))]>, VEX_W;
def mr : FMA4<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, f128mem:$src2, VR128:$src3),
!strconcat(OpcodeStr,
@@ -345,19 +345,19 @@ multiclass fma4p<bits<8> opc, string Opc
[(set VR128:$dst,
(OpNode VR128:$src1, (ld_frag128 addr:$src2), VR128:$src3))]>;
let isCommutable = 1 in
- def Yrr : FMA4<opc, MRMSrcReg, (outs VR256:$dst),
+ def Yrr : FMA4<opc, MRMSrcRegOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, VR256:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR256:$dst,
(OpVT256 (OpNode VR256:$src1, VR256:$src2, VR256:$src3)))]>,
- VEX_W, MemOp4, VEX_L;
- def Yrm : FMA4<opc, MRMSrcMem, (outs VR256:$dst),
+ VEX_W, VEX_L;
+ def Yrm : FMA4<opc, MRMSrcMemOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, f256mem:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR256:$dst, (OpNode VR256:$src1, VR256:$src2,
- (ld_frag256 addr:$src3)))]>, VEX_W, MemOp4, VEX_L;
+ (ld_frag256 addr:$src3)))]>, VEX_W, VEX_L;
def Ymr : FMA4<opc, MRMSrcMem, (outs VR256:$dst),
(ins VR256:$src1, f256mem:$src2, VR256:$src3),
!strconcat(OpcodeStr,
Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Mon Aug 22 02:38:45 2016
@@ -27,14 +27,16 @@ def RawFrmDst : Format<5>;
def RawFrmDstSrc : Format<6>;
def RawFrmImm8 : Format<7>;
def RawFrmImm16 : Format<8>;
-def MRMDestMem : Format<32>;
-def MRMSrcMem : Format<33>;
+def MRMDestMem : Format<32>;
+def MRMSrcMem : Format<33>;
+def MRMSrcMemOp4 : Format<34>;
def MRMXm : Format<39>;
def MRM0m : Format<40>; def MRM1m : Format<41>; def MRM2m : Format<42>;
def MRM3m : Format<43>; def MRM4m : Format<44>; def MRM5m : Format<45>;
def MRM6m : Format<46>; def MRM7m : Format<47>;
-def MRMDestReg : Format<48>;
-def MRMSrcReg : Format<49>;
+def MRMDestReg : Format<48>;
+def MRMSrcReg : Format<49>;
+def MRMSrcRegOp4 : Format<50>;
def MRMXr : Format<55>;
def MRM0r : Format<56>; def MRM1r : Format<57>; def MRM2r : Format<58>;
def MRM3r : Format<59>; def MRM4r : Format<60>; def MRM5r : Format<61>;
@@ -218,7 +220,6 @@ class EVEX_CD8<int esize, CD8VForm form>
}
class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; }
-class MemOp4 { bit hasMemOp4Prefix = 1; }
class XOP { Encoding OpEnc = EncXOP; }
class XOP_4V : XOP { bit hasVEX_4V = 1; }
class XOP_4VOp3 : XOP { bit hasVEX_4VOp3 = 1; }
@@ -284,7 +285,6 @@ class X86Inst<bits<8> opcod, Format f, I
// assigning to bits<7>.
int CD8_EltSize = 0; // Compressed disp8 form - element-size in bytes.
bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding?
- bit hasMemOp4Prefix = 0; // Same bit as VEX_W, but used for swapping operands
bit hasEVEX_RC = 0; // Explicitly specified rounding control in FP instruction.
bits<2> EVEX_LL;
@@ -330,8 +330,7 @@ class X86Inst<bits<8> opcod, Format f, I
// If we run out of TSFlags bits, it's possible to encode this in 3 bits.
let TSFlags{53-47} = CD8_Scale;
let TSFlags{54} = has3DNow0F0FOpcode;
- let TSFlags{55} = hasMemOp4Prefix;
- let TSFlags{56} = hasEVEX_RC;
+ let TSFlags{55} = hasEVEX_RC;
}
class PseudoI<dag oops, dag iops, list<dag> pattern>
Modified: llvm/trunk/lib/Target/X86/X86InstrXOP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrXOP.td?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrXOP.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrXOP.td Mon Aug 22 02:38:45 2016
@@ -232,14 +232,14 @@ multiclass xop4op<bits<8> opc, string Op
(vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2),
(vt128 VR128:$src3))))]>,
XOP_4V;
- def rrm : IXOPi8Reg<opc, MRMSrcMem, (outs VR128:$dst),
+ def rrm : IXOPi8Reg<opc, MRMSrcMemOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, i128mem:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
(vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2),
(vt128 (bitconvert (loadv2i64 addr:$src3))))))]>,
- XOP_4V, VEX_W, MemOp4;
+ XOP_4V, VEX_W;
def rmr : IXOPi8Reg<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, i128mem:$src2, VR128:$src3),
!strconcat(OpcodeStr,
@@ -250,11 +250,11 @@ multiclass xop4op<bits<8> opc, string Op
XOP_4V;
// For disassembler
let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
- def rrr_REV : IXOPi8Reg<opc, MRMSrcReg, (outs VR128:$dst),
+ def rrr_REV : IXOPi8Reg<opc, MRMSrcRegOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, VR128:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
- []>, XOP_4V, VEX_W, MemOp4;
+ []>, XOP_4V, VEX_W;
}
let ExeDomain = SSEPackedInt in {
@@ -271,14 +271,14 @@ multiclass xop4op_int<bits<8> opc, strin
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst, (Int128 VR128:$src1, VR128:$src2, VR128:$src3))]>,
XOP_4V;
- def rrm : IXOPi8Reg<opc, MRMSrcMem, (outs VR128:$dst),
+ def rrm : IXOPi8Reg<opc, MRMSrcMemOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, i128mem:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
(Int128 VR128:$src1, VR128:$src2,
(bitconvert (loadv2i64 addr:$src3))))]>,
- XOP_4V, VEX_W, MemOp4;
+ XOP_4V, VEX_W;
def rmr : IXOPi8Reg<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, i128mem:$src2, VR128:$src3),
!strconcat(OpcodeStr,
@@ -289,11 +289,11 @@ multiclass xop4op_int<bits<8> opc, strin
XOP_4V;
// For disassembler
let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
- def rrr_REV : IXOPi8Reg<opc, MRMSrcReg, (outs VR128:$dst),
+ def rrr_REV : IXOPi8Reg<opc, MRMSrcRegOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, VR128:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
- []>, XOP_4V, VEX_W, MemOp4;
+ []>, XOP_4V, VEX_W;
// 256-bit Instruction
def rrrY : IXOPi8Reg<opc, MRMSrcReg, (outs VR256:$dst),
@@ -302,14 +302,14 @@ multiclass xop4op_int<bits<8> opc, strin
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR256:$dst, (Int256 VR256:$src1, VR256:$src2, VR256:$src3))]>,
XOP_4V, VEX_L;
- def rrmY : IXOPi8Reg<opc, MRMSrcMem, (outs VR256:$dst),
+ def rrmY : IXOPi8Reg<opc, MRMSrcMemOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, i256mem:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR256:$dst,
(Int256 VR256:$src1, VR256:$src2,
(bitconvert (loadv4i64 addr:$src3))))]>,
- XOP_4V, VEX_W, MemOp4, VEX_L;
+ XOP_4V, VEX_W, VEX_L;
def rmrY : IXOPi8Reg<opc, MRMSrcMem, (outs VR256:$dst),
(ins VR256:$src1, f256mem:$src2, VR256:$src3),
!strconcat(OpcodeStr,
@@ -320,11 +320,11 @@ multiclass xop4op_int<bits<8> opc, strin
XOP_4V, VEX_L;
// For disassembler
let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
- def rrrY_REV : IXOPi8Reg<opc, MRMSrcReg, (outs VR256:$dst),
+ def rrrY_REV : IXOPi8Reg<opc, MRMSrcRegOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, VR256:$src3),
!strconcat(OpcodeStr,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
- []>, XOP_4V, VEX_W, MemOp4, VEX_L;
+ []>, XOP_4V, VEX_W, VEX_L;
}
let ExeDomain = SSEPackedInt in {
@@ -353,7 +353,7 @@ multiclass xop5op<bits<8> opc, string Op
[(set VR128:$dst,
(vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2),
(id128 VR128:$src3), (i8 imm:$src4))))]>;
- def rm : IXOP5<opc, MRMSrcMem, (outs VR128:$dst),
+ def rm : IXOP5<opc, MRMSrcMemOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, i128mem:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
"\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
@@ -361,7 +361,7 @@ multiclass xop5op<bits<8> opc, string Op
(vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2),
(id128 (bitconvert (loadv2i64 addr:$src3))),
(i8 imm:$src4))))]>,
- VEX_W, MemOp4;
+ VEX_W;
def mr : IXOP5<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, f128mem:$src2, VR128:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
@@ -372,11 +372,11 @@ multiclass xop5op<bits<8> opc, string Op
(id128 VR128:$src3), (i8 imm:$src4))))]>;
// For disassembler
let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
- def rr_REV : IXOP5<opc, MRMSrcReg, (outs VR128:$dst),
+ def rr_REV : IXOP5<opc, MRMSrcRegOp4, (outs VR128:$dst),
(ins VR128:$src1, VR128:$src2, VR128:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
"\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
- []>, VEX_W, MemOp4;
+ []>, VEX_W;
def rrY : IXOP5<opc, MRMSrcReg, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, VR256:$src3, u8imm:$src4),
@@ -385,14 +385,14 @@ multiclass xop5op<bits<8> opc, string Op
[(set VR256:$dst,
(vt256 (OpNode (vt256 VR256:$src1), (vt256 VR256:$src2),
(id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L;
- def rmY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst),
+ def rmY : IXOP5<opc, MRMSrcMemOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, i256mem:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
"\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
[(set VR256:$dst,
(vt256 (OpNode (vt256 VR256:$src1), (vt256 VR256:$src2),
(id256 (bitconvert (loadv4i64 addr:$src3))),
- (i8 imm:$src4))))]>, VEX_W, MemOp4, VEX_L;
+ (i8 imm:$src4))))]>, VEX_W, VEX_L;
def mrY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst),
(ins VR256:$src1, f256mem:$src2, VR256:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
@@ -403,11 +403,11 @@ multiclass xop5op<bits<8> opc, string Op
(id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L;
// For disassembler
let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
- def rrY_REV : IXOP5<opc, MRMSrcReg, (outs VR256:$dst),
+ def rrY_REV : IXOP5<opc, MRMSrcRegOp4, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, VR256:$src3, u8imm:$src4),
!strconcat(OpcodeStr,
"\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
- []>, VEX_W, MemOp4, VEX_L;
+ []>, VEX_W, VEX_L;
}
let ExeDomain = SSEPackedDouble in
Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Mon Aug 22 02:38:45 2016
@@ -100,13 +100,15 @@ namespace X86Local {
RawFrmDstSrc = 6,
RawFrmImm8 = 7,
RawFrmImm16 = 8,
- MRMDestMem = 32,
- MRMSrcMem = 33,
+ MRMDestMem = 32,
+ MRMSrcMem = 33,
+ MRMSrcMemOp4 = 34,
MRMXm = 39,
MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43,
MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47,
- MRMDestReg = 48,
- MRMSrcReg = 49,
+ MRMDestReg = 48,
+ MRMSrcReg = 49,
+ MRMSrcRegOp4 = 50,
MRMXr = 55,
MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59,
MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63,
@@ -201,7 +203,6 @@ RecognizableInstr::RecognizableInstr(Dis
HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3");
HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix");
- HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix");
IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L");
HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");
@@ -653,19 +654,24 @@ void RecognizableInstr::emitInstructionS
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
- if (HasMemOp4Prefix)
- HANDLE_OPERAND(immediate)
-
HANDLE_OPERAND(rmRegister)
if (HasVEX_4VOp3)
HANDLE_OPERAND(vvvvRegister)
- if (!HasMemOp4Prefix)
- HANDLE_OPTIONAL(immediate)
+ HANDLE_OPTIONAL(immediate)
HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::MRMSrcRegOp4:
+ assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
+ "Unexpected number of operands for MRMSrcRegOp4Frm");
+ HANDLE_OPERAND(roRegister)
+ HANDLE_OPERAND(vvvvRegister)
+ HANDLE_OPERAND(immediate) // Register in imm[7:4]
+ HANDLE_OPERAND(rmRegister)
+ HANDLE_OPTIONAL(immediate)
+ break;
case X86Local::MRMSrcMem:
// Operand 1 is a register operand in the Reg/Opcode field.
// Operand 2 is a memory operand (possibly SIB-extended)
@@ -686,18 +692,23 @@ void RecognizableInstr::emitInstructionS
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
- if (HasMemOp4Prefix)
- HANDLE_OPERAND(immediate)
-
HANDLE_OPERAND(memory)
if (HasVEX_4VOp3)
HANDLE_OPERAND(vvvvRegister)
- if (!HasMemOp4Prefix)
- HANDLE_OPTIONAL(immediate)
+ HANDLE_OPTIONAL(immediate)
HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
break;
+ case X86Local::MRMSrcMemOp4:
+ assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
+ "Unexpected number of operands for MRMSrcMemOp4Frm");
+ HANDLE_OPERAND(roRegister)
+ HANDLE_OPERAND(vvvvRegister)
+ HANDLE_OPERAND(immediate) // Register in imm[7:4]
+ HANDLE_OPERAND(memory)
+ HANDLE_OPTIONAL(immediate)
+ break;
case X86Local::MRMXr:
case X86Local::MRM0r:
case X86Local::MRM1r:
@@ -842,11 +853,13 @@ void RecognizableInstr::emitDecodePath(D
break;
case X86Local::MRMDestReg:
case X86Local::MRMSrcReg:
+ case X86Local::MRMSrcRegOp4:
case X86Local::MRMXr:
filter = new ModFilter(true);
break;
case X86Local::MRMDestMem:
case X86Local::MRMSrcMem:
+ case X86Local::MRMSrcMemOp4:
case X86Local::MRMXm:
filter = new ModFilter(false);
break;
Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.h?rev=279423&r1=279422&r2=279423&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.h (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.h Mon Aug 22 02:38:45 2016
@@ -61,8 +61,6 @@ private:
bool HasVEX_WPrefix;
/// Inferred from the operands; indicates whether the L bit in the VEX prefix is set
bool HasVEX_LPrefix;
- /// The hasMemOp4Prefix field from the record
- bool HasMemOp4Prefix;
/// The ignoreVEX_L field from the record
bool IgnoresVEX_L;
/// The hasEVEX_L2Prefix field from the record
More information about the llvm-commits
mailing list