Loading llvm/lib/Target/CBackend/CBackend.cpp +83 −45 Original line number Diff line number Diff line Loading @@ -2936,10 +2936,6 @@ static std::string gccifyAsm(std::string asmstr) { void CWriter::visitInlineAsm(CallInst &CI) { InlineAsm* as = cast<InlineAsm>(CI.getOperand(0)); std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints(); std::vector<std::pair<std::string, Value*> > Input; std::vector<std::pair<std::string, std::pair<Value*, int> > > Output; std::string Clobber; unsigned ValueCount = 0; std::vector<std::pair<Value*, int> > ResultVals; if (CI.getType() == Type::VoidTy) Loading @@ -2951,61 +2947,103 @@ void CWriter::visitInlineAsm(CallInst &CI) { ResultVals.push_back(std::make_pair(&CI, -1)); } // Fix up the asm string for gcc and emit it. Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n"; Out << " :"; unsigned ValueCount = 0; bool IsFirst = true; // Convert over all the output constraints. for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isOutput) { ++ValueCount; continue; // Ignore non-output constraints. } assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; switch (I->Type) { default: assert(0 && "Unknown asm constraint"); case InlineAsm::isInput: { assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); Value *V = CI.getOperand(ValueCount-ResultVals.size()+1); Input.push_back(std::make_pair(C, V)); break; } case InlineAsm::isOutput: { std::pair<Value*, int> V; if (ValueCount < ResultVals.size()) V = ResultVals[ValueCount]; else V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1); Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C), V)); break; if (!IsFirst) { Out << ", "; IsFirst = false; } case InlineAsm::isClobber: Clobber += ",\"" + C + "\""; continue; // Not an actual argument. // Unpack the dest. Value *DestVal; int DestValNo = -1; if (ValueCount < ResultVals.size()) { DestVal = ResultVals[ValueCount].first; DestValNo = ResultVals[ValueCount].second; } else DestVal = CI.getOperand(ValueCount-ResultVals.size()+1); if (I->isEarlyClobber) C = "&"+C; Out << "\"=" << C << "\"(" << GetValueName(DestVal); if (DestValNo != -1) Out << ".field" << DestValNo; // Multiple retvals. Out << ")"; ++ValueCount; } ++ValueCount; // Consumes an argument. // Convert over all the input constraints. Out << "\n :"; IsFirst = true; ValueCount = 0; for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isInput) { ++ValueCount; continue; // Ignore non-input constraints. } // Fix up the asm string for gcc. std::string asmstr = gccifyAsm(as->getAsmString()); assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; Out << "__asm__ volatile (\"" << asmstr << "\"\n"; Out << " :"; for (unsigned i = 0, e = Output.size(); i != e; ++i) { if (i) if (!IsFirst) { Out << ", "; Out << "\"" << Output[i].first << "\"(" << GetValueName(Output[i].second.first); if (Output[i].second.second != -1) Out << ".field" << Output[i].second.second; // Multiple retvals. IsFirst = false; } assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1); Out << "\"" << C << "\"("; if (!I->isIndirect) writeOperand(SrcVal); else writeOperandDeref(SrcVal); Out << ")"; } Out << "\n :"; for (unsigned i = 0, e = Input.size(); i != e; ++i) { if (i) // Convert over the clobber constraints. IsFirst = true; ValueCount = 0; for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isClobber) continue; // Ignore non-input constraints. assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; if (!IsFirst) { Out << ", "; Out << "\"" << Input[i].first << "\"("; writeOperand(Input[i].second); Out << ")"; IsFirst = false; } if (Clobber.size()) Out << "\n :" << Clobber.substr(1); Out << '\"' << C << '"'; } Out << ")"; } Loading llvm/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll 0 → 100644 +12 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))} ; PR2407 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" target triple = "i386-pc-linux-gnu" define void @foo() { %newcw = alloca i16 ; <i16*> [#uses=2] call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16* %newcw ) nounwind ret void } Loading
llvm/lib/Target/CBackend/CBackend.cpp +83 −45 Original line number Diff line number Diff line Loading @@ -2936,10 +2936,6 @@ static std::string gccifyAsm(std::string asmstr) { void CWriter::visitInlineAsm(CallInst &CI) { InlineAsm* as = cast<InlineAsm>(CI.getOperand(0)); std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints(); std::vector<std::pair<std::string, Value*> > Input; std::vector<std::pair<std::string, std::pair<Value*, int> > > Output; std::string Clobber; unsigned ValueCount = 0; std::vector<std::pair<Value*, int> > ResultVals; if (CI.getType() == Type::VoidTy) Loading @@ -2951,61 +2947,103 @@ void CWriter::visitInlineAsm(CallInst &CI) { ResultVals.push_back(std::make_pair(&CI, -1)); } // Fix up the asm string for gcc and emit it. Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n"; Out << " :"; unsigned ValueCount = 0; bool IsFirst = true; // Convert over all the output constraints. for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isOutput) { ++ValueCount; continue; // Ignore non-output constraints. } assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; switch (I->Type) { default: assert(0 && "Unknown asm constraint"); case InlineAsm::isInput: { assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); Value *V = CI.getOperand(ValueCount-ResultVals.size()+1); Input.push_back(std::make_pair(C, V)); break; } case InlineAsm::isOutput: { std::pair<Value*, int> V; if (ValueCount < ResultVals.size()) V = ResultVals[ValueCount]; else V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1); Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C), V)); break; if (!IsFirst) { Out << ", "; IsFirst = false; } case InlineAsm::isClobber: Clobber += ",\"" + C + "\""; continue; // Not an actual argument. // Unpack the dest. Value *DestVal; int DestValNo = -1; if (ValueCount < ResultVals.size()) { DestVal = ResultVals[ValueCount].first; DestValNo = ResultVals[ValueCount].second; } else DestVal = CI.getOperand(ValueCount-ResultVals.size()+1); if (I->isEarlyClobber) C = "&"+C; Out << "\"=" << C << "\"(" << GetValueName(DestVal); if (DestValNo != -1) Out << ".field" << DestValNo; // Multiple retvals. Out << ")"; ++ValueCount; } ++ValueCount; // Consumes an argument. // Convert over all the input constraints. Out << "\n :"; IsFirst = true; ValueCount = 0; for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isInput) { ++ValueCount; continue; // Ignore non-input constraints. } // Fix up the asm string for gcc. std::string asmstr = gccifyAsm(as->getAsmString()); assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; Out << "__asm__ volatile (\"" << asmstr << "\"\n"; Out << " :"; for (unsigned i = 0, e = Output.size(); i != e; ++i) { if (i) if (!IsFirst) { Out << ", "; Out << "\"" << Output[i].first << "\"(" << GetValueName(Output[i].second.first); if (Output[i].second.second != -1) Out << ".field" << Output[i].second.second; // Multiple retvals. IsFirst = false; } assert(ValueCount >= ResultVals.size() && "Input can't refer to result"); Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1); Out << "\"" << C << "\"("; if (!I->isIndirect) writeOperand(SrcVal); else writeOperandDeref(SrcVal); Out << ")"; } Out << "\n :"; for (unsigned i = 0, e = Input.size(); i != e; ++i) { if (i) // Convert over the clobber constraints. IsFirst = true; ValueCount = 0; for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(), E = Constraints.end(); I != E; ++I) { if (I->Type != InlineAsm::isClobber) continue; // Ignore non-input constraints. assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle"); std::string C = InterpretASMConstraint(*I); if (C.empty()) continue; if (!IsFirst) { Out << ", "; Out << "\"" << Input[i].first << "\"("; writeOperand(Input[i].second); Out << ")"; IsFirst = false; } if (Clobber.size()) Out << "\n :" << Clobber.substr(1); Out << '\"' << C << '"'; } Out << ")"; } Loading
llvm/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll 0 → 100644 +12 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))} ; PR2407 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" target triple = "i386-pc-linux-gnu" define void @foo() { %newcw = alloca i16 ; <i16*> [#uses=2] call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16* %newcw ) nounwind ret void }