forked from OSchip/llvm-project
[x86] Add assembly parser bounds checking to the immediate value for cmpss/cmpsd/cmpps/cmppd.
llvm-svn: 226642
This commit is contained in:
parent
53afae49ee
commit
f38dea1cfa
|
@ -34,6 +34,11 @@ inline bool isImmSExti64i32Value(uint64_t Value) {
|
||||||
(0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
|
(0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isImmUnsignedi8Value(uint64_t Value) {
|
||||||
|
return (( Value <= 0x00000000000000FFULL)||
|
||||||
|
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace llvm
|
} // End of namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -187,6 +187,13 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||||
return isImmSExti64i32Value(CE->getValue());
|
return isImmSExti64i32Value(CE->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isImmUnsignedi8() const {
|
||||||
|
if (!isImm()) return false;
|
||||||
|
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||||
|
if (!CE) return false;
|
||||||
|
return isImmUnsignedi8Value(CE->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
bool isOffsetOf() const override {
|
bool isOffsetOf() const override {
|
||||||
return OffsetOfLoc.getPointer();
|
return OffsetOfLoc.getPointer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1210,11 +1210,11 @@ multiclass avx512_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
|
||||||
(ld_frag addr:$src2), imm:$cc))], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
|
(ld_frag addr:$src2), imm:$cc))], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
|
||||||
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
||||||
def rri_alt : AVX512Ii8<0xC2, MRMSrcReg,
|
def rri_alt : AVX512Ii8<0xC2, MRMSrcReg,
|
||||||
(outs VK1:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
|
(outs VK1:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
|
||||||
asm_alt, [], IIC_SSE_ALU_F32S_RR>, EVEX_4V;
|
asm_alt, [], IIC_SSE_ALU_F32S_RR>, EVEX_4V;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def rmi_alt : AVX512Ii8<0xC2, MRMSrcMem,
|
def rmi_alt : AVX512Ii8<0xC2, MRMSrcMem,
|
||||||
(outs VK1:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
|
(outs VK1:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
|
||||||
asm_alt, [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
|
asm_alt, [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1545,12 +1545,12 @@ multiclass avx512_cmp_packed<RegisterClass KRC, RegisterClass RC,
|
||||||
// Accept explicit immediate argument form instead of comparison code.
|
// Accept explicit immediate argument form instead of comparison code.
|
||||||
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
||||||
def rri_alt : AVX512PIi8<0xC2, MRMSrcReg,
|
def rri_alt : AVX512PIi8<0xC2, MRMSrcReg,
|
||||||
(outs KRC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
|
(outs KRC:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
|
||||||
!strconcat("vcmp", suffix,
|
!strconcat("vcmp", suffix,
|
||||||
"\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
|
"\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def rmi_alt : AVX512PIi8<0xC2, MRMSrcMem,
|
def rmi_alt : AVX512PIi8<0xC2, MRMSrcMem,
|
||||||
(outs KRC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
|
(outs KRC:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
|
||||||
!strconcat("vcmp", suffix,
|
!strconcat("vcmp", suffix,
|
||||||
"\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
|
"\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,6 +609,14 @@ def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
|
||||||
ImmSExti64i32AsmOperand];
|
ImmSExti64i32AsmOperand];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unsigned immediate used by SSE/AVX instructions
|
||||||
|
// [0, 0xFF]
|
||||||
|
// [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
|
||||||
|
def ImmUnsignedi8AsmOperand : AsmOperandClass {
|
||||||
|
let Name = "ImmUnsignedi8";
|
||||||
|
let RenderMethod = "addImmOperands";
|
||||||
|
}
|
||||||
|
|
||||||
// A couple of more descriptive operand definitions.
|
// A couple of more descriptive operand definitions.
|
||||||
// 16-bits but only 8 bits are significant.
|
// 16-bits but only 8 bits are significant.
|
||||||
def i16i8imm : Operand<i16> {
|
def i16i8imm : Operand<i16> {
|
||||||
|
@ -627,6 +635,18 @@ def i64i32imm : Operand<i64> {
|
||||||
let OperandType = "OPERAND_IMMEDIATE";
|
let OperandType = "OPERAND_IMMEDIATE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 64-bits but only 8 bits are significant.
|
||||||
|
def i64i8imm : Operand<i64> {
|
||||||
|
let ParserMatchClass = ImmSExti64i8AsmOperand;
|
||||||
|
let OperandType = "OPERAND_IMMEDIATE";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsigned 8-bit immediate used by SSE/AVX instructions.
|
||||||
|
def u8imm : Operand<i8> {
|
||||||
|
let ParserMatchClass = ImmUnsignedi8AsmOperand;
|
||||||
|
let OperandType = "OPERAND_IMMEDIATE";
|
||||||
|
}
|
||||||
|
|
||||||
// 64-bits but only 32 bits are significant, and those bits are treated as being
|
// 64-bits but only 32 bits are significant, and those bits are treated as being
|
||||||
// pc relative.
|
// pc relative.
|
||||||
def i64i32imm_pcrel : Operand<i64> {
|
def i64i32imm_pcrel : Operand<i64> {
|
||||||
|
@ -635,12 +655,6 @@ def i64i32imm_pcrel : Operand<i64> {
|
||||||
let OperandType = "OPERAND_PCREL";
|
let OperandType = "OPERAND_PCREL";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64-bits but only 8 bits are significant.
|
|
||||||
def i64i8imm : Operand<i64> {
|
|
||||||
let ParserMatchClass = ImmSExti64i8AsmOperand;
|
|
||||||
let OperandType = "OPERAND_IMMEDIATE";
|
|
||||||
}
|
|
||||||
|
|
||||||
def lea64_32mem : Operand<i32> {
|
def lea64_32mem : Operand<i32> {
|
||||||
let PrintMethod = "printanymem";
|
let PrintMethod = "printanymem";
|
||||||
let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
|
let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
|
||||||
|
|
|
@ -2348,11 +2348,11 @@ multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
|
||||||
// Accept explicit immediate argument form instead of comparison code.
|
// Accept explicit immediate argument form instead of comparison code.
|
||||||
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
||||||
def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
|
def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
|
||||||
(ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, [],
|
(ins RC:$src1, RC:$src2, u8imm:$cc), asm_alt, [],
|
||||||
IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
|
IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
|
def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
|
||||||
(ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, [],
|
(ins RC:$src1, x86memop:$src2, u8imm:$cc), asm_alt, [],
|
||||||
IIC_SSE_ALU_F32S_RM>,
|
IIC_SSE_ALU_F32S_RM>,
|
||||||
Sched<[itins.Sched.Folded, ReadAfterLd]>;
|
Sched<[itins.Sched.Folded, ReadAfterLd]>;
|
||||||
}
|
}
|
||||||
|
@ -2502,11 +2502,11 @@ multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
|
||||||
// Accept explicit immediate argument form instead of comparison code.
|
// Accept explicit immediate argument form instead of comparison code.
|
||||||
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
let isAsmParserOnly = 1, hasSideEffects = 0 in {
|
||||||
def rri_alt : PIi8<0xC2, MRMSrcReg,
|
def rri_alt : PIi8<0xC2, MRMSrcReg,
|
||||||
(outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
|
(outs RC:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
|
||||||
asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
|
asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def rmi_alt : PIi8<0xC2, MRMSrcMem,
|
def rmi_alt : PIi8<0xC2, MRMSrcMem,
|
||||||
(outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
|
(outs RC:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
|
||||||
asm_alt, [], itins.rm, d>,
|
asm_alt, [], itins.rm, d>,
|
||||||
Sched<[WriteFAddLd, ReadAfterLd]>;
|
Sched<[WriteFAddLd, ReadAfterLd]>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3351,3 +3351,15 @@
|
||||||
vdppd $0x81, %xmm2, %xmm5, %xmm1
|
vdppd $0x81, %xmm2, %xmm5, %xmm1
|
||||||
// CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1
|
// CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1
|
||||||
vinsertps $0x81, %xmm3, %xmm2, %xmm1
|
vinsertps $0x81, %xmm3, %xmm2, %xmm1
|
||||||
|
|
||||||
|
// CHECK: vcmpps $-128, %xmm2, %xmm1, %xmm0
|
||||||
|
// CHECK: encoding: [0xc5,0xf0,0xc2,0xc2,0x80]
|
||||||
|
vcmpps $-128, %xmm2, %xmm1, %xmm0
|
||||||
|
|
||||||
|
// CHECK: vcmpps $128, %xmm2, %xmm1, %xmm0
|
||||||
|
// CHECK: encoding: [0xc5,0xf0,0xc2,0xc2,0x80]
|
||||||
|
vcmpps $128, %xmm2, %xmm1, %xmm0
|
||||||
|
|
||||||
|
// CHECK: vcmpps $255, %xmm2, %xmm1, %xmm0
|
||||||
|
// CHECK: encoding: [0xc5,0xf0,0xc2,0xc2,0xff]
|
||||||
|
vcmpps $255, %xmm2, %xmm1, %xmm0
|
||||||
|
|
|
@ -50,3 +50,11 @@ outb al, 4
|
||||||
// 32: error: invalid segment register
|
// 32: error: invalid segment register
|
||||||
// 64: error: invalid segment register
|
// 64: error: invalid segment register
|
||||||
movl %eax:0x00, %ebx
|
movl %eax:0x00, %ebx
|
||||||
|
|
||||||
|
// 32: error: invalid operand for instruction
|
||||||
|
// 64: error: invalid operand for instruction
|
||||||
|
cmpps $-129, %xmm0, %xmm0
|
||||||
|
|
||||||
|
// 32: error: invalid operand for instruction
|
||||||
|
// 64: error: invalid operand for instruction
|
||||||
|
cmppd $256, %xmm0, %xmm0
|
||||||
|
|
Loading…
Reference in New Issue