From f81b1f346a26e085bd08ca68620c9cac07d41cfa Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 21 Jan 2015 06:07:53 +0000 Subject: [PATCH] [x86] Add assembly parser bounds checking to the immediate value for cmpss/cmpsd/cmpps/cmppd. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226642 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParserCommon.h | 5 ++++ lib/Target/X86/AsmParser/X86Operand.h | 7 +++++ lib/Target/X86/X86InstrAVX512.td | 8 +++--- lib/Target/X86/X86InstrInfo.td | 26 ++++++++++++++----- lib/Target/X86/X86InstrSSE.td | 8 +++--- test/MC/X86/x86-32-avx.s | 12 +++++++++ test/MC/X86/x86_errors.s | 8 ++++++ 7 files changed, 60 insertions(+), 14 deletions(-) diff --git a/lib/Target/X86/AsmParser/X86AsmParserCommon.h b/lib/Target/X86/AsmParser/X86AsmParserCommon.h index 72aeeaac163..7610806c457 100644 --- a/lib/Target/X86/AsmParser/X86AsmParserCommon.h +++ b/lib/Target/X86/AsmParser/X86AsmParserCommon.h @@ -34,6 +34,11 @@ inline bool isImmSExti64i32Value(uint64_t Value) { (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); } +inline bool isImmUnsignedi8Value(uint64_t Value) { + return (( Value <= 0x00000000000000FFULL)|| + (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); +} + } // End of namespace llvm #endif diff --git a/lib/Target/X86/AsmParser/X86Operand.h b/lib/Target/X86/AsmParser/X86Operand.h index 6675d4dc045..ac4c0435720 100644 --- a/lib/Target/X86/AsmParser/X86Operand.h +++ b/lib/Target/X86/AsmParser/X86Operand.h @@ -187,6 +187,13 @@ struct X86Operand : public MCParsedAsmOperand { return isImmSExti64i32Value(CE->getValue()); } + bool isImmUnsignedi8() const { + if (!isImm()) return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + if (!CE) return false; + return isImmUnsignedi8Value(CE->getValue()); + } + bool isOffsetOf() const override { return OffsetOfLoc.getPointer(); } diff --git a/lib/Target/X86/X86InstrAVX512.td b/lib/Target/X86/X86InstrAVX512.td index 4809d7c650a..4dd91f464c5 100644 --- a/lib/Target/X86/X86InstrAVX512.td +++ b/lib/Target/X86/X86InstrAVX512.td @@ -1210,11 +1210,11 @@ multiclass avx512_cmp_scalar, EVEX_4V; let isAsmParserOnly = 1, hasSideEffects = 0 in { 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; let mayLoad = 1 in 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; } } @@ -1545,12 +1545,12 @@ multiclass avx512_cmp_packed; let mayLoad = 1 in 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, "\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>; } diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 64e4636b1ac..079b233bb64 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -609,6 +609,14 @@ def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass { 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. // 16-bits but only 8 bits are significant. def i16i8imm : Operand { @@ -627,6 +635,18 @@ def i64i32imm : Operand { let OperandType = "OPERAND_IMMEDIATE"; } +// 64-bits but only 8 bits are significant. +def i64i8imm : Operand { + let ParserMatchClass = ImmSExti64i8AsmOperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + +// Unsigned 8-bit immediate used by SSE/AVX instructions. +def u8imm : Operand { + let ParserMatchClass = ImmUnsignedi8AsmOperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + // 64-bits but only 32 bits are significant, and those bits are treated as being // pc relative. def i64i32imm_pcrel : Operand { @@ -635,12 +655,6 @@ def i64i32imm_pcrel : Operand { let OperandType = "OPERAND_PCREL"; } -// 64-bits but only 8 bits are significant. -def i64i8imm : Operand { - let ParserMatchClass = ImmSExti64i8AsmOperand; - let OperandType = "OPERAND_IMMEDIATE"; -} - def lea64_32mem : Operand { let PrintMethod = "printanymem"; let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm); diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 56d76839e15..b4bcd7756b5 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -2348,11 +2348,11 @@ multiclass sse12_cmp_scalar, Sched<[itins.Sched]>; let mayLoad = 1 in 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>, Sched<[itins.Sched.Folded, ReadAfterLd]>; } @@ -2502,11 +2502,11 @@ multiclass sse12_cmp_packed, Sched<[WriteFAdd]>; let mayLoad = 1 in 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>, Sched<[WriteFAddLd, ReadAfterLd]>; } diff --git a/test/MC/X86/x86-32-avx.s b/test/MC/X86/x86-32-avx.s index ec4abdbb2a8..5c702392a90 100644 --- a/test/MC/X86/x86-32-avx.s +++ b/test/MC/X86/x86-32-avx.s @@ -3351,3 +3351,15 @@ vdppd $0x81, %xmm2, %xmm5, %xmm1 // CHECK: vinsertps $129, %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 diff --git a/test/MC/X86/x86_errors.s b/test/MC/X86/x86_errors.s index 0b3bc7f4350..fa87ef676f3 100644 --- a/test/MC/X86/x86_errors.s +++ b/test/MC/X86/x86_errors.s @@ -50,3 +50,11 @@ outb al, 4 // 32: error: invalid segment register // 64: error: invalid segment register 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 -- 2.34.1