llvm.org GIT mirror llvm / b666e3e
Merge from mainline to fix PR2407. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_23@51962 91177308-0d34-0410-b5e6-96231b3b80d8 Tanya Lattner 12 years ago
2 changed file(s) with 98 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
29352935 void CWriter::visitInlineAsm(CallInst &CI) {
29362936 InlineAsm* as = cast(CI.getOperand(0));
29372937 std::vector Constraints = as->ParseConstraints();
2938 std::vector > Input;
2939 std::vector > > Output;
2940 std::string Clobber;
2941 unsigned ValueCount = 0;
29422938
29432939 std::vector > ResultVals;
29442940 if (CI.getType() == Type::VoidTy)
29502946 ResultVals.push_back(std::make_pair(&CI, -1));
29512947 }
29522948
2949 // Fix up the asm string for gcc and emit it.
2950 Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n";
2951 Out << " :";
2952
2953 unsigned ValueCount = 0;
2954 bool IsFirst = true;
2955
2956 // Convert over all the output constraints.
29532957 for (std::vector::iterator I = Constraints.begin(),
2954 E = Constraints.end(); I != E; ++I) {
2958 E = Constraints.end(); I != E; ++I) {
2959
2960 if (I->Type != InlineAsm::isOutput) {
2961 ++ValueCount;
2962 continue; // Ignore non-output constraints.
2963 }
2964
29552965 assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
29562966 std::string C = InterpretASMConstraint(*I);
29572967 if (C.empty()) continue;
29582968
2959 switch (I->Type) {
2960 default: assert(0 && "Unknown asm constraint");
2961 case InlineAsm::isInput: {
2962 assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
2963 Value *V = CI.getOperand(ValueCount-ResultVals.size()+1);
2964 Input.push_back(std::make_pair(C, V));
2965 break;
2966 }
2967 case InlineAsm::isOutput: {
2968 std::pair V;
2969 if (ValueCount < ResultVals.size())
2970 V = ResultVals[ValueCount];
2971 else
2972 V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1);
2973 Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C),
2974 V));
2975 break;
2976 }
2977 case InlineAsm::isClobber:
2978 Clobber += ",\"" + C + "\"";
2979 continue; // Not an actual argument.
2980 }
2981 ++ValueCount; // Consumes an argument.
2982 }
2983
2984 // Fix up the asm string for gcc.
2985 std::string asmstr = gccifyAsm(as->getAsmString());
2986
2987 Out << "__asm__ volatile (\"" << asmstr << "\"\n";
2988 Out << " :";
2989 for (unsigned i = 0, e = Output.size(); i != e; ++i) {
2990 if (i)
2969 if (!IsFirst) {
29912970 Out << ", ";
2992 Out << "\"" << Output[i].first << "\"("
2993 << GetValueName(Output[i].second.first);
2994 if (Output[i].second.second != -1)
2995 Out << ".field" << Output[i].second.second; // Multiple retvals.
2971 IsFirst = false;
2972 }
2973
2974 // Unpack the dest.
2975 Value *DestVal;
2976 int DestValNo = -1;
2977
2978 if (ValueCount < ResultVals.size()) {
2979 DestVal = ResultVals[ValueCount].first;
2980 DestValNo = ResultVals[ValueCount].second;
2981 } else
2982 DestVal = CI.getOperand(ValueCount-ResultVals.size()+1);
2983
2984 if (I->isEarlyClobber)
2985 C = "&"+C;
2986
2987 Out << "\"=" << C << "\"(" << GetValueName(DestVal);
2988 if (DestValNo != -1)
2989 Out << ".field" << DestValNo; // Multiple retvals.
29962990 Out << ")";
2997 }
2991 ++ValueCount;
2992 }
2993
2994
2995 // Convert over all the input constraints.
29982996 Out << "\n :";
2999 for (unsigned i = 0, e = Input.size(); i != e; ++i) {
3000 if (i)
2997 IsFirst = true;
2998 ValueCount = 0;
2999 for (std::vector::iterator I = Constraints.begin(),
3000 E = Constraints.end(); I != E; ++I) {
3001 if (I->Type != InlineAsm::isInput) {
3002 ++ValueCount;
3003 continue; // Ignore non-input constraints.
3004 }
3005
3006 assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
3007 std::string C = InterpretASMConstraint(*I);
3008 if (C.empty()) continue;
3009
3010 if (!IsFirst) {
30013011 Out << ", ";
3002 Out << "\"" << Input[i].first << "\"(";
3003 writeOperand(Input[i].second);
3012 IsFirst = false;
3013 }
3014
3015 assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
3016 Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1);
3017
3018 Out << "\"" << C << "\"(";
3019 if (!I->isIndirect)
3020 writeOperand(SrcVal);
3021 else
3022 writeOperandDeref(SrcVal);
30043023 Out << ")";
30053024 }
3006 if (Clobber.size())
3007 Out << "\n :" << Clobber.substr(1);
3025
3026 // Convert over the clobber constraints.
3027 IsFirst = true;
3028 ValueCount = 0;
3029 for (std::vector::iterator I = Constraints.begin(),
3030 E = Constraints.end(); I != E; ++I) {
3031 if (I->Type != InlineAsm::isClobber)
3032 continue; // Ignore non-input constraints.
3033
3034 assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
3035 std::string C = InterpretASMConstraint(*I);
3036 if (C.empty()) continue;
3037
3038 if (!IsFirst) {
3039 Out << ", ";
3040 IsFirst = false;
3041 }
3042
3043 Out << '\"' << C << '"';
3044 }
3045
30083046 Out << ")";
30093047 }
30103048
0 ; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))}
1 ; PR2407
2
3 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:32:32"
4 target triple = "i386-pc-linux-gnu"
5
6 define void @foo() {
7 %newcw = alloca i16 ; [#uses=2]
8 call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16*
9 %newcw ) nounwind
10 ret void
11 }