Skip to content

Commit b7956f6

Browse files
committed
Merge from mainline to fix PR2407.
llvm-svn: 51962
1 parent 9b3a8a3 commit b7956f6

File tree

2 files changed

+95
-45
lines changed

2 files changed

+95
-45
lines changed

llvm/lib/Target/CBackend/CBackend.cpp

Lines changed: 83 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,10 +2936,6 @@ static std::string gccifyAsm(std::string asmstr) {
29362936
void CWriter::visitInlineAsm(CallInst &CI) {
29372937
InlineAsm* as = cast<InlineAsm>(CI.getOperand(0));
29382938
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;
29432939

29442940
std::vector<std::pair<Value*, int> > ResultVals;
29452941
if (CI.getType() == Type::VoidTy)
@@ -2951,61 +2947,103 @@ void CWriter::visitInlineAsm(CallInst &CI) {
29512947
ResultVals.push_back(std::make_pair(&CI, -1));
29522948
}
29532949

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.
29542958
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+
29562966
assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
29572967
std::string C = InterpretASMConstraint(*I);
29582968
if (C.empty()) continue;
29592969

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;
29812973
}
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;
29832993
}
29842994

2985-
// Fix up the asm string for gcc.
2986-
std::string asmstr = gccifyAsm(as->getAsmString());
29872995

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) {
29923012
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);
29973024
Out << ")";
29983025
}
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) {
30023040
Out << ", ";
3003-
Out << "\"" << Input[i].first << "\"(";
3004-
writeOperand(Input[i].second);
3005-
Out << ")";
3041+
IsFirst = false;
3042+
}
3043+
3044+
Out << '\"' << C << '"';
30063045
}
3007-
if (Clobber.size())
3008-
Out << "\n :" << Clobber.substr(1);
3046+
30093047
Out << ")";
30103048
}
30113049

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))}
2+
; PR2407
3+
4+
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"
5+
target triple = "i386-pc-linux-gnu"
6+
7+
define void @foo() {
8+
%newcw = alloca i16 ; <i16*> [#uses=2]
9+
call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16*
10+
%newcw ) nounwind
11+
ret void
12+
}

0 commit comments

Comments
 (0)