Extend InlineAsm::C_Register to allow multiple specific registers
authorDale Johannesen <dalej@apple.com>
Thu, 13 Nov 2008 21:52:36 +0000 (21:52 +0000)
committerDale Johannesen <dalej@apple.com>
Thu, 13 Nov 2008 21:52:36 +0000 (21:52 +0000)
(actually, code already all worked, only the comment
changed).  Use this to implement 'A' constraint on x86.
Fixes PR 1779.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59266 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86RegisterInfo.td

index b5cc14e56f84f79c8ce7fc3c8b6c807cd22c87b7..0e36b6806175bfe85ce1a9a665b43ab5d32ba882 100644 (file)
@@ -1207,8 +1207,8 @@ public:
   //
   
   enum ConstraintType {
-    C_Register,            // Constraint represents a single register.
-    C_RegisterClass,       // Constraint represents one or more registers.
+    C_Register,            // Constraint represents specific register(s).
+    C_RegisterClass,       // Constraint represents any of register(s) in class.
     C_Memory,              // Memory constraint.
     C_Other,               // Something else.
     C_Unknown              // Unsupported constraint.
index 221f29fa728f2ab4f69314267caf5f2b429e926b..2348191ebaa7144c8f13e32ff80d56e939bc1556 100644 (file)
@@ -7542,6 +7542,7 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
   if (Constraint.size() == 1) {
     switch (Constraint[0]) {
     case 'A':
+      return C_Register;
     case 'f':
     case 'r':
     case 'R':
@@ -7671,10 +7672,6 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint,
     // FIXME: not handling fp-stack yet!
     switch (Constraint[0]) {      // GCC X86 Constraint Letters
     default: break;  // Unknown constraint letter
-    case 'A':   // EAX/EDX
-      if (VT == MVT::i32 || VT == MVT::i64)
-        return make_vector<unsigned>(X86::EAX, X86::EDX, 0);
-      break;
     case 'q':   // Q_REGS (GENERAL_REGS in 64-bit mode)
     case 'Q':   // Q_REGS
       if (VT == MVT::i32)
@@ -7762,7 +7759,11 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
       Res.first = X86::ST0;
       Res.second = X86::RFP80RegisterClass;
     }
-
+    // 'A' means EAX + EDX.
+    if (Constraint == "A") {
+      Res.first = X86::EAX;
+      Res.second = X86::GRADRegisterClass;
+    }
     return Res;
   }
 
index 5228b76ea5ed60725da04f6c0180fc64481002b2..4ddec00500f4e9dcae416a3c3f35b0380ca22faf 100644 (file)
@@ -440,6 +440,27 @@ def GR32_ : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> {
   let SubRegClassList = [GR8, GR16];
 }
 
+// A class to support the 'A' assembler constraint: EAX then EDX.
+def GRAD : RegisterClass<"X86", [i32], 32, [EAX, EDX]> {
+  let MethodProtos = [{
+    iterator allocation_order_begin(const MachineFunction &MF) const;
+    iterator allocation_order_end(const MachineFunction &MF) const;
+  }];
+  
+  let MethodBodies = [{
+     static const unsigned X86_GRAD_AO[] = {X86::EAX, X86::EDX};
+   GRADClass::iterator
+    GRADClass::allocation_order_begin(const MachineFunction &MF) const {
+      return X86_GRAD_AO;
+    }
+
+    GRADClass::iterator
+    GRADClass::allocation_order_end(const MachineFunction &MF) const {
+      return X86_GRAD_AO + (sizeof(X86_GRAD_AO) / sizeof(unsigned));
+    }
+  }];
+}
+
 // Scalar SSE2 floating point registers.
 def FR32 : RegisterClass<"X86", [f32], 32,
                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,