From 41f6259a4b54d2dc58a4040e942b37f00d306b7b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 29 Apr 2008 04:29:54 +0000 Subject: [PATCH] add support for multiple return values in inline asm. This is a step towards PR2094. It now compiles the attached .ll file to: _sad16_sse2: movslq %ecx, %rax ## InlineAsm Start %ecx %rdx %rax %rax %r8d %rdx %rsi ## InlineAsm End ## InlineAsm Start set %eax ## InlineAsm End ret which is pretty decent for a 3 output, 4 input asm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50386 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 31 ++++++++++++------- test/CodeGen/X86/inline-asm-mrv.ll | 17 ++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 test/CodeGen/X86/inline-asm-mrv.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2d65a331457..a0deb8151e6 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -176,6 +176,15 @@ namespace { } } + /// append - Add the specified values to this one. + void append(const RegsForValue &RHS) { + TLI = RHS.TLI; + ValueVTs.append(RHS.ValueVTs.begin(), RHS.ValueVTs.end()); + RegVTs.append(RHS.RegVTs.begin(), RHS.RegVTs.end()); + Regs.append(RHS.Regs.begin(), RHS.Regs.end()); + } + + /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from /// this value and returns the result as a ValueVTs value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. @@ -3754,7 +3763,6 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, bool HasEarlyClobber, } // Otherwise, we couldn't allocate enough registers for this. - return; } @@ -3938,7 +3946,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // Loop over all of the inputs, copying the operand values into the // appropriate registers and processing the output regs. RegsForValue RetValRegs; - + // IndirectStoresToEmit - The set of stores to emit after the inline asm node. std::vector > IndirectStoresToEmit; @@ -3970,15 +3978,16 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { exit(1); } - if (!OpInfo.isIndirect) { - // This is the result value of the call. - assert(RetValRegs.Regs.empty() && - "Cannot have multiple output constraints yet!"); - assert(CS.getType() != Type::VoidTy && "Bad inline asm!"); - RetValRegs = OpInfo.AssignedRegs; - } else { + // If this is an indirect operand, store through the pointer after the + // asm. + if (OpInfo.isIndirect) { IndirectStoresToEmit.push_back(std::make_pair(OpInfo.AssignedRegs, OpInfo.CallOperandVal)); + } else { + // This is the result value of the call. + assert(CS.getType() != Type::VoidTy && "Bad inline asm!"); + // Concatenate this output onto the outputs list. + RetValRegs.append(OpInfo.AssignedRegs); } // Add information to the INLINEASM node to know that this register is @@ -4115,9 +4124,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // width/num elts. Make sure to convert it to the right type with // bit_convert. if (MVT::isVector(Val.getValueType())) { - const VectorType *VTy = cast(CS.getType()); - MVT::ValueType DesiredVT = TLI.getValueType(VTy); - + MVT::ValueType DesiredVT = TLI.getValueType(CS.getType()); Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val); } diff --git a/test/CodeGen/X86/inline-asm-mrv.ll b/test/CodeGen/X86/inline-asm-mrv.ll new file mode 100644 index 00000000000..1d83a16ef21 --- /dev/null +++ b/test/CodeGen/X86/inline-asm-mrv.ll @@ -0,0 +1,17 @@ +; PR2094 +; RUN: llvm-as < %s | llc -march=x86-64 | grep movslq +; RUN: llvm-as < %s | llc -march=x86-64 | not grep movq + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin8" + +define i32 @sad16_sse2(i8* %v, i8* %blk2, i8* %blk1, i32 %stride, i32 %h) nounwind { +entry: + %tmp12 = sext i32 %stride to i64 ; [#uses=1] + %mrv = call {i32, i8*, i8*} asm sideeffect "$0 $1 $2 $3 $4 $5 $6", + "=r,=r,=r,r,r,r,r"( i64 %tmp12, i32 %h, i8* %blk1, i8* %blk2 ) nounwind + %tmp6 = getresult {i32, i8*, i8*} %mrv, 0 + %tmp7 = call i32 asm sideeffect "set $0", + "=r,~{dirflag},~{fpsr},~{flags}"( ) nounwind + ret i32 %tmp7 +} -- 2.34.1