@@ -2592,11 +2592,8 @@ void CWriter::lowerIntrinsics(Function &F) {
2592
2592
}
2593
2593
2594
2594
void CWriter::visitCallInst (CallInst &I) {
2595
- // check if we have inline asm
2596
- if (isInlineAsm (I)) {
2597
- visitInlineAsm (I);
2598
- return ;
2599
- }
2595
+ if (isa<InlineAsm>(I.getOperand (0 )))
2596
+ return visitInlineAsm (I);
2600
2597
2601
2598
bool WroteCallee = false ;
2602
2599
@@ -2914,53 +2911,64 @@ void CWriter::visitInlineAsm(CallInst &CI) {
2914
2911
InlineAsm* as = cast<InlineAsm>(CI.getOperand (0 ));
2915
2912
std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints ();
2916
2913
std::vector<std::pair<std::string, Value*> > Input;
2917
- std::vector<std::pair<std::string, Value*> > Output;
2914
+ std::vector<std::pair<std::string, std::pair< Value*, int > > > Output;
2918
2915
std::string Clobber;
2919
- int count = CI.getType () == Type::VoidTy ? 1 : 0 ;
2916
+ unsigned ValueCount = 0 ;
2917
+
2918
+ std::vector<std::pair<Value*, int > > ResultVals;
2919
+ if (CI.getType () == Type::VoidTy)
2920
+ ;
2921
+ else if (const StructType *ST = dyn_cast<StructType>(CI.getType ())) {
2922
+ for (unsigned i = 0 , e = ST->getNumElements (); i != e; ++i)
2923
+ ResultVals.push_back (std::make_pair (&CI, (int )i));
2924
+ } else {
2925
+ ResultVals.push_back (std::make_pair (&CI, -1 ));
2926
+ }
2927
+
2920
2928
for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin (),
2921
2929
E = Constraints.end (); I != E; ++I) {
2922
2930
assert (I->Codes .size () == 1 && " Too many asm constraint codes to handle" );
2923
- std::string c =
2924
- InterpretASMConstraint (*I);
2925
- switch (I->Type ) {
2926
- default :
2927
- assert (0 && " Unknown asm constraint" );
2928
- break ;
2931
+ std::string C = InterpretASMConstraint (*I);
2932
+ if (C.empty ()) continue ;
2933
+
2934
+ switch (I->Type ) {
2935
+ default : assert (0 && " Unknown asm constraint" );
2929
2936
case InlineAsm::isInput: {
2930
- if (c.size ()) {
2931
- Input.push_back (std::make_pair (c, count ? CI.getOperand (count) : &CI));
2932
- ++count; // consume arg
2933
- }
2937
+ assert (ValueCount >= ResultVals.size () && " Input can't refer to result" );
2938
+ Value *V = CI.getOperand (ValueCount-ResultVals.size ());
2939
+ Input.push_back (std::make_pair (C, V));
2934
2940
break ;
2935
2941
}
2936
2942
case InlineAsm::isOutput: {
2937
- if (c.size ()) {
2938
- Output.push_back (std::make_pair (" =" +((I->isEarlyClobber ? " &" : " " )+c),
2939
- count ? CI.getOperand (count) : &CI));
2940
- ++count; // consume arg
2941
- }
2942
- break ;
2943
- }
2944
- case InlineAsm::isClobber: {
2945
- if (c.size ())
2946
- Clobber += " ,\" " + c + " \" " ;
2943
+ std::pair<Value*, int > V;
2944
+ if (ValueCount < ResultVals.size ())
2945
+ V = ResultVals[ValueCount];
2946
+ else
2947
+ V = std::make_pair (CI.getOperand (ValueCount-ResultVals.size ()), -1 );
2948
+ Output.push_back (std::make_pair (" =" +((I->isEarlyClobber ? " &" : " " )+C),
2949
+ V));
2947
2950
break ;
2948
2951
}
2952
+ case InlineAsm::isClobber:
2953
+ Clobber += " ,\" " + C + " \" " ;
2954
+ continue ; // Not an actual argument.
2949
2955
}
2956
+ ++ValueCount; // Consumes an argument.
2950
2957
}
2951
2958
2952
- // fix up the asm string for gcc
2959
+ // Fix up the asm string for gcc.
2953
2960
std::string asmstr = gccifyAsm (as->getAsmString ());
2954
2961
2955
2962
Out << " __asm__ volatile (\" " << asmstr << " \"\n " ;
2956
2963
Out << " :" ;
2957
- for (std::vector<std::pair<std::string, Value*> >::iterator I =Output.begin (),
2958
- E = Output.end (); I != E; ++I) {
2959
- Out << " \" " << I->first << " \" (" ;
2960
- writeOperandRaw (I->second );
2964
+ for (unsigned i = 0 , e = Output.size (); i != e; ++i) {
2965
+ if (i)
2966
+ Out << " , " ;
2967
+ Out << " \" " << Output[i].first << " \" (" ;
2968
+ writeOperandRaw (Output[i].second .first );
2969
+ if (Output[i].second .second != -1 )
2970
+ Out << " .field" << Output[i].second .second ; // Multiple retvals.
2961
2971
Out << " )" ;
2962
- if (I + 1 != E)
2963
- Out << " ," ;
2964
2972
}
2965
2973
Out << " \n :" ;
2966
2974
for (std::vector<std::pair<std::string, Value*> >::iterator I = Input.begin (),
0 commit comments