mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-18 01:17:46 +00:00
[x86] Prevent llvm.x86.cmp.ps/pd/ss/sd from being selected with bad immediates. The frontend now checks this when the builtin is used. This will allow the instruction printer to not have to deal with invalid immediates on these instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224885 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cc80af1b4f
commit
6ba84e58da
@ -541,11 +541,19 @@ def SSECC : Operand<i8> {
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
def i8immZExt3 : ImmLeaf<i8, [{
|
||||
return Imm >= 0 && Imm < 8;
|
||||
}]>;
|
||||
|
||||
def AVXCC : Operand<i8> {
|
||||
let PrintMethod = "printAVXCC";
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
def i8immZExt5 : ImmLeaf<i8, [{
|
||||
return Imm >= 0 && Imm < 32;
|
||||
}]>;
|
||||
|
||||
class ImmSExtAsmOperandClass : AsmOperandClass {
|
||||
let SuperClasses = [ImmAsmOperand];
|
||||
let RenderMethod = "addImmOperands";
|
||||
|
@ -2333,15 +2333,15 @@ let Predicates = [UseSSE2] in {
|
||||
multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
|
||||
Operand CC, SDNode OpNode, ValueType VT,
|
||||
PatFrag ld_frag, string asm, string asm_alt,
|
||||
OpndItins itins> {
|
||||
OpndItins itins, ImmLeaf immLeaf> {
|
||||
def rr : SIi8<0xC2, MRMSrcReg,
|
||||
(outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
|
||||
[(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
|
||||
[(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, immLeaf:$cc))],
|
||||
itins.rr>, Sched<[itins.Sched]>;
|
||||
def rm : SIi8<0xC2, MRMSrcMem,
|
||||
(outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
|
||||
[(set RC:$dst, (OpNode (VT RC:$src1),
|
||||
(ld_frag addr:$src2), imm:$cc))],
|
||||
(ld_frag addr:$src2), immLeaf:$cc))],
|
||||
itins.rm>,
|
||||
Sched<[itins.Sched.Folded, ReadAfterLd]>;
|
||||
|
||||
@ -2361,38 +2361,37 @@ multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
|
||||
defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
|
||||
"cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSE_ALU_F32S>,
|
||||
XS, VEX_4V, VEX_LIG;
|
||||
SSE_ALU_F32S, i8immZExt5>, XS, VEX_4V, VEX_LIG;
|
||||
defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
|
||||
"cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSE_ALU_F32S>, // same latency as 32 bit compare
|
||||
SSE_ALU_F32S, i8immZExt5>, // same latency as 32 bit compare
|
||||
XD, VEX_4V, VEX_LIG;
|
||||
|
||||
let Constraints = "$src1 = $dst" in {
|
||||
defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
|
||||
"cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
|
||||
"cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S>,
|
||||
XS;
|
||||
"cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S,
|
||||
i8immZExt3>, XS;
|
||||
defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
|
||||
"cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
|
||||
"cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
|
||||
SSE_ALU_F64S>,
|
||||
XD;
|
||||
SSE_ALU_F64S, i8immZExt3>, XD;
|
||||
}
|
||||
|
||||
multiclass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,
|
||||
Intrinsic Int, string asm, OpndItins itins> {
|
||||
Intrinsic Int, string asm, OpndItins itins,
|
||||
ImmLeaf immLeaf> {
|
||||
def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
|
||||
(ins VR128:$src1, VR128:$src, CC:$cc), asm,
|
||||
[(set VR128:$dst, (Int VR128:$src1,
|
||||
VR128:$src, imm:$cc))],
|
||||
VR128:$src, immLeaf:$cc))],
|
||||
itins.rr>,
|
||||
Sched<[itins.Sched]>;
|
||||
def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
|
||||
(ins VR128:$src1, x86memop:$src, CC:$cc), asm,
|
||||
[(set VR128:$dst, (Int VR128:$src1,
|
||||
(load addr:$src), imm:$cc))],
|
||||
(load addr:$src), immLeaf:$cc))],
|
||||
itins.rm>,
|
||||
Sched<[itins.Sched.Folded, ReadAfterLd]>;
|
||||
}
|
||||
@ -2401,19 +2400,19 @@ let isCodeGenOnly = 1 in {
|
||||
// Aliases to match intrinsics which expect XMM operand(s).
|
||||
defm Int_VCMPSS : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,
|
||||
"cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
|
||||
SSE_ALU_F32S>,
|
||||
SSE_ALU_F32S, i8immZExt5>,
|
||||
XS, VEX_4V;
|
||||
defm Int_VCMPSD : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,
|
||||
"cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
|
||||
SSE_ALU_F32S>, // same latency as f32
|
||||
SSE_ALU_F32S, i8immZExt5>, // same latency as f32
|
||||
XD, VEX_4V;
|
||||
let Constraints = "$src1 = $dst" in {
|
||||
defm Int_CMPSS : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,
|
||||
"cmp${cc}ss\t{$src, $dst|$dst, $src}",
|
||||
SSE_ALU_F32S>, XS;
|
||||
SSE_ALU_F32S, i8immZExt3>, XS;
|
||||
defm Int_CMPSD : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,
|
||||
"cmp${cc}sd\t{$src, $dst|$dst, $src}",
|
||||
SSE_ALU_F64S>,
|
||||
SSE_ALU_F64S, i8immZExt3>,
|
||||
XD;
|
||||
}
|
||||
}
|
||||
@ -2487,16 +2486,16 @@ let Defs = [EFLAGS] in {
|
||||
// sse12_cmp_packed - sse 1 & 2 compare packed instructions
|
||||
multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
|
||||
Operand CC, Intrinsic Int, string asm,
|
||||
string asm_alt, Domain d,
|
||||
string asm_alt, Domain d, ImmLeaf immLeaf,
|
||||
OpndItins itins = SSE_ALU_F32P> {
|
||||
def rri : PIi8<0xC2, MRMSrcReg,
|
||||
(outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
|
||||
[(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
|
||||
[(set RC:$dst, (Int RC:$src1, RC:$src2, immLeaf:$cc))],
|
||||
itins.rr, d>,
|
||||
Sched<[WriteFAdd]>;
|
||||
def rmi : PIi8<0xC2, MRMSrcMem,
|
||||
(outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
|
||||
[(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
|
||||
[(set RC:$dst, (Int RC:$src1, (memop addr:$src2), immLeaf:$cc))],
|
||||
itins.rm, d>,
|
||||
Sched<[WriteFAddLd, ReadAfterLd]>;
|
||||
|
||||
@ -2515,28 +2514,28 @@ multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
|
||||
defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,
|
||||
"cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSEPackedSingle>, PS, VEX_4V;
|
||||
SSEPackedSingle, i8immZExt5>, PS, VEX_4V;
|
||||
defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,
|
||||
"cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSEPackedDouble>, PD, VEX_4V;
|
||||
SSEPackedDouble, i8immZExt5>, PD, VEX_4V;
|
||||
defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,
|
||||
"cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSEPackedSingle>, PS, VEX_4V, VEX_L;
|
||||
SSEPackedSingle, i8immZExt5>, PS, VEX_4V, VEX_L;
|
||||
defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,
|
||||
"cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
|
||||
"cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
|
||||
SSEPackedDouble>, PD, VEX_4V, VEX_L;
|
||||
SSEPackedDouble, i8immZExt5>, PD, VEX_4V, VEX_L;
|
||||
let Constraints = "$src1 = $dst" in {
|
||||
defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,
|
||||
"cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
|
||||
"cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
|
||||
SSEPackedSingle, SSE_ALU_F32P>, PS;
|
||||
SSEPackedSingle, i8immZExt5, SSE_ALU_F32P>, PS;
|
||||
defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,
|
||||
"cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
|
||||
"cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
|
||||
SSEPackedDouble, SSE_ALU_F64P>, PD;
|
||||
SSEPackedDouble, i8immZExt5, SSE_ALU_F64P>, PD;
|
||||
}
|
||||
|
||||
let Predicates = [HasAVX] in {
|
||||
|
Loading…
Reference in New Issue
Block a user