mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Various x86 disassembler fixes.
Add VEX_LIG to scalar FMA4 instructions. Use VEX_LIG in some of the inheriting checks in disassembler table generator. Make use of VEX_L_W, VEX_L_W_XS, VEX_L_W_XD contexts. Don't let VEX_L_W, VEX_L_W_XS, VEX_L_W_XD, VEX_L_W_OPSIZE inherit from their non-L forms unless VEX_LIG is set. Let VEX_L_W, VEX_L_W_XS, VEX_L_W_XD, VEX_L_W_OPSIZE inherit from all of their non-L or non-W cases. Increase ranking on VEX_L_W, VEX_L_W_XS, VEX_L_W_XD, VEX_L_W_OPSIZE so they get chosen over non-L/non-W forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191649 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2f08433210
commit
92b4581953
@ -828,42 +828,6 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
|
||||
|
||||
/* The following clauses compensate for limitations of the tables. */
|
||||
|
||||
if ((attrMask & ATTR_VEXL) && (attrMask & ATTR_REXW) &&
|
||||
!(attrMask & ATTR_OPSIZE)) {
|
||||
/*
|
||||
* Some VEX instructions ignore the L-bit, but use the W-bit. Normally L-bit
|
||||
* has precedence since there are no L-bit with W-bit entries in the tables.
|
||||
* So if the L-bit isn't significant we should use the W-bit instead.
|
||||
* We only need to do this if the instruction doesn't specify OpSize since
|
||||
* there is a VEX_L_W_OPSIZE table.
|
||||
*/
|
||||
|
||||
const struct InstructionSpecifier *spec;
|
||||
uint16_t instructionIDWithWBit;
|
||||
const struct InstructionSpecifier *specWithWBit;
|
||||
|
||||
spec = specifierForUID(instructionID);
|
||||
|
||||
if (getIDWithAttrMask(&instructionIDWithWBit,
|
||||
insn,
|
||||
(attrMask & (~ATTR_VEXL)) | ATTR_REXW)) {
|
||||
insn->instructionID = instructionID;
|
||||
insn->spec = spec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
specWithWBit = specifierForUID(instructionIDWithWBit);
|
||||
|
||||
if (instructionID != instructionIDWithWBit) {
|
||||
insn->instructionID = instructionIDWithWBit;
|
||||
insn->spec = specWithWBit;
|
||||
} else {
|
||||
insn->instructionID = instructionID;
|
||||
insn->spec = spec;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) {
|
||||
/*
|
||||
* The instruction tables make no distinction between instructions that
|
||||
|
@ -116,10 +116,10 @@ enum attributeBits {
|
||||
ENUM_ENTRY(IC_VEX_L_XS, 4, "requires VEX and the L and XS prefix")\
|
||||
ENUM_ENTRY(IC_VEX_L_XD, 4, "requires VEX and the L and XD prefix")\
|
||||
ENUM_ENTRY(IC_VEX_L_OPSIZE, 4, "requires VEX, L, and OpSize") \
|
||||
ENUM_ENTRY(IC_VEX_L_W, 3, "requires VEX, L and W") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_XS, 4, "requires VEX, L, W and XS prefix") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_XD, 4, "requires VEX, L, W and XD prefix") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_OPSIZE, 4, "requires VEX, L, W and OpSize") \
|
||||
ENUM_ENTRY(IC_VEX_L_W, 4, "requires VEX, L and W") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_XS, 5, "requires VEX, L, W and XS prefix") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_XD, 5, "requires VEX, L, W and XD prefix") \
|
||||
ENUM_ENTRY(IC_VEX_L_W_OPSIZE, 5, "requires VEX, L, W and OpSize") \
|
||||
ENUM_ENTRY(IC_EVEX, 1, "requires an EVEX prefix") \
|
||||
ENUM_ENTRY(IC_EVEX_XS, 2, "requires EVEX and the XS prefix") \
|
||||
ENUM_ENTRY(IC_EVEX_XD, 2, "requires EVEX and the XD prefix") \
|
||||
|
@ -206,25 +206,26 @@ multiclass fma4s<bits<8> opc, string OpcodeStr, RegisterClass RC,
|
||||
!strconcat(OpcodeStr,
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
|
||||
[(set RC:$dst,
|
||||
(OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>, VEX_W, MemOp4;
|
||||
(OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>, VEX_W, VEX_LIG, MemOp4;
|
||||
def rm : FMA4<opc, MRMSrcMem, (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, MemOp4;
|
||||
(mem_frag addr:$src3)))]>, VEX_W, VEX_LIG, MemOp4;
|
||||
def mr : FMA4<opc, MRMSrcMem, (outs RC:$dst),
|
||||
(ins RC:$src1, x86memop:$src2, RC:$src3),
|
||||
!strconcat(OpcodeStr,
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
|
||||
[(set RC:$dst,
|
||||
(OpNode RC:$src1, (mem_frag addr:$src2), RC:$src3))]>;
|
||||
(OpNode RC:$src1, (mem_frag addr:$src2), RC:$src3))]>, VEX_LIG;
|
||||
// For disassembler
|
||||
let isCodeGenOnly = 1, hasSideEffects = 0 in
|
||||
def rr_REV : FMA4<opc, MRMSrcReg, (outs RC:$dst),
|
||||
(ins RC:$src1, RC:$src2, RC:$src3),
|
||||
!strconcat(OpcodeStr,
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), []>;
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), []>,
|
||||
VEX_LIG;
|
||||
}
|
||||
|
||||
multiclass fma4s_int<bits<8> opc, string OpcodeStr, Operand memop,
|
||||
@ -235,19 +236,19 @@ multiclass fma4s_int<bits<8> opc, string OpcodeStr, Operand memop,
|
||||
!strconcat(OpcodeStr,
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
|
||||
[(set VR128:$dst,
|
||||
(Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_W, MemOp4;
|
||||
(Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_W, VEX_LIG, MemOp4;
|
||||
def rm_Int : FMA4<opc, MRMSrcMem, (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, MemOp4;
|
||||
mem_cpat:$src3))]>, VEX_W, VEX_LIG, MemOp4;
|
||||
def mr_Int : FMA4<opc, MRMSrcMem, (outs VR128:$dst),
|
||||
(ins VR128:$src1, memop:$src2, VR128:$src3),
|
||||
!strconcat(OpcodeStr,
|
||||
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
|
||||
[(set VR128:$dst,
|
||||
(Int VR128:$src1, mem_cpat:$src2, VR128:$src3))]>;
|
||||
(Int VR128:$src1, mem_cpat:$src2, VR128:$src3))]>, VEX_LIG;
|
||||
}
|
||||
|
||||
multiclass fma4p<bits<8> opc, string OpcodeStr, SDNode OpNode,
|
||||
|
@ -129,6 +129,9 @@
|
||||
# CHECK: vcvtsd2si %xmm0, %rax
|
||||
0xc4 0xe1 0xfb 0x2d 0xc0
|
||||
|
||||
# CHECK: vcvtsd2si %xmm0, %rax
|
||||
0xc4 0xe1 0xff 0x2d 0xc0
|
||||
|
||||
# CHECK: vmaskmovpd %xmm0, %xmm1, (%rax)
|
||||
0xc4 0xe2 0x71 0x2f 0x00
|
||||
|
||||
@ -260,6 +263,9 @@
|
||||
# CHECK: vmovups %ymm0, %ymm1
|
||||
0xc5 0xfc 0x11 0xc1
|
||||
|
||||
# CHECK: vmovups %ymm0, %ymm1
|
||||
0xc4 0xe1 0xfc 0x11 0xc1
|
||||
|
||||
# CHECK: vmovaps %ymm1, %ymm0
|
||||
0xc5 0xfc 0x28 0xc1
|
||||
|
||||
@ -722,6 +728,36 @@
|
||||
# CHECK: vfmaddss %xmm1, (%rcx), %xmm0, %xmm0
|
||||
0xc4 0xe3 0x79 0x6a 0x01 0x10
|
||||
|
||||
# CHECK: vfmaddss (%rcx), %xmm1, %xmm0, %xmm0
|
||||
0xc4 0xe3 0xfd 0x6a 0x01 0x10
|
||||
|
||||
# CHECK: vfmaddss %xmm1, (%rcx), %xmm0, %xmm0
|
||||
0xc4 0xe3 0x7d 0x6a 0x01 0x10
|
||||
|
||||
# CHECK: vfmaddss %xmm2, %xmm1, %xmm0, %xmm0
|
||||
0xc4 0xe3 0xf9 0x6a 0xc2 0x10
|
||||
|
||||
# CHECK: vfmaddss %xmm1, %xmm2, %xmm0, %xmm0
|
||||
0xc4 0xe3 0x79 0x6a 0xc2 0x10
|
||||
|
||||
# CHECK: vfmaddss %xmm2, %xmm1, %xmm0, %xmm0
|
||||
0xc4 0xe3 0xfd 0x6a 0xc2 0x10
|
||||
|
||||
# CHECK: vfmaddss %xmm1, %xmm2, %xmm0, %xmm0
|
||||
0xc4 0xe3 0x7d 0x6a 0xc2 0x10
|
||||
|
||||
# CHECK: vfmaddps (%rcx), %xmm1, %xmm0, %xmm0
|
||||
0xc4 0xe3 0xf9 0x68 0x01 0x10
|
||||
|
||||
# CHECK: vfmaddps %xmm1, (%rcx), %xmm0, %xmm0
|
||||
0xc4 0xe3 0x79 0x68 0x01 0x10
|
||||
|
||||
# CHECK: vfmaddps %xmm1, %xmm2, %xmm0, %xmm0
|
||||
0xc4 0xe3 0x79 0x68 0xc2 0x10
|
||||
|
||||
# CHECK: vfmaddps %xmm2, %xmm1, %xmm0, %xmm0
|
||||
0xc4 0xe3 0xf9 0x68 0xc2 0x10
|
||||
|
||||
# CHECK: vpermil2ps $1, 4(%rax), %xmm2, %xmm3, %xmm0
|
||||
0xc4 0xe3 0xe1 0x48 0x40 0x04 0x21
|
||||
|
||||
|
@ -81,31 +81,37 @@ static inline bool inheritsFrom(InstructionContext child,
|
||||
case IC_64BIT_REXW_OPSIZE:
|
||||
return false;
|
||||
case IC_VEX:
|
||||
return inheritsFrom(child, IC_VEX_L_W) ||
|
||||
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) ||
|
||||
inheritsFrom(child, IC_VEX_W) ||
|
||||
(VEX_LIG && inheritsFrom(child, IC_VEX_L));
|
||||
case IC_VEX_XS:
|
||||
return inheritsFrom(child, IC_VEX_L_W_XS) ||
|
||||
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
|
||||
inheritsFrom(child, IC_VEX_W_XS) ||
|
||||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
|
||||
case IC_VEX_XD:
|
||||
return inheritsFrom(child, IC_VEX_L_W_XD) ||
|
||||
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
|
||||
inheritsFrom(child, IC_VEX_W_XD) ||
|
||||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
|
||||
case IC_VEX_OPSIZE:
|
||||
return inheritsFrom(child, IC_VEX_L_W_OPSIZE) ||
|
||||
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
|
||||
inheritsFrom(child, IC_VEX_W_OPSIZE) ||
|
||||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
|
||||
case IC_VEX_W:
|
||||
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
|
||||
case IC_VEX_W_XS:
|
||||
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS);
|
||||
case IC_VEX_W_XD:
|
||||
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD);
|
||||
case IC_VEX_W_OPSIZE:
|
||||
return false;
|
||||
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
|
||||
case IC_VEX_L:
|
||||
return inheritsFrom(child, IC_VEX_L_W);
|
||||
case IC_VEX_L_XS:
|
||||
return inheritsFrom(child, IC_VEX_L_W_XS);
|
||||
case IC_VEX_L_XD:
|
||||
return inheritsFrom(child, IC_VEX_L_W_XD);
|
||||
case IC_VEX_L_OPSIZE:
|
||||
return false;
|
||||
return inheritsFrom(child, IC_VEX_L_W_OPSIZE);
|
||||
case IC_VEX_L_W:
|
||||
case IC_VEX_L_W_XS:
|
||||
case IC_VEX_L_W_XD:
|
||||
@ -622,6 +628,12 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
|
||||
|
||||
if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
|
||||
o << "IC_VEX_L_W_OPSIZE";
|
||||
else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD))
|
||||
o << "IC_VEX_L_W_XD";
|
||||
else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XS))
|
||||
o << "IC_VEX_L_W_XS";
|
||||
else if ((index & ATTR_VEXL) && (index & ATTR_REXW))
|
||||
o << "IC_VEX_L_W";
|
||||
else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
|
||||
o << "IC_VEX_L_OPSIZE";
|
||||
else if ((index & ATTR_VEXL) && (index & ATTR_XD))
|
||||
|
Loading…
Reference in New Issue
Block a user