@@ -2936,10 +2936,6 @@ static std::string gccifyAsm(std::string asmstr) {
2936
2936
void CWriter::visitInlineAsm (CallInst &CI) {
2937
2937
InlineAsm* as = cast<InlineAsm>(CI.getOperand (0 ));
2938
2938
std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints ();
2939
- std::vector<std::pair<std::string, Value*> > Input;
2940
- std::vector<std::pair<std::string, std::pair<Value*, int > > > Output;
2941
- std::string Clobber;
2942
- unsigned ValueCount = 0 ;
2943
2939
2944
2940
std::vector<std::pair<Value*, int > > ResultVals;
2945
2941
if (CI.getType () == Type::VoidTy)
@@ -2951,61 +2947,103 @@ void CWriter::visitInlineAsm(CallInst &CI) {
2951
2947
ResultVals.push_back (std::make_pair (&CI, -1 ));
2952
2948
}
2953
2949
2950
+ // Fix up the asm string for gcc and emit it.
2951
+ Out << " __asm__ volatile (\" " << gccifyAsm (as->getAsmString ()) << " \"\n " ;
2952
+ Out << " :" ;
2953
+
2954
+ unsigned ValueCount = 0 ;
2955
+ bool IsFirst = true ;
2956
+
2957
+ // Convert over all the output constraints.
2954
2958
for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin (),
2955
- E = Constraints.end (); I != E; ++I) {
2959
+ E = Constraints.end (); I != E; ++I) {
2960
+
2961
+ if (I->Type != InlineAsm::isOutput) {
2962
+ ++ValueCount;
2963
+ continue ; // Ignore non-output constraints.
2964
+ }
2965
+
2956
2966
assert (I->Codes .size () == 1 && " Too many asm constraint codes to handle" );
2957
2967
std::string C = InterpretASMConstraint (*I);
2958
2968
if (C.empty ()) continue ;
2959
2969
2960
- switch (I->Type ) {
2961
- default : assert (0 && " Unknown asm constraint" );
2962
- case InlineAsm::isInput: {
2963
- assert (ValueCount >= ResultVals.size () && " Input can't refer to result" );
2964
- Value *V = CI.getOperand (ValueCount-ResultVals.size ()+1 );
2965
- Input.push_back (std::make_pair (C, V));
2966
- break ;
2967
- }
2968
- case InlineAsm::isOutput: {
2969
- std::pair<Value*, int > V;
2970
- if (ValueCount < ResultVals.size ())
2971
- V = ResultVals[ValueCount];
2972
- else
2973
- V = std::make_pair (CI.getOperand (ValueCount-ResultVals.size ()+1 ), -1 );
2974
- Output.push_back (std::make_pair (" =" +((I->isEarlyClobber ? " &" : " " )+C),
2975
- V));
2976
- break ;
2977
- }
2978
- case InlineAsm::isClobber:
2979
- Clobber += " ,\" " + C + " \" " ;
2980
- continue ; // Not an actual argument.
2970
+ if (!IsFirst) {
2971
+ Out << " , " ;
2972
+ IsFirst = false ;
2981
2973
}
2982
- ++ValueCount; // Consumes an argument.
2974
+
2975
+ // Unpack the dest.
2976
+ Value *DestVal;
2977
+ int DestValNo = -1 ;
2978
+
2979
+ if (ValueCount < ResultVals.size ()) {
2980
+ DestVal = ResultVals[ValueCount].first ;
2981
+ DestValNo = ResultVals[ValueCount].second ;
2982
+ } else
2983
+ DestVal = CI.getOperand (ValueCount-ResultVals.size ()+1 );
2984
+
2985
+ if (I->isEarlyClobber )
2986
+ C = " &" +C;
2987
+
2988
+ Out << " \" =" << C << " \" (" << GetValueName (DestVal);
2989
+ if (DestValNo != -1 )
2990
+ Out << " .field" << DestValNo; // Multiple retvals.
2991
+ Out << " )" ;
2992
+ ++ValueCount;
2983
2993
}
2984
2994
2985
- // Fix up the asm string for gcc.
2986
- std::string asmstr = gccifyAsm (as->getAsmString ());
2987
2995
2988
- Out << " __asm__ volatile (\" " << asmstr << " \"\n " ;
2989
- Out << " :" ;
2990
- for (unsigned i = 0 , e = Output.size (); i != e; ++i) {
2991
- if (i)
2996
+ // Convert over all the input constraints.
2997
+ Out << " \n :" ;
2998
+ IsFirst = true ;
2999
+ ValueCount = 0 ;
3000
+ for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin (),
3001
+ E = Constraints.end (); I != E; ++I) {
3002
+ if (I->Type != InlineAsm::isInput) {
3003
+ ++ValueCount;
3004
+ continue ; // Ignore non-input constraints.
3005
+ }
3006
+
3007
+ assert (I->Codes .size () == 1 && " Too many asm constraint codes to handle" );
3008
+ std::string C = InterpretASMConstraint (*I);
3009
+ if (C.empty ()) continue ;
3010
+
3011
+ if (!IsFirst) {
2992
3012
Out << " , " ;
2993
- Out << " \" " << Output[i].first << " \" ("
2994
- << GetValueName (Output[i].second .first );
2995
- if (Output[i].second .second != -1 )
2996
- Out << " .field" << Output[i].second .second ; // Multiple retvals.
3013
+ IsFirst = false ;
3014
+ }
3015
+
3016
+ assert (ValueCount >= ResultVals.size () && " Input can't refer to result" );
3017
+ Value *SrcVal = CI.getOperand (ValueCount-ResultVals.size ()+1 );
3018
+
3019
+ Out << " \" " << C << " \" (" ;
3020
+ if (!I->isIndirect )
3021
+ writeOperand (SrcVal);
3022
+ else
3023
+ writeOperandDeref (SrcVal);
2997
3024
Out << " )" ;
2998
3025
}
2999
- Out << " \n :" ;
3000
- for (unsigned i = 0 , e = Input.size (); i != e; ++i) {
3001
- if (i)
3026
+
3027
+ // Convert over the clobber constraints.
3028
+ IsFirst = true ;
3029
+ ValueCount = 0 ;
3030
+ for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin (),
3031
+ E = Constraints.end (); I != E; ++I) {
3032
+ if (I->Type != InlineAsm::isClobber)
3033
+ continue ; // Ignore non-input constraints.
3034
+
3035
+ assert (I->Codes .size () == 1 && " Too many asm constraint codes to handle" );
3036
+ std::string C = InterpretASMConstraint (*I);
3037
+ if (C.empty ()) continue ;
3038
+
3039
+ if (!IsFirst) {
3002
3040
Out << " , " ;
3003
- Out << " \" " << Input[i].first << " \" (" ;
3004
- writeOperand (Input[i].second );
3005
- Out << " )" ;
3041
+ IsFirst = false ;
3042
+ }
3043
+
3044
+ Out << ' \" ' << C << ' "' ;
3006
3045
}
3007
- if (Clobber.size ())
3008
- Out << " \n :" << Clobber.substr (1 );
3046
+
3009
3047
Out << " )" ;
3010
3048
}
3011
3049
0 commit comments