[SystemZ] Fix parsing of inline asm registers

GPR and FPR constraints like "{r2}" and "{f2}" weren't handled correctly
because the name-to-regno mapping depends on the value type and
(because of that) the internal names in RegStrings are not the
same as the AsmName.

CC constraints like "{cc}" didn't work either because there was no
associated register class.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186148 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Sandiford 2013-07-12 09:08:12 +00:00
parent 6cf3cfa0ab
commit 5e00954197
4 changed files with 49 additions and 8 deletions

View File

@ -386,6 +386,22 @@ getSingleConstraintMatchWeight(AsmOperandInfo &info,
return weight;
}
// Parse a "{tNNN}" register constraint for which the register type "t"
// has already been verified. MC is the class associated with "t" and
// Map maps 0-based register numbers to LLVM register numbers.
static std::pair<unsigned, const TargetRegisterClass *>
parseRegisterNumber(const std::string &Constraint,
const TargetRegisterClass *RC, const unsigned *Map) {
assert(*(Constraint.end()-1) == '}' && "Missing '}'");
if (isdigit(Constraint[2])) {
std::string Suffix(Constraint.data() + 2, Constraint.size() - 2);
unsigned Index = atoi(Suffix.c_str());
if (Index < 16 && Map[Index])
return std::make_pair(Map[Index], RC);
}
return std::make_pair(0u, static_cast<TargetRegisterClass*>(0));
}
std::pair<unsigned, const TargetRegisterClass *> SystemZTargetLowering::
getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const {
if (Constraint.size() == 1) {
@ -415,6 +431,32 @@ getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const {
return std::make_pair(0U, &SystemZ::FP32BitRegClass);
}
}
if (Constraint[0] == '{') {
// We need to override the default register parsing for GPRs and FPRs
// because the interpretation depends on VT. The internal names of
// the registers are also different from the external names
// (F0D and F0S instead of F0, etc.).
if (Constraint[1] == 'r') {
if (VT == MVT::i32)
return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass,
SystemZMC::GR32Regs);
if (VT == MVT::i128)
return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass,
SystemZMC::GR128Regs);
return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass,
SystemZMC::GR64Regs);
}
if (Constraint[1] == 'f') {
if (VT == MVT::f32)
return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass,
SystemZMC::FP32Regs);
if (VT == MVT::f128)
return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass,
SystemZMC::FP128Regs);
return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass,
SystemZMC::FP64Regs);
}
}
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
}

View File

@ -57,9 +57,6 @@ MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const {
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit())
return MCOperand();
return MCOperand::CreateReg(MO.getReg());
case MachineOperand::MO_Immediate:
@ -104,8 +101,8 @@ void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(Opcode);
for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
const MachineOperand &MO = MI->getOperand(I);
MCOperand MCOp = lowerOperand(MO);
if (MCOp.isValid())
OutMI.addOperand(MCOp);
// Ignore all implicit register operands.
if (!MO.isReg() || !MO.isImplicit())
OutMI.addOperand(lowerOperand(MO));
}
}

View File

@ -35,7 +35,7 @@ public:
// Lower MachineInstr MI to MCInst OutMI.
void lower(const MachineInstr *MI, MCInst &OutMI) const;
// Return an MCOperand for MO. Return an empty operand if MO is implicit.
// Return an MCOperand for MO.
MCOperand lowerOperand(const MachineOperand& MO) const;
// Return an MCOperand for MO, given that it equals Symbol + Offset.

View File

@ -147,5 +147,7 @@ defm FP128 : SystemZRegClass<"FP128", f128, 128, (add F0Q, F1Q, F4Q, F5Q,
// Other registers
//===----------------------------------------------------------------------===//
// The 2-bit condition code field of the PSW.
// The 2-bit condition code field of the PSW. Every register named in an
// inline asm needs a class associated with it.
def CC : SystemZReg<"cc">;
def CCRegs : RegisterClass<"SystemZ", [i32], 32, (add CC)>;