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.

llvm-svn: 50386
This commit is contained in:
Chris Lattner 2008-04-29 04:29:54 +00:00
parent 11b98b6612
commit f9a49c4322
2 changed files with 36 additions and 12 deletions

View File

@ -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<std::pair<RegsForValue, Value*> > 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<VectorType>(CS.getType());
MVT::ValueType DesiredVT = TLI.getValueType(VTy);
MVT::ValueType DesiredVT = TLI.getValueType(CS.getType());
Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val);
}

View File

@ -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 ; <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
}