[llvm-commits] [llvm] r136287 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrSSE.td test/MC/X86/x86-32-avx.s test/MC/X86/x86-32-coverage.s utils/TableGen/EDEmitter.cpp utils/TableGen/X86RecognizableInstr.cpp

Kevin Enderby enderby at apple.com
Wed Jul 27 16:01:50 PDT 2011


Author: enderby
Date: Wed Jul 27 18:01:50 2011
New Revision: 136287

URL: http://llvm.org/viewvc/llvm-project?rev=136287&view=rev
Log:
Fix llvm-mc handing of x86 instructions that take 8-bit unsigned immediates.

llvm-mc gives an "invalid operand" error for instructions that take an unsigned
immediate which have the high bit set such as:
    pblendw $0xc5, %xmm2, %xmm1
llvm-mc treats all x86 immediates as signed values and range checks them.
A small number of x86 instructions use the imm8 field as a set of bits.
This change only changes those instructions and where the high bit is not
ignored.  The others remain unchanged.

Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86InstrSSE.td
    llvm/trunk/test/MC/X86/x86-32-avx.s
    llvm/trunk/test/MC/X86/x86-32-coverage.s
    llvm/trunk/utils/TableGen/EDEmitter.cpp
    llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Wed Jul 27 18:01:50 2011
@@ -226,6 +226,21 @@
             (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
             (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
   }
+  bool isImmZExtu32u8() const {
+    if (!isImm())
+      return false;
+
+    // If this isn't a constant expr, just assume it fits and let relaxation
+    // handle it.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE)
+      return true;
+
+    // Otherwise, check the value is in a range that makes sense for this
+    // extension.
+    uint64_t Value = CE->getValue();
+    return (Value <= 0x00000000000000FFULL);
+  }
   bool isImmSExti64i8() const {
     if (!isImm())
       return false;

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Jul 27 18:01:50 2011
@@ -331,6 +331,11 @@
   let RenderMethod = "addImmOperands";
 }
 
+class ImmZExtAsmOperandClass : AsmOperandClass {
+  let SuperClasses = [ImmAsmOperand];
+  let RenderMethod = "addImmOperands";
+}
+
 // Sign-extended immediate classes. We don't need to define the full lattice
 // here because there is no instruction with an ambiguity between ImmSExti64i32
 // and ImmSExti32i8.
@@ -358,6 +363,12 @@
   let Name = "ImmSExti32i8";
 }
 
+// [0, 0x000000FF]
+def ImmZExtu32u8AsmOperand : ImmZExtAsmOperandClass {
+  let Name = "ImmZExtu32u8";
+}
+
+
 // [0, 0x0000007F]                                            |
 //   [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
@@ -377,6 +388,11 @@
   let ParserMatchClass = ImmSExti32i8AsmOperand;
   let OperandType = "OPERAND_IMMEDIATE";
 }
+// 32-bits but only 8 bits are significant, and those 8 bits are unsigned.
+def u32u8imm  : Operand<i32> {
+  let ParserMatchClass = ImmZExtu32u8AsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
+}
 
 // 64-bits but only 32 bits are significant.
 def i64i32imm  : Operand<i64> {

Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Jul 27 18:01:50 2011
@@ -4298,7 +4298,7 @@
 // in the target vector.
 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
-      (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
+      (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
       !if(Is2Addr,
         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
         !strconcat(asm,
@@ -4307,7 +4307,7 @@
         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
       OpSize;
   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
-      (ins VR128:$src1, f32mem:$src2, i32i8imm:$src3),
+      (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
       !if(Is2Addr,
         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
         !strconcat(asm,
@@ -4721,7 +4721,7 @@
                  X86MemOperand x86memop, bit Is2Addr = 1> {
   let isCommutable = 1 in
   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
-        (ins RC:$src1, RC:$src2, i32i8imm:$src3),
+        (ins RC:$src1, RC:$src2, u32u8imm:$src3),
         !if(Is2Addr,
             !strconcat(OpcodeStr,
                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
@@ -4730,7 +4730,7 @@
         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
         OpSize;
   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
-        (ins RC:$src1, x86memop:$src2, i32i8imm:$src3),
+        (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
         !if(Is2Addr,
             !strconcat(OpcodeStr,
                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),

Modified: llvm/trunk/test/MC/X86/x86-32-avx.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-32-avx.s?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-32-avx.s (original)
+++ llvm/trunk/test/MC/X86/x86-32-avx.s Wed Jul 27 18:01:50 2011
@@ -3281,3 +3281,25 @@
 // CHECK: encoding: [0xc4,0xe3,0x51,0x44,0x18,0x11]
           vpclmulqdq  $17, (%eax), %xmm5, %xmm3
 
+// rdar://9795008
+// These instructions take a mask not an 8-bit sign extended value.
+// CHECK: vblendps $129, %ymm2, %ymm5, %ymm1
+          vblendps $0x81, %ymm2, %ymm5, %ymm1
+// CHECK: vblendps $129, (%eax), %ymm5, %ymm1
+          vblendps $0x81, (%eax), %ymm5, %ymm1
+// CHECK: vblendpd $129, %ymm2, %ymm5, %ymm1
+          vblendpd $0x81, %ymm2, %ymm5, %ymm1
+// CHECK: vblendpd $129, (%eax), %ymm5, %ymm1
+          vblendpd $0x81, (%eax), %ymm5, %ymm1
+// CHECK: vpblendw $129, %xmm2, %xmm5, %xmm1
+          vpblendw $0x81, %xmm2, %xmm5, %xmm1
+// CHECK: vmpsadbw $129, %xmm2, %xmm5, %xmm1
+          vmpsadbw $0x81, %xmm2, %xmm5, %xmm1
+// CHECK: vdpps $129, %ymm2, %ymm5, %ymm1
+          vdpps $0x81, %ymm2, %ymm5, %ymm1
+// CHECK: vdpps $129, (%eax), %ymm5, %ymm1
+          vdpps $0x81, (%eax), %ymm5, %ymm1
+// CHECK: vdppd $129, %xmm2, %xmm5, %xmm1
+          vdppd $0x81, %xmm2, %xmm5, %xmm1
+// CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1
+          vinsertps $0x81, %xmm3, %xmm2, %xmm1

Modified: llvm/trunk/test/MC/X86/x86-32-coverage.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-32-coverage.s?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-32-coverage.s (original)
+++ llvm/trunk/test/MC/X86/x86-32-coverage.s Wed Jul 27 18:01:50 2011
@@ -19575,3 +19575,20 @@
             blendvps (%rax), %xmm1
 // CHECK:   blendvps	%xmm2, %xmm1    # encoding: [0x66,0x0f,0x38,0x14,0xca]
             blendvps %xmm2, %xmm1
+
+// rdar://9795008
+// These instructions take a mask not an 8-bit sign extended value.
+// CHECK: blendps $129, %xmm2, %xmm1
+          blendps $0x81, %xmm2, %xmm1
+// CHECK: blendpd $129, %xmm2, %xmm1
+          blendpd $0x81, %xmm2, %xmm1
+// CHECK: pblendw $129, %xmm2, %xmm1
+          pblendw $0x81, %xmm2, %xmm1
+// CHECK: mpsadbw $129, %xmm2, %xmm1
+          mpsadbw $0x81, %xmm2, %xmm1
+// CHECK: dpps $129, %xmm2, %xmm1
+          dpps $0x81, %xmm2, %xmm1
+// CHECK: dppd $129, %xmm2, %xmm1
+          dppd $0x81, %xmm2, %xmm1
+// CHECK: insertps $129, %xmm2, %xmm1
+          insertps $0x81, %xmm2, %xmm1

Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/EDEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/EDEmitter.cpp Wed Jul 27 18:01:50 2011
@@ -279,6 +279,7 @@
   IMM("i16i8imm");
   IMM("i32imm");
   IMM("i32i8imm");
+  IMM("u32u8imm");
   IMM("i64imm");
   IMM("i64i8imm");
   IMM("i64i32imm");

Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=136287&r1=136286&r2=136287&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Wed Jul 27 18:01:50 2011
@@ -984,6 +984,7 @@
   TYPE("i32mem",              TYPE_Mv)
   TYPE("i32imm",              TYPE_IMMv)
   TYPE("i32i8imm",            TYPE_IMM32)
+  TYPE("u32u8imm",            TYPE_IMM32)
   TYPE("GR32",                TYPE_Rv)
   TYPE("i64mem",              TYPE_Mv)
   TYPE("i64i32imm",           TYPE_IMM64)
@@ -1044,6 +1045,7 @@
     ENCODING("i16imm",        ENCODING_IW)
   }
   ENCODING("i32i8imm",        ENCODING_IB)
+  ENCODING("u32u8imm",        ENCODING_IB)
   ENCODING("SSECC",           ENCODING_IB)
   ENCODING("i16imm",          ENCODING_Iv)
   ENCODING("i16i8imm",        ENCODING_IB)





More information about the llvm-commits mailing list