Support x86 "eiz" and "riz" pseudo index registers in the assembler.
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Sat, 24 Jul 2010 00:06:39 +0000 (00:06 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Sat, 24 Jul 2010 00:06:39 +0000 (00:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109295 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86RegisterInfo.cpp
lib/Target/X86/X86RegisterInfo.td
test/MC/AsmParser/X86/x86_32-avx-encoding.s
test/MC/AsmParser/X86/x86_32-encoding.s
test/MC/AsmParser/X86/x86_64-avx-encoding.s
test/MC/AsmParser/X86/x86_64-encoding.s

index 014708c62a61b1f42c2c363112b1e9069b2df987..981245d124d7d241b4e31654edf2422af783a1b8 100644 (file)
@@ -384,6 +384,12 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
   // validation later, so maybe there is no need for this here.
   RegNo = MatchRegisterName(Tok.getString());
 
+  // FIXME: This should be done using Requires<In32BitMode> and
+  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
+  // can be also checked.
+  if (RegNo == X86::RIZ && !Is64Bit)
+    return Error(Tok.getLoc(), "riz register in 64-bit mode only");
+
   // Parse %st(1) and "%st" as "%st(0)"
   if (RegNo == 0 && Tok.getString() == "st") {
     RegNo = X86::ST0;
@@ -459,6 +465,10 @@ X86Operand *X86ATTAsmParser::ParseOperand() {
     unsigned RegNo;
     SMLoc Start, End;
     if (ParseRegister(RegNo, Start, End)) return 0;
+    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
+      Error(Start, "eiz and riz can only be used as index registers");
+      return 0;
+    }
 
     // If this is a segment register followed by a ':', then this is the start
     // of a memory reference, otherwise this is a normal register reference.
@@ -542,6 +552,10 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
   if (getLexer().is(AsmToken::Percent)) {
     SMLoc L;
     if (ParseRegister(BaseReg, L, L)) return 0;
+    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
+      Error(L, "eiz and riz can only be used as index registers");
+      return 0;
+    }
   }
 
   if (getLexer().is(AsmToken::Comma)) {
@@ -552,7 +566,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
     // correctly.
     //
     // Not that even though it would be completely consistent to support syntax
-    // like "1(%eax,,1)", the assembler doesn't.
+    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
     if (getLexer().is(AsmToken::Percent)) {
       SMLoc L;
       if (ParseRegister(IndexReg, L, L)) return 0;
index 945c35922b50619df03209741c5f653d45d4eb9b..9fd41fdbd5bff9634772d2e1603aaab314bf342c 100644 (file)
@@ -193,6 +193,12 @@ unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
   case X86::DR7:
     return 7;
 
+  // Pseudo index registers are equivalent to a "none"
+  // scaled index (See Intel Manual 2A, table 2-3)
+  case X86::EIZ:
+  case X86::RIZ:
+    return 4;
+
   default:
     assert(isVirtualRegister(RegNo) && "Unknown physical register!");
     llvm_unreachable("Register allocator hasn't allocated reg correctly yet!");
index 6251b3c10f441eee29e23a5b474cdb2a6633b1d1..176e87812d21706d9c76a58c8e60af4ab0c72646 100644 (file)
@@ -241,6 +241,10 @@ let Namespace = "X86" in {
   def CR6 : Register<"cr6">;
   def CR7 : Register<"cr7">;
   def CR8 : Register<"cr8">;
+
+  // Pseudo index registers
+  def EIZ : Register<"eiz">;
+  def RIZ : Register<"riz">;
 }
 
 
index afd5da99ccd755319335696f1ee667cc80d3b2f6..b7ade6670a0104e76a23249238c3bf3a830d088e 100644 (file)
 // CHECK: encoding: [0xc4,0xe2,0x7d,0x0e,0x10]
           vtestps  (%eax), %ymm2
 
+// CHECK: vblendvpd  %ymm0, 57005(%eax,%eiz), %ymm1, %ymm2
+// CHECK: encoding: [0xc4,0xe3,0x75,0x4b,0x94,0x20,0xad,0xde,0x00,0x00,0x00]
+          vblendvpd  %ymm0, 0xdead(%eax,%eiz), %ymm1, %ymm2
+
index 9f5682d6d9591c9640b86d8a6b7508d9bbe846af..ef774239ffe84cd1cf5942557bad1017a8ee9797 100644 (file)
 // CHECK:  encoding: [0xde,0x1d,0xed,0x7e,0x00,0x00]
           ficomps 32493
 
+// CHECK: movl  57005(,%eiz), %ebx
+// CHECK: encoding: [0x8b,0x1c,0x25,0xad,0xde,0x00,0x00]
+          movl  57005(,%eiz), %ebx
+
+// CHECK: movl  48879(,%eiz), %eax
+// CHECK: encoding: [0x8b,0x04,0x25,0xef,0xbe,0x00,0x00]
+          movl  48879(,%eiz), %eax
+
+// CHECK: movl  -4(,%eiz,8), %eax
+// CHECK: encoding: [0x8b,0x04,0xe5,0xfc,0xff,0xff,0xff]
+          movl  -4(,%eiz,8), %eax
+
+// CHECK: movl  (%ecx,%eiz), %eax
+// CHECK: encoding: [0x8b,0x04,0x21]
+          movl  (%ecx,%eiz), %eax
+
+// CHECK: movl  (%ecx,%eiz,8), %eax
+// CHECK: encoding: [0x8b,0x04,0xe1]
+          movl  (%ecx,%eiz,8), %eax
+
index d168bbd825e23c758306a6fa5e812b7661a26eab..7a96bb5a2b4850870b11f8609e7771b763675ecc 100644 (file)
@@ -3312,3 +3312,7 @@ vdivpd  -4(%rcx,%rbx,8), %xmm10, %xmm11
 // CHECK: encoding: [0xc5,0xf9,0xd7,0xcc]
           vpmovmskb  %xmm4, %rcx
 
+// CHECK: vblendvpd  %ymm11, 57005(%rax,%riz), %ymm12, %ymm13
+// CHECK: encoding: [0xc4,0x63,0x1d,0x4b,0xac,0x20,0xad,0xde,0x00,0x00,0xb0]
+          vblendvpd  %ymm11, 0xdead(%rax,%riz), %ymm12, %ymm13
+
index 6fe6807f021a360fe277b8157bdc7a673461c29a..f45b0a23d5e81b8ad8d37769faf9f799cec67f38 100644 (file)
@@ -120,3 +120,23 @@ movd %mm1, %edx
 // CHECK:  fixup A - offset: 5, value: CPI1_0-4
 pshufb CPI1_0(%rip), %xmm1
 
+// CHECK: movq  57005(,%riz), %rbx
+// CHECK: encoding: [0x48,0x8b,0x1c,0x25,0xad,0xde,0x00,0x00]
+          movq  57005(,%riz), %rbx
+
+// CHECK: movq  48879(,%riz), %rax
+// CHECK: encoding: [0x48,0x8b,0x04,0x25,0xef,0xbe,0x00,0x00]
+          movq  48879(,%riz), %rax
+
+// CHECK: movq  -4(,%riz,8), %rax
+// CHECK: encoding: [0x48,0x8b,0x04,0xe5,0xfc,0xff,0xff,0xff]
+          movq  -4(,%riz,8), %rax
+
+// CHECK: movq  (%rcx,%riz), %rax
+// CHECK: encoding: [0x48,0x8b,0x04,0x21]
+          movq  (%rcx,%riz), %rax
+
+// CHECK: movq  (%rcx,%riz,8), %rax
+// CHECK: encoding: [0x48,0x8b,0x04,0xe1]
+          movq  (%rcx,%riz,8), %rax
+