diff options
Diffstat (limited to 'lib')
26 files changed, 502 insertions, 281 deletions
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp index 106f3a1034..dfd34297f3 100644 --- a/lib/Analysis/DataStructure/Local.cpp +++ b/lib/Analysis/DataStructure/Local.cpp @@ -119,7 +119,6 @@ namespace { void visitInstruction(Instruction &I); void visitCallSite(CallSite CS); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C); @@ -475,11 +474,8 @@ void GraphBuilder::visitReturnInst(ReturnInst &RI) { RetNode->mergeWith(getValueDest(*RI.getOperand(0))); } -void GraphBuilder::visitVANextInst(VANextInst &I) { - getValueDest(*I.getOperand(0)).mergeWith(getValueDest(I)); -} - void GraphBuilder::visitVAArgInst(VAArgInst &I) { + //FIXME: also updates the argument DSNodeHandle Ptr = getValueDest(*I.getOperand(0)); if (Ptr.isNull()) return; diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp index 8362be596b..c33a3254aa 100644 --- a/lib/Analysis/IPA/Andersens.cpp +++ b/lib/Analysis/IPA/Andersens.cpp @@ -330,7 +330,6 @@ namespace { void visitCastInst(CastInst &CI); void visitSetCondInst(SetCondInst &SCI) {} // NOOP! void visitSelectInst(SelectInst &SI); - void visitVANext(VANextInst &I); void visitVAArg(VAArgInst &I); void visitInstruction(Instruction &I); }; @@ -867,10 +866,6 @@ void Andersens::visitSelectInst(SelectInst &SI) { } } -void Andersens::visitVANext(VANextInst &I) { - // FIXME: Implement - assert(0 && "vanext not handled yet!"); -} void Andersens::visitVAArg(VAArgInst &I) { assert(0 && "vaarg not handled yet!"); } diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 062e00c419..f9866f2bbc 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -253,9 +253,9 @@ cast { RET_TOK(OtherOpVal, Cast, CAST); } select { RET_TOK(OtherOpVal, Select, SELECT); } shl { RET_TOK(OtherOpVal, Shl, SHL); } shr { RET_TOK(OtherOpVal, Shr, SHR); } -vanext { RET_TOK(OtherOpVal, VANext, VANEXT); } -vaarg { RET_TOK(OtherOpVal, VAArg , VAARG); } - +vanext { return VANEXT_old; } +vaarg { return VAARG_old; } +va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); } ret { RET_TOK(TermOpVal, Ret, RET); } br { RET_TOK(TermOpVal, Br, BR); } switch { RET_TOK(TermOpVal, Switch, SWITCH); } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index d73b008416..f59475cd13 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -47,6 +47,10 @@ static Module *ParserResult; #define YYERROR_VERBOSE 1 +static bool ObsoleteVarArgs; +static BasicBlock* CurBB; + + // This contains info used when building the body of a function. It is // destroyed when the function is completed. // @@ -723,6 +727,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) { static Module * RunParser(Module * M) { llvmAsmlineno = 1; // Reset the current line number... + ObsoleteVarArgs = false; CurModule.CurrentModule = M; yyparse(); // Parse the file, potentially throwing exception @@ -730,6 +735,80 @@ static PATypeHolder HandleUpRefs(const Type *ty) { Module *Result = ParserResult; ParserResult = 0; + if(ObsoleteVarArgs) { + if(Function* F = Result->getNamedFunction("llvm.va_start")) { + assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); + + //foo = va_start() + // -> + //bar = alloca typeof(foo) + //va_start(bar) + //foo = load bar + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_start", + RetTy, ArgTyPtr, 0); + + while (!F->use_empty()) { + CallInst* CI = cast<CallInst>(F->use_back()); + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); + new CallInst(NF, bar, "", CI); + Value* foo = new LoadInst(bar, "vastart.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + + if(Function* F = Result->getNamedFunction("llvm.va_end")) { + assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!"); + //vaend foo + // -> + //bar = alloca 1 of typeof(foo) + //vaend bar + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getParamType(0); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_end", + RetTy, ArgTyPtr, 0); + + while (!F->use_empty()) { + CallInst* CI = cast<CallInst>(F->use_back()); + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); + new CallInst(NF, bar, "", CI); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + + if(Function* F = Result->getNamedFunction("llvm.va_copy")) { + assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!"); + //foo = vacopy(bar) + // -> + //a = alloca 1 of typeof(foo) + //vacopy(a, bar) + //foo = load a + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_copy", + RetTy, ArgTyPtr, ArgTy, 0); + + while (!F->use_empty()) { + CallInst* CI = cast<CallInst>(F->use_back()); + AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); + new CallInst(NF, a, CI->getOperand(1), "", CI); + Value* foo = new LoadInst(a, "vacopy.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + Result->getFunctionList().erase(F); + } + } + return Result; } @@ -866,7 +945,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Other Operators %type <OtherOpVal> ShiftOps -%token <OtherOpVal> PHI_TOK CAST SELECT SHL SHR VAARG VANEXT +%token <OtherOpVal> PHI_TOK CAST SELECT SHL SHR VAARG +%token VAARG_old VANEXT_old //OBSOLETE %start Module @@ -1727,7 +1807,7 @@ InstructionList : InstructionList Inst { $$ = $1; } | /* empty */ { - $$ = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); + $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); // Make sure to move the basic block to the correct location in the // function, instead of leaving it inserted wherever it was first @@ -1737,7 +1817,7 @@ InstructionList : InstructionList Inst { BBL.splice(BBL.end(), BBL, $$); } | LABELSTR { - $$ = getBBVal(ValID::create($1), true); + $$ = CurBB = getBBVal(ValID::create($1), true); // Make sure to move the basic block to the correct location in the // function, instead of leaving it inserted wherever it was first @@ -1964,8 +2044,45 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { $$ = new VAArgInst($2, *$4); delete $4; } - | VANEXT ResolvedVal ',' Types { - $$ = new VANextInst($2, *$4); + | VAARG_old ResolvedVal ',' Types { + ObsoleteVarArgs = true; + const Type* ArgTy = $2->getType(); + Function* NF = CurModule.CurrentModule-> + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vaarg a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //b = vaarg foo, t + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); + CurBB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, $2); + CurBB->getInstList().push_back(bar); + CurBB->getInstList().push_back(new StoreInst(bar, foo)); + $$ = new VAArgInst(foo, *$4); + delete $4; + } + | VANEXT_old ResolvedVal ',' Types { + ObsoleteVarArgs = true; + const Type* ArgTy = $2->getType(); + Function* NF = CurModule.CurrentModule-> + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vanext a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //tmp = vaarg foo, t + //b = load foo + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix"); + CurBB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, $2); + CurBB->getInstList().push_back(bar); + CurBB->getInstList().push_back(new StoreInst(bar, foo)); + Instruction* tmp = new VAArgInst(foo, *$4); + CurBB->getInstList().push_back(tmp); + $$ = new LoadInst(foo); delete $4; } | PHI_TOK PHIList { diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 7e5bed6989..d730ca256a 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -658,10 +658,43 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, Result = new VAArgInst(getValue(iType, Oprnds[0]), getSanitizedType(Oprnds[1])); break; - case Instruction::VANext: - Result = new VANextInst(getValue(iType, Oprnds[0]), - getSanitizedType(Oprnds[1])); + case 32: { //VANext_old + const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vanext a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //tmp = vaarg foo, t + //b = load foo + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix"); + BB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, getValue(iType, Oprnds[0])); + BB->getInstList().push_back(bar); + BB->getInstList().push_back(new StoreInst(bar, foo)); + Instruction* tmp = new VAArgInst(foo, getSanitizedType(Oprnds[1])); + BB->getInstList().push_back(tmp); + Result = new LoadInst(foo); break; + } + case 33: { //VAArg_old + const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + + //b = vaarg a, t -> + //foo = alloca 1 of t + //bar = vacopy a + //store bar -> foo + //b = vaarg foo, t + AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); + BB->getInstList().push_back(foo); + CallInst* bar = new CallInst(NF, getValue(iType, Oprnds[0])); + BB->getInstList().push_back(bar); + BB->getInstList().push_back(new StoreInst(bar, foo)); + Result = new VAArgInst(foo, getSanitizedType(Oprnds[1])); + break; + } case Instruction::Cast: Result = new CastInst(getValue(iType, Oprnds[0]), getSanitizedType(Oprnds[1])); diff --git a/lib/Bytecode/Reader/ReaderWrappers.cpp b/lib/Bytecode/Reader/ReaderWrappers.cpp index 6823936209..8d1f384986 100644 --- a/lib/Bytecode/Reader/ReaderWrappers.cpp +++ b/lib/Bytecode/Reader/ReaderWrappers.cpp @@ -149,6 +149,100 @@ BytecodeStdinReader::BytecodeStdinReader( BytecodeHandler* H ) } //===----------------------------------------------------------------------===// +// Varargs transmogrification code... +// + +// CheckVarargs - This is used to automatically translate old-style varargs to +// new style varargs for backwards compatibility. +static ModuleProvider* CheckVarargs(ModuleProvider* MP) { + Module* M = MP->getModule(); + + // check to see if va_start takes arguements... + Function* F = M->getNamedFunction("llvm.va_start"); + if(F == 0) return MP; //No varargs use, just return. + + if (F->getFunctionType()->getNumParams() == 1) + return MP; // Modern varargs processing, just return. + + // If we get to this point, we know that we have an old-style module. + // Materialize the whole thing to perform the rewriting. + MP->materializeModule(); + + if(Function* F = M->getNamedFunction("llvm.va_start")) { + assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); + + //foo = va_start() + // -> + //bar = alloca typeof(foo) + //va_start(bar) + //foo = load bar + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = M->getOrInsertFunction("llvm.va_start", + RetTy, ArgTyPtr, 0); + + for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) + if (CallInst* CI = dyn_cast<CallInst>(*I++)) { + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); + new CallInst(NF, bar, "", CI); + Value* foo = new LoadInst(bar, "vastart.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + + if(Function* F = M->getNamedFunction("llvm.va_end")) { + assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!"); + //vaend foo + // -> + //bar = alloca 1 of typeof(foo) + //vaend bar + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getParamType(0); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = M->getOrInsertFunction("llvm.va_end", + RetTy, ArgTyPtr, 0); + + for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) + if (CallInst* CI = dyn_cast<CallInst>(*I++)) { + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); + new CallInst(NF, bar, "", CI); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + + if(Function* F = M->getNamedFunction("llvm.va_copy")) { + assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!"); + //foo = vacopy(bar) + // -> + //a = alloca 1 of typeof(foo) + //vacopy(a, bar) + //foo = load a + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = M->getOrInsertFunction("llvm.va_copy", + RetTy, ArgTyPtr, ArgTy, 0); + + for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) + if (CallInst* CI = dyn_cast<CallInst>(*I++)) { + AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); + new CallInst(NF, a, CI->getOperand(1), "", CI); + Value* foo = new LoadInst(a, "vacopy.fix.2", CI); + CI->replaceAllUsesWith(foo); + CI->getParent()->getInstList().erase(CI); + } + F->setName(""); + } + return MP; +} + +//===----------------------------------------------------------------------===// // Wrapper functions //===----------------------------------------------------------------------===// @@ -159,7 +253,8 @@ llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer, unsigned Length, const std::string &ModuleID, BytecodeHandler* H ) { - return new BytecodeBufferReader(Buffer, Length, ModuleID, H); + return CheckVarargs( + new BytecodeBufferReader(Buffer, Length, ModuleID, H)); } /// ParseBytecodeBuffer - Parse a given bytecode buffer @@ -182,9 +277,9 @@ Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length, ModuleProvider *llvm::getBytecodeModuleProvider(const std::string &Filename, BytecodeHandler* H) { if (Filename != std::string("-")) // Read from a file... - return new BytecodeFileReader(Filename,H); + return CheckVarargs(new BytecodeFileReader(Filename,H)); else // Read from stdin - return new BytecodeStdinReader(H); + return CheckVarargs(new BytecodeStdinReader(H)); } /// ParseBytecodeFile - Parse the given bytecode file diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index fbeb50c03a..c6aba09fe5 100644 --- a/lib/Bytecode/Writer/SlotCalculator.cpp +++ b/lib/Bytecode/Writer/SlotCalculator.cpp @@ -187,8 +187,6 @@ void SlotCalculator::processModule() { !isa<GlobalValue>(I->getOperand(op))) getOrCreateSlot(I->getOperand(op)); getOrCreateSlot(I->getType()); - if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I)) - getOrCreateSlot(VAN->getArgType()); } processSymbolTableConstants(&F->getSymbolTable()); } @@ -320,8 +318,6 @@ void SlotCalculator::incorporateFunction(const Function *F) { getOrCreateSlot(BB); for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { getOrCreateSlot(I); - if (const VANextInst *VAN = dyn_cast<VANextInst>(I)) - getOrCreateSlot(VAN->getArgType()); } } @@ -472,8 +468,6 @@ void SlotCalculator::buildCompactionTable(const Function *F) { for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) if (isa<Constant>(I->getOperand(op))) getOrCreateCompactionTableSlot(I->getOperand(op)); - if (const VANextInst *VAN = dyn_cast<VANextInst>(&*I)) - getOrCreateCompactionTableSlot(VAN->getArgType()); } // Do the types in the symbol table diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index fb5a1aa603..90cfa96462 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -439,7 +439,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, output_typeid(Type); // Result type unsigned NumArgs = I->getNumOperands(); - output_vbr(NumArgs + (isa<CastInst>(I) || isa<VANextInst>(I) || + output_vbr(NumArgs + (isa<CastInst>(I) || isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58)); if (!isa<GetElementPtrInst>(&I)) { @@ -453,10 +453,6 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Cast return type unknown?"); output_typeid((unsigned)Slot); - } else if (const VANextInst *VAI = dyn_cast<VANextInst>(I)) { - int Slot = Table.getSlot(VAI->getArgType()); - assert(Slot != -1 && "VarArg argument type unknown?"); - output_typeid((unsigned)Slot); } else if (Opcode == 56) { // Invoke escape sequence output_vbr(cast<InvokeInst>(I)->getCallingConv()); } else if (Opcode == 58) { // Call escape sequence @@ -704,11 +700,6 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { assert(Slots[1] != ~0U && "Cast return type unknown?"); if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; NumOperands++; - } else if (const VANextInst *VANI = dyn_cast<VANextInst>(&I)) { - Slots[1] = Table.getSlot(VANI->getArgType()); - assert(Slots[1] != ~0U && "va_next return type unknown?"); - if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; - NumOperands++; } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) { // We need to encode the type of sequential type indices into their slot # unsigned Idx = 1; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2e3febade9..0c94ea74cd 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -356,7 +356,6 @@ public: void visitCall(CallInst &I); void visitVAStart(CallInst &I); - void visitVANext(VANextInst &I); void visitVAArg(VAArgInst &I); void visitVAEnd(CallInst &I); void visitVACopy(CallInst &I); @@ -839,7 +838,7 @@ void SelectionDAGLowering::visitFree(FreeInst &I) { } std::pair<SDOperand, SDOperand> -TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { +TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { // We have no sane default behavior, just emit a useful error message and bail // out. std::cerr << "Variable arguments handling not implemented on this target!\n"; @@ -854,13 +853,16 @@ SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand L, } std::pair<SDOperand,SDOperand> -TargetLowering::LowerVACopy(SDOperand Chain, SDOperand L, SelectionDAG &DAG) { - // Default to returning the input list. - return std::make_pair(L, Chain); +TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, + SelectionDAG &DAG) { + // We have no sane default behavior, just emit a useful error message and bail + // out. + std::cerr << "Variable arguments handling not implemented on this target!\n"; + abort(); } std::pair<SDOperand,SDOperand> -TargetLowering::LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, +TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { // We have no sane default behavior, just emit a useful error message and bail // out. @@ -871,23 +873,15 @@ TargetLowering::LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, void SelectionDAGLowering::visitVAStart(CallInst &I) { - std::pair<SDOperand,SDOperand> Result = TLI.LowerVAStart(getRoot(), DAG); + std::pair<SDOperand,SDOperand> Result = TLI.LowerVAStart(getRoot(), DAG, getValue(I.getOperand(1))); setValue(&I, Result.first); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAArg(VAArgInst &I) { std::pair<SDOperand,SDOperand> Result = - TLI.LowerVAArgNext(false, getRoot(), getValue(I.getOperand(0)), - I.getType(), DAG); - setValue(&I, Result.first); - DAG.setRoot(Result.second); -} - -void SelectionDAGLowering::visitVANext(VANextInst &I) { - std::pair<SDOperand,SDOperand> Result = - TLI.LowerVAArgNext(true, getRoot(), getValue(I.getOperand(0)), - I.getArgType(), DAG); + TLI.LowerVAArgNext(getRoot(), getValue(I.getOperand(0)), + I.getType(), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } @@ -898,7 +892,7 @@ void SelectionDAGLowering::visitVAEnd(CallInst &I) { void SelectionDAGLowering::visitVACopy(CallInst &I) { std::pair<SDOperand,SDOperand> Result = - TLI.LowerVACopy(getRoot(), getValue(I.getOperand(1)), DAG); + TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), getValue(I.getOperand(1)), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 11608b6bfa..a41d12af4f 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -988,18 +988,6 @@ void Interpreter::visitCastInst(CastInst &I) { SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); } -void Interpreter::visitVANextInst(VANextInst &I) { - ExecutionContext &SF = ECStack.back(); - - // Get the incoming valist parameter. LLI treats the valist as a - // (ec-stack-depth var-arg-index) pair. - GenericValue VAList = getOperandValue(I.getOperand(0), SF); - - // Move the pointer to the next vararg. - ++VAList.UIntPairVal.second; - SetValue(&I, VAList, SF); -} - #define IMPLEMENT_VAARG(TY) \ case Type::TY##TyID: Dest.TY##Val = Src.TY##Val; break @@ -1033,6 +1021,9 @@ void Interpreter::visitVAArgInst(VAArgInst &I) { // Set the Value of this Instruction. SetValue(&I, Dest, SF); + + // Move the pointer to the next vararg. + ++VAList.UIntPairVal.second; } //===----------------------------------------------------------------------===// diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index 2e83f5e7c6..180d0921b7 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -153,7 +153,6 @@ public: void visitShl(ShiftInst &I); void visitShr(ShiftInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { std::cerr << I; diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index e521a033a0..de135cb3c2 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -72,7 +72,8 @@ namespace { // AlphaTargetLowering - Alpha Implementation of the TargetLowering interface namespace { class AlphaTargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int VarArgsOffset; // What is the offset to the first vaarg + int VarArgsBase; // What is the base FrameIndex unsigned GP; //GOT vreg public: AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { @@ -151,10 +152,10 @@ namespace { SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> - LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); virtual std::pair<SDOperand,SDOperand> - LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> @@ -300,12 +301,14 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) // If the functions takes variable number of arguments, copy all regs to stack if (F.isVarArg()) { + VarArgsOffset = count * 8; std::vector<SDOperand> LS; for (int i = 0; i < 6; ++i) { if (args_int[i] < 1024) args_int[i] = AddLiveIn(MF,args_int[i], getRegClassFor(MVT::i64)); SDOperand argt = DAG.getCopyFromReg(args_int[i], MVT::i64, DAG.getRoot()); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); + if (i == 0) VarArgsBase = FI; SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, SDFI, DAG.getSrcValue(NULL))); @@ -393,15 +396,34 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, } std::pair<SDOperand, SDOperand> -AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { - //vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); +AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { + // vastart just stores the address of the VarArgsBase and VarArgsOffset + SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i32); + SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, Dest, DAG.getConstant(8, MVT::i64)); + SDOperand S2 = DAG.getNode(ISD::STORE, MVT::Other, S1, + DAG.getConstant(VarArgsOffset, MVT::i64), SA2, + DAG.getSrcValue(NULL)); + + return std::make_pair(S2, S2); } std::pair<SDOperand,SDOperand> AlphaTargetLowering:: -LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, +LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { - abort(); + //FIXME: For now, ignore FP + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAList, + DAG.getConstant(8, MVT::i64)); + SDOperand Offset = DAG.getLoad(MVT::i64, Chain, Tmp, DAG.getSrcValue(NULL)); + SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); + SDOperand Result = DAG.getLoad(MVT::i64, Chain, DataPtr, + DAG.getSrcValue(NULL)); + SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, + DAG.getConstant(8, MVT::i64)); + SDOperand Update = DAG.getNode(ISD::STORE, MVT::Other, Result, NewOffset, + Tmp, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Update); } diff --git a/lib/Target/CBackend/CBacke |