Arrange to print constants that match "n" and "i" constraints

in inline asm as signed (what gcc does).  Add partial support
for x86-specific "e" and "Z" constraints, with appropriate
signedness for printing.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64400 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2009-02-12 20:58:09 +00:00
parent a971b29425
commit 78e3e521cd
3 changed files with 55 additions and 3 deletions

View File

@ -2082,8 +2082,11 @@ void TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
if (C) { // just C, no GV.
// Simple constants are not allowed for 's'.
if (ConstraintLetter != 's') {
Ops.push_back(DAG.getTargetConstant(C->getAPIntValue(),
Op.getValueType()));
// gcc prints these as sign extended. Sign extend value to 64 bits
// now; without this it would get ZExt'd later in
// ScheduleDAGSDNodes::EmitNode, which is very generic.
Ops.push_back(DAG.getTargetConstant(C->getAPIntValue().getSExtValue(),
MVT::i64));
return;
}
}

View File

@ -8152,6 +8152,9 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
case 'y':
case 'Y':
return C_RegisterClass;
case 'e':
case 'Z':
return C_Other;
default:
break;
}
@ -8211,10 +8214,38 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
}
}
return;
case 'e': {
// 32-bit signed value
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
const ConstantInt *CI = C->getConstantIntValue();
if (CI->isValueValidForType(Type::Int32Ty, C->getSExtValue())) {
// Widen to 64 bits here to get it sign extended.
Result = DAG.getTargetConstant(C->getSExtValue(), MVT::i64);
break;
}
// FIXME gcc accepts some relocatable values here too, but only in certain
// memory models; it's complicated.
}
return;
}
case 'Z': {
// 32-bit unsigned value
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
const ConstantInt *CI = C->getConstantIntValue();
if (CI->isValueValidForType(Type::Int32Ty, C->getZExtValue())) {
Result = DAG.getTargetConstant(C->getZExtValue(), Op.getValueType());
break;
}
}
// FIXME gcc accepts some relocatable values here too, but only in certain
// memory models; it's complicated.
return;
}
case 'i': {
// Literal immediates are always ok.
if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op)) {
Result = DAG.getTargetConstant(CST->getZExtValue(), Op.getValueType());
// Widen to 64 bits here to get it sign extended.
Result = DAG.getTargetConstant(CST->getSExtValue(), MVT::i64);
break;
}

View File

@ -0,0 +1,18 @@
; RUN: llvm-as < %s | llc -march=x86 | grep {\$-81920} | count 3
; RUN: llvm-as < %s | llc -march=x86 | grep {\$4294885376} | count 1
; ModuleID = 'shant.c'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i386-apple-darwin9.6"
define void @f() nounwind {
entry:
call void asm sideeffect "foo $0", "n,~{dirflag},~{fpsr},~{flags}"(i32 -81920) nounwind
call void asm sideeffect "foo $0", "i,~{dirflag},~{fpsr},~{flags}"(i32 -81920) nounwind
call void asm sideeffect "foo $0", "e,~{dirflag},~{fpsr},~{flags}"(i32 -81920) nounwind
call void asm sideeffect "foo $0", "Z,~{dirflag},~{fpsr},~{flags}"(i64 4294885376) nounwind
br label %return
return: ; preds = %entry
ret void
}