[llvm-branch-commits] [llvm-branch] r104498 - in /llvm/branches/Apple/whitney: lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.td test/MC/AsmParser/X86/x86_64-imm-widths.s

Daniel Dunbar daniel at zuster.org
Mon May 24 08:16:47 PDT 2010


Author: ddunbar
Date: Mon May 24 10:16:47 2010
New Revision: 104498

URL: http://llvm.org/viewvc/llvm-project?rev=104498&view=rev
Log:
MC/X86: Subdivide immediates a bit more, so that we properly recognize immediates based on the width of the target instruction. For example: addw $0xFFFF, %ax should match the same as addw $-1, %ax but we used to match it to the longer encoding.

Added:
    llvm/branches/Apple/whitney/test/MC/AsmParser/X86/x86_64-imm-widths.s
Modified:
    llvm/branches/Apple/whitney/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/branches/Apple/whitney/lib/Target/X86/X86Instr64bit.td
    llvm/branches/Apple/whitney/lib/Target/X86/X86InstrInfo.td

Modified: llvm/branches/Apple/whitney/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/whitney/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=104498&r1=104497&r2=104498&view=diff
==============================================================================
--- llvm/branches/Apple/whitney/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/branches/Apple/whitney/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon May 24 10:16:47 2010
@@ -186,32 +186,71 @@
 
   bool isImm() const { return Kind == Immediate; }
   
-  bool isImmSExt8() const { 
-    // Accept immediates which fit in 8 bits when sign extended, and
-    // non-absolute immediates.
+  bool isImmSExti16i8() const {
     if (!isImm())
       return false;
 
-    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
-      int64_t Value = CE->getValue();
-      return Value == (int64_t) (int8_t) Value;
-    }
+    // 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;
 
-    return true;
+    // Otherwise, check the value is in a range that makes sense for this
+    // extension.
+    uint64_t Value = CE->getValue();
+    return ((                                  Value <= 0x000000000000007FULL)||
+            (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
+            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
   }
-  
-  bool isImmSExt32() const {
-    // Accept immediates which fit in 32 bits when sign extended, and
-    // non-absolute immediates.
+  bool isImmSExti32i8() const {
     if (!isImm())
       return false;
 
-    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
-      int64_t Value = CE->getValue();
-      return Value == (int64_t) (int32_t) Value;
-    }
+    // 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;
 
-    return true;
+    // Otherwise, check the value is in a range that makes sense for this
+    // extension.
+    uint64_t Value = CE->getValue();
+    return ((                                  Value <= 0x000000000000007FULL)||
+            (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
+            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
+  }
+  bool isImmSExti64i8() 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 <= 0x000000000000007FULL)||
+            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
+  }
+  bool isImmSExti64i32() 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 <= 0x000000007FFFFFFFULL)||
+            (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
   }
 
   bool isMem() const { return Kind == Memory; }
@@ -245,18 +284,6 @@
     addExpr(Inst, getImm());
   }
 
-  void addImmSExt8Operands(MCInst &Inst, unsigned N) const {
-    // FIXME: Support user customization of the render method.
-    assert(N == 1 && "Invalid number of operands!");
-    addExpr(Inst, getImm());
-  }
-
-  void addImmSExt32Operands(MCInst &Inst, unsigned N) const {
-    // FIXME: Support user customization of the render method.
-    assert(N == 1 && "Invalid number of operands!");
-    addExpr(Inst, getImm());
-  }
-
   void addMemOperands(MCInst &Inst, unsigned N) const {
     assert((N == 5) && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));

Modified: llvm/branches/Apple/whitney/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/whitney/lib/Target/X86/X86Instr64bit.td?rev=104498&r1=104497&r2=104498&view=diff
==============================================================================
--- llvm/branches/Apple/whitney/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/branches/Apple/whitney/lib/Target/X86/X86Instr64bit.td Mon May 24 10:16:47 2010
@@ -19,7 +19,7 @@
 
 // 64-bits but only 32 bits are significant.
 def i64i32imm  : Operand<i64> {
-  let ParserMatchClass = ImmSExt32AsmOperand;
+  let ParserMatchClass = ImmSExti64i32AsmOperand;
 }
 
 // 64-bits but only 32 bits are significant, and those bits are treated as being
@@ -32,7 +32,7 @@
 
 // 64-bits but only 8 bits are significant.
 def i64i8imm   : Operand<i64> {
-  let ParserMatchClass = ImmSExt8AsmOperand;
+  let ParserMatchClass = ImmSExti64i8AsmOperand;
 }
 
 // Special i64mem for addresses of load folding tail calls. These are not

Modified: llvm/branches/Apple/whitney/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/whitney/lib/Target/X86/X86InstrInfo.td?rev=104498&r1=104497&r2=104498&view=diff
==============================================================================
--- llvm/branches/Apple/whitney/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/branches/Apple/whitney/lib/Target/X86/X86InstrInfo.td Mon May 24 10:16:47 2010
@@ -270,24 +270,49 @@
   let PrintMethod = "printSSECC";
 }
 
-def ImmSExt32AsmOperand : AsmOperandClass {
-  let Name = "ImmSExt32";
+class ImmSExtAsmOperandClass : AsmOperandClass {
   let SuperClasses = [ImmAsmOperand];
+  let RenderMethod = "addImmOperands";
 }
 
-def ImmSExt8AsmOperand : AsmOperandClass {
-  let Name = "ImmSExt8";
-  let SuperClasses = [ImmSExt32AsmOperand];
+// 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.
+//
+// The strange ranges come from the fact that the assembler always works with
+// 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
+// (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
+
+// [0, 0x7FFFFFFF]                                            | [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
+def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
+  let Name = "ImmSExti64i32";
+}
+
+// [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
+def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
+  let Name = "ImmSExti16i8";
+  let SuperClasses = [ImmSExti64i32AsmOperand];
+}
+
+// [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
+def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
+  let Name = "ImmSExti32i8";
+}
+
+// [0, 0x0000007F]                                            | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
+def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
+  let Name = "ImmSExti64i8";
+  let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand, ImmSExti64i32AsmOperand];
 }
 
 // A couple of more descriptive operand definitions.
 // 16-bits but only 8 bits are significant.
 def i16i8imm  : Operand<i16> {
-  let ParserMatchClass = ImmSExt8AsmOperand;
+  let ParserMatchClass = ImmSExti16i8AsmOperand;
 }
 // 32-bits but only 8 bits are significant.
 def i32i8imm  : Operand<i32> {
-  let ParserMatchClass = ImmSExt8AsmOperand;
+  let ParserMatchClass = ImmSExti32i8AsmOperand;
 }
 
 //===----------------------------------------------------------------------===//

Added: llvm/branches/Apple/whitney/test/MC/AsmParser/X86/x86_64-imm-widths.s
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/whitney/test/MC/AsmParser/X86/x86_64-imm-widths.s?rev=104498&view=auto
==============================================================================
--- llvm/branches/Apple/whitney/test/MC/AsmParser/X86/x86_64-imm-widths.s (added)
+++ llvm/branches/Apple/whitney/test/MC/AsmParser/X86/x86_64-imm-widths.s Mon May 24 10:16:47 2010
@@ -0,0 +1,105 @@
+// RUN: llvm-mc -triple x86_64- --show-encoding %s | FileCheck %s
+
+// CHECK: addb $0, %al
+// CHECK: encoding: [0x04,0x00]
+ 	addb $0x00, %al
+
+// CHECK: addb $127, %al
+// CHECK: encoding: [0x04,0x7f]
+ 	addb $0x7F, %al
+
+// CHECK: addb $128, %al
+// CHECK: encoding: [0x04,0x80]
+ 	addb $0x80, %al
+
+// CHECK: addb $255, %al
+// CHECK: encoding: [0x04,0xff]
+ 	addb $0xFF, %al
+
+// CHECK: addw $0, %ax
+// CHECK: encoding: [0x66,0x83,0xc0,0x00]
+ 	addw $0x0000, %ax
+
+// CHECK: addw $127, %ax
+// CHECK: encoding: [0x66,0x83,0xc0,0x7f]
+ 	addw $0x007F, %ax
+
+// CHECK: addw $65408, %ax
+// CHECK: encoding: [0x66,0x83,0xc0,0x80]
+ 	addw $0xFF80, %ax
+
+// CHECK: addw $65535, %ax
+// CHECK: encoding: [0x66,0x83,0xc0,0xff]
+	addw $0xFFFF, %ax
+
+// CHECK: addl $0, %eax
+// CHECK: encoding: [0x83,0xc0,0x00]
+ 	addl $0x00000000, %eax
+
+// CHECK: addl $127, %eax
+// CHECK: encoding: [0x83,0xc0,0x7f]
+ 	addl $0x0000007F, %eax
+
+// CHECK: addl $65408, %eax
+// CHECK: encoding: [0x05,0x80,0xff,0x00,0x00]
+ 	addl $0xFF80, %eax
+
+// CHECK: addl $65535, %eax
+// CHECK: encoding: [0x05,0xff,0xff,0x00,0x00]
+	addl $0xFFFF, %eax
+
+// CHECK: addl $4294967168, %eax
+// CHECK: encoding: [0x83,0xc0,0x80]
+ 	addl $0xFFFFFF80, %eax
+
+// CHECK: addl $4294967295, %eax
+// CHECK: encoding: [0x83,0xc0,0xff]
+ 	addl $0xFFFFFFFF, %eax
+
+// CHECK: addq $0, %rax
+// CHECK: encoding: [0x48,0x83,0xc0,0x00]
+ 	addq $0x0000000000000000, %rax
+
+// CHECK: addq $127, %rax
+// CHECK: encoding: [0x48,0x83,0xc0,0x7f]
+ 	addq $0x000000000000007F, %rax
+
+// CHECK: addq $-128, %rax
+// CHECK: encoding: [0x48,0x83,0xc0,0x80]
+ 	addq $0xFFFFFFFFFFFFFF80, %rax
+
+// CHECK: addq $-1, %rax
+// CHECK: encoding: [0x48,0x83,0xc0,0xff]
+ 	addq $0xFFFFFFFFFFFFFFFF, %rax
+
+// CHECK: addq $0, %rax
+// CHECK: encoding: [0x48,0x83,0xc0,0x00]
+ 	addq $0x0000000000000000, %rax
+
+// CHECK: addq $65408, %rax
+// CHECK: encoding: [0x48,0x05,0x80,0xff,0x00,0x00]
+ 	addq $0xFF80, %rax
+
+// CHECK: addq $65535, %rax
+// CHECK: encoding: [0x48,0x05,0xff,0xff,0x00,0x00]
+	addq $0xFFFF, %rax
+
+// CHECK: movq $4294967168, %rax
+// CHECK: encoding: [0x48,0xb8,0x80,0xff,0xff,0xff,0x00,0x00,0x00,0x00]
+ 	movq $0xFFFFFF80, %rax
+
+// CHECK: movq $4294967295, %rax
+// CHECK: encoding: [0x48,0xb8,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00]
+        movq $0xFFFFFFFF, %rax
+
+// CHECK: addq $2147483647, %rax
+// CHECK: encoding: [0x48,0x05,0xff,0xff,0xff,0x7f]
+ 	addq $0x000000007FFFFFFF, %rax
+
+// CHECK: addq $-2147483648, %rax
+// CHECK: encoding: [0x48,0x05,0x00,0x00,0x00,0x80]
+	addq $0xFFFFFFFF80000000, %rax
+
+// CHECK: addq $-256, %rax
+// CHECK: encoding: [0x48,0x05,0x00,0xff,0xff,0xff]
+ 	addq $0xFFFFFFFFFFFFFF00, %rax





More information about the llvm-branch-commits mailing list