diff options
author | Dale Johannesen <dalej@apple.com> | 2009-02-12 20:58:09 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2009-02-12 20:58:09 +0000 |
commit | 78e3e521cd90e5f6382c14b6e4d809fb59610ed6 (patch) | |
tree | ab8207e9c0143230e527faae7e0ddb06b0c613fc | |
parent | a971b294253cb848c0a640185f26459978c9ba41 (diff) | |
download | external_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.cpp | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 33 | ||||
-rw-r--r-- | test/CodeGen/X86/2009-02-12-InlineAsm-nieZ-constraints.ll | 18 |
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 +} |