mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-06 04:09:04 +00:00
Handle 'X' constraint in asm's better.
llvm-svn: 46485
This commit is contained in:
parent
86ff705c22
commit
f12104ce4b
@ -1006,6 +1006,11 @@ public:
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint,
|
||||
MVT::ValueType VT) const;
|
||||
|
||||
/// LowerXConstraint - try to replace an X constraint, which matches anything,
|
||||
/// with another that has more specific requirements based on the type of the
|
||||
/// corresponding operand.
|
||||
virtual void lowerXConstraint(MVT::ValueType ConstraintVT,
|
||||
std::string&) const;
|
||||
|
||||
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
|
||||
/// vector. If it is invalid, don't add anything to Ops.
|
||||
|
@ -1108,9 +1108,10 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
|
||||
// Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
|
||||
const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
|
||||
|
||||
// If this asmstr is empty, don't bother printing the #APP/#NOAPP markers.
|
||||
// If this asmstr is empty, just print the #APP/#NOAPP markers.
|
||||
// These are useful to see where empty asm's wound up.
|
||||
if (AsmStr[0] == 0) {
|
||||
O << "\n"; // Tab already printed, avoid double indenting next instr.
|
||||
O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3250,27 +3250,41 @@ void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) {
|
||||
if (Codes.size() == 1) { // Single-letter constraints ('r') are very common.
|
||||
ConstraintCode = *Current;
|
||||
ConstraintType = CurType;
|
||||
return;
|
||||
} else {
|
||||
unsigned CurGenerality = getConstraintGenerality(CurType);
|
||||
|
||||
// If we have multiple constraints, try to pick the most general one ahead
|
||||
// of time. This isn't a wonderful solution, but handles common cases.
|
||||
for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
|
||||
TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
|
||||
unsigned ThisGenerality = getConstraintGenerality(ThisType);
|
||||
if (ThisGenerality > CurGenerality) {
|
||||
// This constraint letter is more general than the previous one,
|
||||
// use it.
|
||||
CurType = ThisType;
|
||||
Current = &Codes[j];
|
||||
CurGenerality = ThisGenerality;
|
||||
}
|
||||
}
|
||||
|
||||
ConstraintCode = *Current;
|
||||
ConstraintType = CurType;
|
||||
}
|
||||
|
||||
unsigned CurGenerality = getConstraintGenerality(CurType);
|
||||
|
||||
// If we have multiple constraints, try to pick the most general one ahead
|
||||
// of time. This isn't a wonderful solution, but handles common cases.
|
||||
for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
|
||||
TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
|
||||
unsigned ThisGenerality = getConstraintGenerality(ThisType);
|
||||
if (ThisGenerality > CurGenerality) {
|
||||
// This constraint letter is more general than the previous one,
|
||||
// use it.
|
||||
CurType = ThisType;
|
||||
Current = &Codes[j];
|
||||
CurGenerality = ThisGenerality;
|
||||
|
||||
if (ConstraintCode == "X") {
|
||||
if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal))
|
||||
return;
|
||||
// This matches anything. Labels and constants we handle elsewhere
|
||||
// ('X' is the only thing that matches labels). Otherwise, try to
|
||||
// resolve it to something we know about by looking at the actual
|
||||
// operand type.
|
||||
std::string s = "";
|
||||
TLI.lowerXConstraint(ConstraintVT, s);
|
||||
if (s!="") {
|
||||
ConstraintCode = s;
|
||||
ConstraintType = TLI.getConstraintType(ConstraintCode);
|
||||
}
|
||||
}
|
||||
|
||||
ConstraintCode = *Current;
|
||||
ConstraintType = CurType;
|
||||
}
|
||||
|
||||
|
||||
@ -3492,7 +3506,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
|
||||
if (OpInfo.CallOperandVal) {
|
||||
if (isa<BasicBlock>(OpInfo.CallOperandVal))
|
||||
OpInfo.CallOperand =
|
||||
DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]);
|
||||
DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(
|
||||
OpInfo.CallOperandVal)]);
|
||||
else {
|
||||
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
|
||||
const Type *OpTy = OpInfo.CallOperandVal->getType();
|
||||
|
@ -1525,6 +1525,19 @@ TargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
return C_Unknown;
|
||||
}
|
||||
|
||||
/// LowerXConstraint - try to replace an X constraint, which matches anything,
|
||||
/// with another that has more specific requirements based on the type of the
|
||||
/// corresponding operand.
|
||||
void TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT,
|
||||
std::string& s) const {
|
||||
if (MVT::isInteger(ConstraintVT))
|
||||
s = "r";
|
||||
else if (MVT::isFloatingPoint(ConstraintVT))
|
||||
s = "f"; // works for many targets
|
||||
else
|
||||
s = "";
|
||||
}
|
||||
|
||||
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
|
||||
/// vector. If it is invalid, don't add anything to Ops.
|
||||
void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
|
||||
|
@ -5701,6 +5701,22 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
return TargetLowering::getConstraintType(Constraint);
|
||||
}
|
||||
|
||||
/// LowerXConstraint - try to replace an X constraint, which matches anything,
|
||||
/// with another that has more specific requirements based on the type of the
|
||||
/// corresponding operand.
|
||||
void X86TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT,
|
||||
std::string& s) const {
|
||||
if (MVT::isFloatingPoint(ConstraintVT)) {
|
||||
if (Subtarget->hasSSE2())
|
||||
s = "Y";
|
||||
else if (Subtarget->hasSSE1())
|
||||
s = "x";
|
||||
else
|
||||
s = "f";
|
||||
} else
|
||||
return TargetLowering::lowerXConstraint(ConstraintVT, s);
|
||||
}
|
||||
|
||||
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
|
||||
/// vector. If it is invalid, don't add anything to Ops.
|
||||
void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
|
||||
|
@ -366,6 +366,9 @@ namespace llvm {
|
||||
getRegClassForInlineAsmConstraint(const std::string &Constraint,
|
||||
MVT::ValueType VT) const;
|
||||
|
||||
virtual void lowerXConstraint(MVT::ValueType ConstraintVT,
|
||||
std::string&) const;
|
||||
|
||||
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
|
||||
/// vector. If it is invalid, don't add anything to Ops.
|
||||
virtual void LowerAsmOperandForConstraint(SDOperand Op,
|
||||
|
Loading…
x
Reference in New Issue
Block a user