diff options
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 11 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.td | 21 |
3 files changed, 29 insertions, 7 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index b5cc14e56f..0e36b68061 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -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. diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 221f29fa72..2348191eba 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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; } diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 5228b76ea5..4ddec00500 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -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, |