aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2009-02-12 20:58:09 +0000
committerDale Johannesen <dalej@apple.com>2009-02-12 20:58:09 +0000
commit78e3e521cd90e5f6382c14b6e4d809fb59610ed6 (patch)
treeab8207e9c0143230e527faae7e0ddb06b0c613fc
parenta971b294253cb848c0a640185f26459978c9ba41 (diff)
downloadexternal_llvm-78e3e521cd90e5f6382c14b6e4d809fb59610ed6.zip
external_llvm-78e3e521cd90e5f6382c14b6e4d809fb59610ed6.tar.gz
external_llvm-78e3e521cd90e5f6382c14b6e4d809fb59610ed6.tar.bz2
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
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp7
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp33
-rw-r--r--test/CodeGen/X86/2009-02-12-InlineAsm-nieZ-constraints.ll18
3 files changed, 55 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index fce57f9..909789b 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -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;
}
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index a3c67e0..46fe216 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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;
}
diff --git a/test/CodeGen/X86/2009-02-12-InlineAsm-nieZ-constraints.ll b/test/CodeGen/X86/2009-02-12-InlineAsm-nieZ-constraints.ll
new file mode 100644
index 0000000..ddd15f7
--- /dev/null
+++ b/test/CodeGen/X86/2009-02-12-InlineAsm-nieZ-constraints.ll
@@ -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
+}