Extend InlineAsm::C_Register to allow multiple specific registers

(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
This commit is contained in:
Dale Johannesen 2008-11-13 21:52:36 +00:00
parent 704bff9e6c
commit 330169fa3e
3 changed files with 29 additions and 7 deletions

View 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.

View 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;
}

View 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,