diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 852bca6b83b..eb1193a6180 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -761,78 +761,7 @@ static void executeGEPInst(GetElementPtrInst &I, ExecutionContext &SF) { void Interpreter::executeLoadInst(LoadInst &I, ExecutionContext &SF) { GenericValue SRC = getOperandValue(I.getPointerOperand(), SF); GenericValue *Ptr = (GenericValue*)GVTOP(SRC); - GenericValue Result; - - if (TD.isLittleEndian()) { - switch (I.getType()->getPrimitiveID()) { - case Type::BoolTyID: - case Type::UByteTyID: - case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; - case Type::UShortTyID: - case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[0] | - ((unsigned)Ptr->Untyped[1] << 8); - break; - Load4BytesLittleEndian: - case Type::FloatTyID: - case Type::UIntTyID: - case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[0] | - ((unsigned)Ptr->Untyped[1] << 8) | - ((unsigned)Ptr->Untyped[2] << 16) | - ((unsigned)Ptr->Untyped[3] << 24); - break; - case Type::PointerTyID: if (getModule().has32BitPointers()) - goto Load4BytesLittleEndian; - case Type::DoubleTyID: - case Type::ULongTyID: - case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] | - ((uint64_t)Ptr->Untyped[1] << 8) | - ((uint64_t)Ptr->Untyped[2] << 16) | - ((uint64_t)Ptr->Untyped[3] << 24) | - ((uint64_t)Ptr->Untyped[4] << 32) | - ((uint64_t)Ptr->Untyped[5] << 40) | - ((uint64_t)Ptr->Untyped[6] << 48) | - ((uint64_t)Ptr->Untyped[7] << 56); - break; - default: - std::cout << "Cannot load value of type " << *I.getType() << "!\n"; - abort(); - } - } else { - switch (I.getType()->getPrimitiveID()) { - case Type::BoolTyID: - case Type::UByteTyID: - case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; - case Type::UShortTyID: - case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[1] | - ((unsigned)Ptr->Untyped[0] << 8); - break; - Load4BytesBigEndian: - case Type::FloatTyID: - case Type::UIntTyID: - case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[3] | - ((unsigned)Ptr->Untyped[2] << 8) | - ((unsigned)Ptr->Untyped[1] << 16) | - ((unsigned)Ptr->Untyped[0] << 24); - break; - case Type::PointerTyID: if (getModule().has32BitPointers()) - goto Load4BytesBigEndian; - case Type::DoubleTyID: - case Type::ULongTyID: - case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] | - ((uint64_t)Ptr->Untyped[6] << 8) | - ((uint64_t)Ptr->Untyped[5] << 16) | - ((uint64_t)Ptr->Untyped[4] << 24) | - ((uint64_t)Ptr->Untyped[3] << 32) | - ((uint64_t)Ptr->Untyped[2] << 40) | - ((uint64_t)Ptr->Untyped[1] << 48) | - ((uint64_t)Ptr->Untyped[0] << 56); - break; - default: - std::cout << "Cannot load value of type " << *I.getType() << "!\n"; - abort(); - } - } - + GenericValue Result = LoadValueFromMemory(Ptr, I.getType()); SetValue(&I, Result, SF); } @@ -1009,6 +938,26 @@ static void executeCastInst(CastInst &I, ExecutionContext &SF) { SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); } +static void executeVarArgInst(VarArgInst &I, ExecutionContext &SF) { + // Get the pointer to the valist element. LLI treats the valist in memory as + // an integer. + GenericValue VAListPtr = getOperandValue(I.getOperand(0), SF); + + // Load the pointer + GenericValue VAList = + TheEE->LoadValueFromMemory((GenericValue *)GVTOP(VAListPtr), Type::UIntTy); + + unsigned Argument = VAList.IntVal++; + + // Update the valist to point to the next argument... + TheEE->StoreValueToMemory(VAList, (GenericValue *)GVTOP(VAListPtr), + Type::UIntTy); + + // Set the value... + assert(Argument < SF.VarArgs.size() && + "Accessing past the last vararg argument!"); + SetValue(&I, SF.VarArgs[Argument], SF); +} //===----------------------------------------------------------------------===// // Dispatch and Execution Code @@ -1166,9 +1115,10 @@ bool Interpreter::executeInstruction() { // Miscellaneous Instructions case Instruction::Call: executeCallInst (cast (I), SF); break; case Instruction::PHINode: executePHINode (cast (I), SF); break; + case Instruction::Cast: executeCastInst (cast (I), SF); break; case Instruction::Shl: executeShlInst (cast(I), SF); break; case Instruction::Shr: executeShrInst (cast(I), SF); break; - case Instruction::Cast: executeCastInst (cast (I), SF); break; + case Instruction::VarArg: executeVarArgInst(cast(I),SF); break; default: std::cout << "Don't know how to execute this instruction!\n-->" << I; abort(); diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index ef81c128b12..88b994caad9 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -695,6 +695,35 @@ GenericValue lle_X_fprintf(FunctionType *M, const vector &Args) { return GV; } +//===----------------------------------------------------------------------===// +// LLVM Intrinsic Functions... +//===----------------------------------------------------------------------===// + +// void llvm.va_start( *) - Implement the va_start operation... +GenericValue llvm_va_start(FunctionType *F, const vector &Args) { + assert(Args.size() == 1); + GenericValue *VAListP = (GenericValue *)GVTOP(Args[0]); + GenericValue Val; + Val.UIntVal = 0; // Start at the first '...' argument... + TheInterpreter->StoreValueToMemory(Val, VAListP, Type::UIntTy); + return GenericValue(); +} + +// void llvm.va_end( *) - Implement the va_end operation... +GenericValue llvm_va_end(FunctionType *F, const vector &Args) { + assert(Args.size() == 1); + return GenericValue(); // Noop! +} + +// void llvm.va_copy( *, ) - Implement the va_copy +// operation... +GenericValue llvm_va_copy(FunctionType *F, const vector &Args) { + assert(Args.size() == 2); + GenericValue *DestVAList = (GenericValue*)GVTOP(Args[0]); + TheInterpreter->StoreValueToMemory(Args[1], DestVAList, Type::UIntTy); + return GenericValue(); +} + } // End extern "C" @@ -748,4 +777,8 @@ void Interpreter::initializeExternalFunctions() { FuncNames["lle_X_ungetc"] = lle_X_ungetc; FuncNames["lle_X_fprintf"] = lle_X_fprintf; FuncNames["lle_X_freopen"] = lle_X_freopen; + + FuncNames["lle_X_llvm.va_start"]= llvm_va_start; + FuncNames["lle_X_llvm.va_end"] = llvm_va_end; + FuncNames["lle_X_llvm.va_copy"] = llvm_va_copy; }