ExternalFunctions.cpp revision 9dbf6dddcec7a627fabfc722e124311321de8fa0
12fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner//===-- ExternalFunctions.cpp - Implement External Functions --------------===// 27720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 32fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// This file contains both code to deal with invoking "external" functions, but 42fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// also contains code that implements "exported" external functions. 57720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 62fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// External functions in LLI are implemented by dlopen'ing the lli executable 72fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// and using dlsym to look op the functions that we want to invoke. If a 82fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// function is found, then the arguments are mangled and passed in to the 92fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// function call. 107720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 117720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 137720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "Interpreter.h" 14005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "ExecutionAnnotations.h" 15fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#include "llvm/Module.h" 167720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "llvm/DerivedTypes.h" 17005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "llvm/SymbolTable.h" 18005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "llvm/Target/TargetData.h" 197720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include <map> 207720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include <dlfcn.h> 217720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include <link.h> 22c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner#include <math.h> 23c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner#include <stdio.h> 24697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::vector; 25697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::cout; 267720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 27b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnertypedef GenericValue (*ExFunc)(FunctionType *, const vector<GenericValue> &); 28b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnerstatic std::map<const Function *, ExFunc> Functions; 29697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstatic std::map<std::string, ExFunc> FuncNames; 307720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 31e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattnerstatic Interpreter *TheInterpreter; 32e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 33e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner// getCurrentExecutablePath() - Return the directory that the lli executable 34e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner// lives in. 35e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner// 36697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstd::string Interpreter::getCurrentExecutablePath() const { 37e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner Dl_info Info; 38e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner if (dladdr(&TheInterpreter, &Info) == 0) return ""; 39e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 40697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string LinkAddr(Info.dli_fname); 41e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner unsigned SlashPos = LinkAddr.rfind('/'); 42697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner if (SlashPos != std::string::npos) 43e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner LinkAddr.resize(SlashPos); // Trim the executable name off... 44e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 45e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return LinkAddr; 46e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner} 47e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 48e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 497720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerstatic char getTypeID(const Type *Ty) { 507720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner switch (Ty->getPrimitiveID()) { 517720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::VoidTyID: return 'V'; 527720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::BoolTyID: return 'o'; 537720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::UByteTyID: return 'B'; 547720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::SByteTyID: return 'b'; 557720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::UShortTyID: return 'S'; 567720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::ShortTyID: return 's'; 577720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::UIntTyID: return 'I'; 587720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::IntTyID: return 'i'; 597720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::ULongTyID: return 'L'; 607720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::LongTyID: return 'l'; 617720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::FloatTyID: return 'F'; 627720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::DoubleTyID: return 'D'; 637720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::PointerTyID: return 'P'; 64b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner case Type::FunctionTyID: return 'M'; 657720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::StructTyID: return 'T'; 667720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::ArrayTyID: return 'A'; 677720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::OpaqueTyID: return 'O'; 687720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner default: return 'U'; 697720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 707720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 717720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 72b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnerstatic ExFunc lookupFunction(const Function *M) { 737720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // Function not found, look it up... start by figuring out what the 747720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // composite function name should be. 75697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string ExtName = "lle_"; 76b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner const FunctionType *MT = M->getFunctionType(); 777720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner for (unsigned i = 0; const Type *Ty = MT->getContainedType(i); ++i) 787720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner ExtName += getTypeID(Ty); 797720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner ExtName += "_" + M->getName(); 807720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 817720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner //cout << "Tried: '" << ExtName << "'\n"; 824721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner ExFunc FnPtr = FuncNames[ExtName]; 834721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner if (FnPtr == 0) 844721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ExtName.c_str()); 854721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner if (FnPtr == 0) 864721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FnPtr = FuncNames["lle_X_"+M->getName()]; 877720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr == 0) // Try calling a generic function... if it exists... 887720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ("lle_X_"+M->getName()).c_str()); 897720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr != 0) 90697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Functions.insert(std::make_pair(M, FnPtr)); // Cache for later 917720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner return FnPtr; 927720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 937720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 94b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue Interpreter::callExternalMethod(Function *M, 954721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner const vector<GenericValue> &ArgVals) { 96e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter = this; 97e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 982fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // Do a lookup to see if the function is in our cache... this should just be a 997720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // defered annotation! 100b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner std::map<const Function *, ExFunc>::iterator FI = Functions.find(M); 101b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner ExFunc Fn = (FI == Functions.end()) ? lookupFunction(M) : FI->second; 1027720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (Fn == 0) { 1032fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner cout << "Tried to execute an unknown external function: " 104697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << M->getType()->getDescription() << " " << M->getName() << "\n"; 1054721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner return GenericValue(); 1067720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 1077720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1087720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // TODO: FIXME when types are not const! 1092fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner GenericValue Result = Fn(const_cast<FunctionType*>(M->getFunctionType()), 1102fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner ArgVals); 1114721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner return Result; 1127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 1137720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1147720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1157720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 116b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner// Functions "exported" to the running application... 1177720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 1187720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerextern "C" { // Don't add C++ manglings to llvm mangling :) 1197720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1202e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner// Implement void printstr([ubyte {x N}] *) 121b111874b386f5e3d807a8f78edb010b40d507115Chris LattnerGenericValue lle_VP_printstr(FunctionType *M, 122b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const vector<GenericValue> &ArgVal){ 1232e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner assert(ArgVal.size() == 1 && "printstr only takes one argument!"); 124b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner cout << (char*)GVTOP(ArgVal[0]); 1252e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner return GenericValue(); 1262e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner} 1272e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 1287720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// Implement 'void print(X)' for every type... 129b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_print(FunctionType *M, const vector<GenericValue> &ArgVals) { 1307720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner assert(ArgVals.size() == 1 && "generic print only takes one argument!"); 1312e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 1322e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner Interpreter::print(M->getParamTypes()[0], ArgVals[0]); 1332e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner return GenericValue(); 1342e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner} 1352e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 1362e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner// Implement 'void printVal(X)' for every type... 137b111874b386f5e3d807a8f78edb010b40d507115Chris LattnerGenericValue lle_X_printVal(FunctionType *M, 138b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const vector<GenericValue> &ArgVal) { 1392e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner assert(ArgVal.size() == 1 && "generic print only takes one argument!"); 1402e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 141f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner // Specialize print([ubyte {x N} ] *) and print(sbyte *) 1420b12b5f50ec77a8bd01b92d287c52d748619bb4bChris Lattner if (const PointerType *PTy = 1430b12b5f50ec77a8bd01b92d287c52d748619bb4bChris Lattner dyn_cast<PointerType>(M->getParamTypes()[0].get())) 1447a1767520611d9ff6face702068de858e1cadf2cChris Lattner if (PTy->getElementType() == Type::SByteTy || 1457a1767520611d9ff6face702068de858e1cadf2cChris Lattner isa<ArrayType>(PTy->getElementType())) { 1462e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner return lle_VP_printstr(M, ArgVal); 1472e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner } 1482e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 1492e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]); 1507720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner return GenericValue(); 1517720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 1527720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1533eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve// Implement 'void printString(X)' 1543eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve// Argument must be [ubyte {x N} ] * or sbyte * 155b111874b386f5e3d807a8f78edb010b40d507115Chris LattnerGenericValue lle_X_printString(FunctionType *M, 156b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const vector<GenericValue> &ArgVal) { 1573eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve assert(ArgVal.size() == 1 && "generic print only takes one argument!"); 1583eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve return lle_VP_printstr(M, ArgVal); 1593eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve} 1603eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve 1613eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve// Implement 'void print<TYPE>(X)' for each primitive type or pointer type 1623eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve#define PRINT_TYPE_FUNC(TYPENAME,TYPEID) \ 163b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner GenericValue lle_X_print##TYPENAME(FunctionType *M,\ 164316a65bda996a5b22bf5e8dacadee848d51f6cbeChris Lattner const vector<GenericValue> &ArgVal) {\ 1653eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve assert(ArgVal.size() == 1 && "generic print only takes one argument!");\ 16669b5ce90dcd2043f5a6913665c357442b174fdd2Chris Lattner assert(M->getParamTypes()[0].get()->getPrimitiveID() == Type::TYPEID);\ 1673eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]);\ 1683eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve return GenericValue();\ 1693eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve } 1703eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve 1714721f1304f3d49e44c78c9eed882a34ad7388be0Chris LattnerPRINT_TYPE_FUNC(SByte, SByteTyID) 1723eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(UByte, UByteTyID) 1733eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Short, ShortTyID) 1743eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(UShort, UShortTyID) 1753eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Int, IntTyID) 1763eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(UInt, UIntTyID) 1773eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Long, LongTyID) 1783eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(ULong, ULongTyID) 1793eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Float, FloatTyID) 1803eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Double, DoubleTyID) 1813eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. AdvePRINT_TYPE_FUNC(Pointer, PointerTyID) 1823eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve 1833eb60f8775941422a7f04c0e16bd3a7fac9b73f5Vikram S. Adve 184005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void putchar(sbyte) 185b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_Vb_putchar(FunctionType *M, const vector<GenericValue> &Args) { 1867720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner cout << Args[0].SByteVal; 1877720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner return GenericValue(); 1887720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 1897720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 190005cbce20e55077d7e02255812e5df068188d302Chris Lattner// int putchar(int) 191b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_ii_putchar(FunctionType *M, const vector<GenericValue> &Args) { 192697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cout << ((char)Args[0].IntVal) << std::flush; 193e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return Args[0]; 194e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner} 195e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 196005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void putchar(ubyte) 197b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_VB_putchar(FunctionType *M, const vector<GenericValue> &Args) { 198697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cout << Args[0].SByteVal << std::flush; 199e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return Args[0]; 2002e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner} 2012e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 202005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void __main() 203b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_V___main(FunctionType *M, const vector<GenericValue> &Args) { 204f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner return GenericValue(); 205f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner} 206f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner 207005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void exit(int) 208b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_exit(FunctionType *M, const vector<GenericValue> &Args) { 209e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter->exitCalled(Args[0]); 210e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return GenericValue(); 211e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner} 212e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 213005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void abort(void) 2141ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris LattnerGenericValue lle_X_abort(FunctionType *M, const vector<GenericValue> &Args) { 2151ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner std::cerr << "***PROGRAM ABORTED***!\n"; 2161ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner GenericValue GV; 2171ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner GV.IntVal = 1; 2181ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner TheInterpreter->exitCalled(GV); 2191ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner return GenericValue(); 2201ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner} 2211ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner 222c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void *malloc(uint) 223b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_malloc(FunctionType *M, const vector<GenericValue> &Args) { 2244721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner assert(Args.size() == 1 && "Malloc expects one argument!"); 225b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return PTOGV(malloc(Args[0].UIntVal)); 226c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 227c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 228c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void free(void *) 229b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_free(FunctionType *M, const vector<GenericValue> &Args) { 230c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 1); 231b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner free(GVTOP(Args[0])); 232c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner return GenericValue(); 233c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 234c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 235782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// int atoi(char *) 236b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_atoi(FunctionType *M, const vector<GenericValue> &Args) { 237782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 238782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GenericValue GV; 239b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = atoi((char*)GVTOP(Args[0])); 240782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GV; 241782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 242782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner 243c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// double pow(double, double) 244b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_pow(FunctionType *M, const vector<GenericValue> &Args) { 245c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 2); 246c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner GenericValue GV; 24708845a242c574d695566cbc61e46da1c86c810acChris Lattner GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal); 248c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner return GV; 249c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 250c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 25134dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner// double exp(double) 252b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_exp(FunctionType *M, const vector<GenericValue> &Args) { 25334dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner assert(Args.size() == 1); 25434dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner GenericValue GV; 25534dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner GV.DoubleVal = exp(Args[0].DoubleVal); 25634dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner return GV; 25734dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner} 25834dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner 259c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner// double sqrt(double) 260b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sqrt(FunctionType *M, const vector<GenericValue> &Args) { 261c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 1); 262c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner GenericValue GV; 263c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner GV.DoubleVal = sqrt(Args[0].DoubleVal); 264c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner return GV; 265c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner} 266c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 2678679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double log(double) 268b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_log(FunctionType *M, const vector<GenericValue> &Args) { 2698679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner assert(Args.size() == 1); 2708679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GenericValue GV; 2718679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GV.DoubleVal = log(Args[0].DoubleVal); 2728679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner return GV; 2738679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner} 2748679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 275dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner// int isnan(double value); 276dbcda22bf31e60e197f526fd3546cd196386937aChris LattnerGenericValue lle_X_isnan(FunctionType *F, const vector<GenericValue> &Args) { 277dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner assert(Args.size() == 1); 278dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner GenericValue GV; 279dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner GV.IntVal = isnan(Args[0].DoubleVal); 280dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner return GV; 281dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner} 282dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner 283782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// double floor(double) 284b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_floor(FunctionType *M, const vector<GenericValue> &Args) { 285782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 286782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GenericValue GV; 287782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GV.DoubleVal = floor(Args[0].DoubleVal); 288782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GV; 289782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 290782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner 2918679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double drand48() 292b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_drand48(FunctionType *M, const vector<GenericValue> &Args) { 2938679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner assert(Args.size() == 0); 2948679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GenericValue GV; 2958679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GV.DoubleVal = drand48(); 2968679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner return GV; 2978679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner} 2988679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 2991b600144bda9717804ae3b998c95223947200075Chris Lattner// long lrand48() 300b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_lrand48(FunctionType *M, const vector<GenericValue> &Args) { 3011b600144bda9717804ae3b998c95223947200075Chris Lattner assert(Args.size() == 0); 3021b600144bda9717804ae3b998c95223947200075Chris Lattner GenericValue GV; 3031b600144bda9717804ae3b998c95223947200075Chris Lattner GV.IntVal = lrand48(); 3041b600144bda9717804ae3b998c95223947200075Chris Lattner return GV; 3051b600144bda9717804ae3b998c95223947200075Chris Lattner} 3061b600144bda9717804ae3b998c95223947200075Chris Lattner 3071b600144bda9717804ae3b998c95223947200075Chris Lattner// void srand48(long) 308b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_srand48(FunctionType *M, const vector<GenericValue> &Args) { 3091b600144bda9717804ae3b998c95223947200075Chris Lattner assert(Args.size() == 1); 3101b600144bda9717804ae3b998c95223947200075Chris Lattner srand48(Args[0].IntVal); 3111b600144bda9717804ae3b998c95223947200075Chris Lattner return GenericValue(); 3121b600144bda9717804ae3b998c95223947200075Chris Lattner} 3131b600144bda9717804ae3b998c95223947200075Chris Lattner 314782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// void srand(uint) 315b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_srand(FunctionType *M, const vector<GenericValue> &Args) { 316782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 317782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner srand(Args[0].UIntVal); 318782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GenericValue(); 319782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 3208679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 321b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner// int puts(const char*) 322b111874b386f5e3d807a8f78edb010b40d507115Chris LattnerGenericValue lle_X_puts(FunctionType *M, const vector<GenericValue> &Args) { 323b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner assert(Args.size() == 1); 324b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GenericValue GV; 325b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = puts((char*)GVTOP(Args[0])); 326b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return GV; 327b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner} 328b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner 329e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make 330e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// output useful. 331b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sprintf(FunctionType *M, const vector<GenericValue> &Args) { 332b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner char *OutputBuffer = (char *)GVTOP(Args[0]); 333b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const char *FmtStr = (const char *)GVTOP(Args[1]); 334e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner unsigned ArgNo = 2; 33508845a242c574d695566cbc61e46da1c86c810acChris Lattner 33608845a242c574d695566cbc61e46da1c86c810acChris Lattner // printf should return # chars printed. This is completely incorrect, but 33708845a242c574d695566cbc61e46da1c86c810acChris Lattner // close enough for now. 33808845a242c574d695566cbc61e46da1c86c810acChris Lattner GenericValue GV; GV.IntVal = strlen(FmtStr); 33908845a242c574d695566cbc61e46da1c86c810acChris Lattner while (1) { 34008845a242c574d695566cbc61e46da1c86c810acChris Lattner switch (*FmtStr) { 34108845a242c574d695566cbc61e46da1c86c810acChris Lattner case 0: return GV; // Null terminator... 34208845a242c574d695566cbc61e46da1c86c810acChris Lattner default: // Normal nonspecial character 343e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer++, "%c", *FmtStr++); 34408845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 34508845a242c574d695566cbc61e46da1c86c810acChris Lattner case '\\': { // Handle escape codes 346e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1)); 347e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FmtStr += 2; OutputBuffer += 2; 34808845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 34908845a242c574d695566cbc61e46da1c86c810acChris Lattner } 35008845a242c574d695566cbc61e46da1c86c810acChris Lattner case '%': { // Handle format specifiers 351ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char FmtBuf[100] = "", Buffer[1000] = ""; 352ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char *FB = FmtBuf; 353ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB++ = *FmtStr++; 354ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char Last = *FB++ = *FmtStr++; 355ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner unsigned HowLong = 0; 356ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' && 357ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' && 358ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' && 359ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'p' && Last != 's' && Last != '%') { 360ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner if (Last == 'l' || Last == 'L') HowLong++; // Keep track of l's 361ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last = *FB++ = *FmtStr++; 36208845a242c574d695566cbc61e46da1c86c810acChris Lattner } 363ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB = 0; 364ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner 365ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner switch (Last) { 366ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case '%': 367ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf); break; 368ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'c': 3692012d5e33ffa601eb1c58f6830017dce1a1774b3Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break; 370ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'd': case 'i': 371ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'u': case 'o': 372ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'x': case 'X': 37369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner if (HowLong >= 1) { 37469ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner if (HowLong == 1) { 37569ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // Make sure we use %lld with a 64 bit argument because we might be 37669ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // compiling LLI on a 32 bit compiler. 37769ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner unsigned Size = strlen(FmtBuf); 37869ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size] = FmtBuf[Size-1]; 37969ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size+1] = 0; 38069ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size-1] = 'l'; 38169ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } 382ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].ULongVal); 38369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } else 384ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break; 385ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'e': case 'E': case 'g': case 'G': case 'f': 386ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break; 387ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'p': 388b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break; 389ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 's': 390b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break; 391ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner default: cout << "<unknown printf code '" << *FmtStr << "'!>"; 392ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner ArgNo++; break; 393ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner } 394e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner strcpy(OutputBuffer, Buffer); 395e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner OutputBuffer += strlen(Buffer); 39608845a242c574d695566cbc61e46da1c86c810acChris Lattner } 39708845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 39808845a242c574d695566cbc61e46da1c86c810acChris Lattner } 39908845a242c574d695566cbc61e46da1c86c810acChris Lattner } 40008845a242c574d695566cbc61e46da1c86c810acChris Lattner} 40108845a242c574d695566cbc61e46da1c86c810acChris Lattner 402e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int printf(sbyte *, ...) - a very rough implementation to make output useful. 403b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_printf(FunctionType *M, const vector<GenericValue> &Args) { 404e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner char Buffer[10000]; 405e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner vector<GenericValue> NewArgs; 406b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner NewArgs.push_back(PTOGV(Buffer)); 407e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin(), Args.end()); 408b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GenericValue GV = lle_X_sprintf(M, NewArgs); 409e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner cout << Buffer; 410e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner return GV; 411e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner} 412e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner 413f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattnerstatic void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1, 414f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg2, void *Arg3, void *Arg4, void *Arg5, 415f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg6, void *Arg7, void *Arg8) { 416f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 }; 417f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 418f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Loop over the format string, munging read values as appropriate (performs 419f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // byteswaps as neccesary). 420f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned ArgNo = 0; 421f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (*Fmt) { 422f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (*Fmt++ == '%') { 423f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read any flag characters that may be present... 424f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Suppress = false; 425f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Half = false; 426f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Long = false; 427f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool LongLong = false; // long long or long double 428f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 429f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (1) { 430f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (*Fmt++) { 431f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case '*': Suppress = true; break; 432f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'a': /*Allocate = true;*/ break; // We don't need to track this 433f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'h': Half = true; break; 434f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'l': Long = true; break; 435f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'q': 436f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'L': LongLong = true; break; 437f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: 438f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Fmt[-1] > '9' || Fmt[-1] < '0') // Ignore field width specs 439f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner goto Out; 440f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 441f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 442f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Out: 443f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 444f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read the conversion character 445f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (!Suppress && Fmt[-1] != '%') { // Nothing to do? 446f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned Size = 0; 447f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner const Type *Ty = 0; 448f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 449f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (Fmt[-1]) { 450f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p': 451f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'd': 452f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 453f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 8; Ty = Type::ULongTy; 454f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else if (Half) { 455f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 4; Ty = Type::UShortTy; 456f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 457f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 4; Ty = Type::UIntTy; 458f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 459f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 460f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 461f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'e': case 'g': case 'E': 462f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'f': 463f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 464f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 8; Ty = Type::DoubleTy; 465f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 466f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 4; Ty = Type::FloatTy; 467f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 468f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 469f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 470f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 's': case 'c': case '[': // No byteswap needed 471f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 1; 472f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Ty = Type::SByteTy; 473f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 474f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 475f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: break; 476f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 477f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 478f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Size) { 479f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 480f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg = Args[ArgNo++]; 481f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner memcpy(&GV, Arg, Size); 482f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty); 483f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 484f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 485f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 486f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 487f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 488f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 489665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int sscanf(const char *format, ...); 490b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sscanf(FunctionType *M, const vector<GenericValue> &args) { 491665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); 492665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 493f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 494665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 495f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 496665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 497665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 498665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GV.IntVal = sscanf(Args[0], Args[1], Args[2], Args[3], Args[4], 499665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9]); 500f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4], 501f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9], 0); 502f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner return GV; 503f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 504f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 505f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner// int scanf(const char *format, ...); 506f9a88b684d8ca368ad51695c61a3580f4700da52Chris LattnerGenericValue lle_X_scanf(FunctionType *M, const vector<GenericValue> &args) { 507f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); 508f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 509f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 510f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 511f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 512f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 513f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 514f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GV.IntVal = scanf(Args[0], Args[1], Args[2], Args[3], Args[4], 515f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9]); 516f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4], 517f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9]); 518665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 519665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 520665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 521665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 522295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner// int clock(void) - Profiling implementation 523b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_i_clock(FunctionType *M, const vector<GenericValue> &Args) { 524295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner extern int clock(void); 525295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner GenericValue GV; GV.IntVal = clock(); 526295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner return GV; 527295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner} 528e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner 529665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===// 530665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// IO Functions... 531665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===// 532665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 533005cbce20e55077d7e02255812e5df068188d302Chris Lattner// getFILE - Turn a pointer in the host address space into a legit pointer in 534005cbce20e55077d7e02255812e5df068188d302Chris Lattner// the interpreter address space. For the most part, this is an identity 535005cbce20e55077d7e02255812e5df068188d302Chris Lattner// transformation, but if the program refers to stdio, stderr, stdin then they 536005cbce20e55077d7e02255812e5df068188d302Chris Lattner// have pointers that are relative to the __iob array. If this is the case, 537005cbce20e55077d7e02255812e5df068188d302Chris Lattner// change the FILE into the REAL stdio stream. 538005cbce20e55077d7e02255812e5df068188d302Chris Lattner// 539b111874b386f5e3d807a8f78edb010b40d507115Chris Lattnerstatic FILE *getFILE(void *Ptr) { 540005cbce20e55077d7e02255812e5df068188d302Chris Lattner static Module *LastMod = 0; 541005cbce20e55077d7e02255812e5df068188d302Chris Lattner static PointerTy IOBBase = 0; 542005cbce20e55077d7e02255812e5df068188d302Chris Lattner static unsigned FILESize; 543005cbce20e55077d7e02255812e5df068188d302Chris Lattner 544fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner if (LastMod != &TheInterpreter->getModule()) { // Module change or initialize? 545fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner Module *M = LastMod = &TheInterpreter->getModule(); 546005cbce20e55077d7e02255812e5df068188d302Chris Lattner 547005cbce20e55077d7e02255812e5df068188d302Chris Lattner // Check to see if the currently loaded module contains an __iob symbol... 548005cbce20e55077d7e02255812e5df068188d302Chris Lattner GlobalVariable *IOB = 0; 5496e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner SymbolTable &ST = M->getSymbolTable(); 5506e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) { 5516e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner SymbolTable::VarMap &M = I->second; 5526e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner for (SymbolTable::VarMap::iterator J = M.begin(), E = M.end(); 5536e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner J != E; ++J) 5546e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner if (J->first == "__iob") 5556e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner if ((IOB = dyn_cast<GlobalVariable>(J->second))) 5566e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner break; 5576e6026b46569b01f8f6d4dcdb6c899c3a9c76b3eChris Lattner if (IOB) break; 558005cbce20e55077d7e02255812e5df068188d302Chris Lattner } 559005cbce20e55077d7e02255812e5df068188d302Chris Lattner 560fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#if 0 /// FIXME! __iob support for LLI 561005cbce20e55077d7e02255812e5df068188d302Chris Lattner // If we found an __iob symbol now, find out what the actual address it's 562005cbce20e55077d7e02255812e5df068188d302Chris Lattner // held in is... 563005cbce20e55077d7e02255812e5df068188d302Chris Lattner if (IOB) { 564005cbce20e55077d7e02255812e5df068188d302Chris Lattner // Get the address the array lives in... 565005cbce20e55077d7e02255812e5df068188d302Chris Lattner GlobalAddress *Address = 566005cbce20e55077d7e02255812e5df068188d302Chris Lattner (GlobalAddress*)IOB->getOrCreateAnnotation(GlobalAddressAID); 567005cbce20e55077d7e02255812e5df068188d302Chris Lattner IOBBase = (PointerTy)(GenericValue*)Address->Ptr; 568005cbce20e55077d7e02255812e5df068188d302Chris Lattner 569005cbce20e55077d7e02255812e5df068188d302Chris Lattner // Figure out how big each element of the array is... 570005cbce20e55077d7e02255812e5df068188d302Chris Lattner const ArrayType *AT = 571005cbce20e55077d7e02255812e5df068188d302Chris Lattner dyn_cast<ArrayType>(IOB->getType()->getElementType()); 572005cbce20e55077d7e02255812e5df068188d302Chris Lattner if (AT) 573005cbce20e55077d7e02255812e5df068188d302Chris Lattner FILESize = TD.getTypeSize(AT->getElementType()); 574005cbce20e55077d7e02255812e5df068188d302Chris Lattner else 575005cbce20e55077d7e02255812e5df068188d302Chris Lattner FILESize = 16*8; // Default size 576005cbce20e55077d7e02255812e5df068188d302Chris Lattner } 577fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#endif 578005cbce20e55077d7e02255812e5df068188d302Chris Lattner } 579005cbce20e55077d7e02255812e5df068188d302Chris Lattner 580005cbce20e55077d7e02255812e5df068188d302Chris Lattner // Check to see if this is a reference to __iob... 581005cbce20e55077d7e02255812e5df068188d302Chris Lattner if (IOBBase) { 582b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner unsigned FDNum = ((unsigned long)Ptr-IOBBase)/FILESize; 583005cbce20e55077d7e02255812e5df068188d302Chris Lattner if (FDNum == 0) 584005cbce20e55077d7e02255812e5df068188d302Chris Lattner return stdin; 585005cbce20e55077d7e02255812e5df068188d302Chris Lattner else if (FDNum == 1) 586005cbce20e55077d7e02255812e5df068188d302Chris Lattner return stdout; 587005cbce20e55077d7e02255812e5df068188d302Chris Lattner else if (FDNum == 2) 588005cbce20e55077d7e02255812e5df068188d302Chris Lattner return stderr; 589005cbce20e55077d7e02255812e5df068188d302Chris Lattner } 590005cbce20e55077d7e02255812e5df068188d302Chris Lattner 591005cbce20e55077d7e02255812e5df068188d302Chris Lattner return (FILE*)Ptr; 592005cbce20e55077d7e02255812e5df068188d302Chris Lattner} 593005cbce20e55077d7e02255812e5df068188d302Chris Lattner 594005cbce20e55077d7e02255812e5df068188d302Chris Lattner 595665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// FILE *fopen(const char *filename, const char *mode); 596b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fopen(FunctionType *M, const vector<GenericValue> &Args) { 597665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 2); 598b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return PTOGV(fopen((const char *)GVTOP(Args[0]), 599b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner (const char *)GVTOP(Args[1]))); 600665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 601665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 602665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fclose(FILE *F); 603b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fclose(FunctionType *M, const vector<GenericValue> &Args) { 604665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 1); 605665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 606b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = fclose(getFILE(GVTOP(Args[0]))); 607665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 608665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 609665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 61025f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner// int feof(FILE *stream); 61125f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris LattnerGenericValue lle_X_feof(FunctionType *M, const vector<GenericValue> &Args) { 61225f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner assert(Args.size() == 1); 61325f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner GenericValue GV; 61425f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner 615b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = feof(getFILE(GVTOP(Args[0]))); 61625f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner return GV; 61725f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner} 61825f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner 619665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); 620b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fread(FunctionType *M, const vector<GenericValue> &Args) { 621665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 4); 622665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 623665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 624b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.UIntVal = fread((void*)GVTOP(Args[0]), Args[1].UIntVal, 625b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner Args[2].UIntVal, getFILE(GVTOP(Args[3]))); 626665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 627665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 628665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 629665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); 630b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fwrite(FunctionType *M, const vector<GenericValue> &Args) { 631665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 4); 632665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 633665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 634b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.UIntVal = fwrite((void*)GVTOP(Args[0]), Args[1].UIntVal, 635b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner Args[2].UIntVal, getFILE(GVTOP(Args[3]))); 636665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 637665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 638665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 639665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// char *fgets(char *s, int n, FILE *stream); 640b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fgets(FunctionType *M, const vector<GenericValue> &Args) { 641665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 3); 642b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return GVTOP(fgets((char*)GVTOP(Args[0]), Args[1].IntVal, 643b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner getFILE(GVTOP(Args[2])))); 644665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 645665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 646a4479cd94615f84fe87533081e521669113557c7Chris Lattner// FILE *freopen(const char *path, const char *mode, FILE *stream); 647a4479cd94615f84fe87533081e521669113557c7Chris LattnerGenericValue lle_X_freopen(FunctionType *M, const vector<GenericValue> &Args) { 648a4479cd94615f84fe87533081e521669113557c7Chris Lattner assert(Args.size() == 3); 649b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), 650b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner getFILE(GVTOP(Args[2])))); 651a4479cd94615f84fe87533081e521669113557c7Chris Lattner} 652a4479cd94615f84fe87533081e521669113557c7Chris Lattner 653665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fflush(FILE *stream); 654b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fflush(FunctionType *M, const vector<GenericValue> &Args) { 655665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 1); 656665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 657b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = fflush(getFILE(GVTOP(Args[0]))); 658005cbce20e55077d7e02255812e5df068188d302Chris Lattner return GV; 659005cbce20e55077d7e02255812e5df068188d302Chris Lattner} 660005cbce20e55077d7e02255812e5df068188d302Chris Lattner 661005cbce20e55077d7e02255812e5df068188d302Chris Lattner// int getc(FILE *stream); 662005cbce20e55077d7e02255812e5df068188d302Chris LattnerGenericValue lle_X_getc(FunctionType *M, const vector<GenericValue> &Args) { 663005cbce20e55077d7e02255812e5df068188d302Chris Lattner assert(Args.size() == 1); 664005cbce20e55077d7e02255812e5df068188d302Chris Lattner GenericValue GV; 665b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = getc(getFILE(GVTOP(Args[0]))); 666665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 667665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 668665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 669a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int fputc(int C, FILE *stream); 670a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris LattnerGenericValue lle_X_fputc(FunctionType *M, const vector<GenericValue> &Args) { 671a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner assert(Args.size() == 2); 672a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner GenericValue GV; 673b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = fputc(Args[0].IntVal, getFILE(GVTOP(Args[1]))); 674a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner return GV; 675a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner} 676a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner 677a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int ungetc(int C, FILE *stream); 678a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris LattnerGenericValue lle_X_ungetc(FunctionType *M, const vector<GenericValue> &Args) { 679a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner assert(Args.size() == 2); 680a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner GenericValue GV; 681b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GV.IntVal = ungetc(Args[0].IntVal, getFILE(GVTOP(Args[1]))); 682a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner return GV; 683a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner} 684a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner 685cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output 686cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// useful. 687cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris LattnerGenericValue lle_X_fprintf(FunctionType *M, const vector<GenericValue> &Args) { 6889dbf6dddcec7a627fabfc722e124311321de8fa0Chris Lattner assert(Args.size() >= 2); 689cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner char Buffer[10000]; 690cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner vector<GenericValue> NewArgs; 691b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner NewArgs.push_back(PTOGV(Buffer)); 692cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end()); 693b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GenericValue GV = lle_X_sprintf(M, NewArgs); 694cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 695b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner fputs(Buffer, getFILE(GVTOP(Args[0]))); 696cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner return GV; 697cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner} 698cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 6997720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} // End extern "C" 7004721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 7014721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 7024721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattnervoid Interpreter::initializeExternalMethods() { 7034721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_VP_printstr"] = lle_VP_printstr; 7044721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_print"] = lle_X_print; 7054721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printVal"] = lle_X_printVal; 7064721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printString"] = lle_X_printString; 7074721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printUByte"] = lle_X_printUByte; 7084721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printSByte"] = lle_X_printSByte; 7094721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printUShort"] = lle_X_printUShort; 7104721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printShort"] = lle_X_printShort; 7114721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printInt"] = lle_X_printInt; 7124721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printUInt"] = lle_X_printUInt; 7134721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printLong"] = lle_X_printLong; 7144721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printULong"] = lle_X_printULong; 7154721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printFloat"] = lle_X_printFloat; 7164721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printDouble"] = lle_X_printDouble; 7174721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner FuncNames["lle_X_printPointer"] = lle_X_printPointer; 7180f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_Vb_putchar"] = lle_Vb_putchar; 7190f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_ii_putchar"] = lle_ii_putchar; 7200f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_VB_putchar"] = lle_VB_putchar; 7210f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_V___main"] = lle_V___main; 7220f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_exit"] = lle_X_exit; 7231ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner FuncNames["lle_X_abort"] = lle_X_abort; 7240f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_malloc"] = lle_X_malloc; 7250f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_free"] = lle_X_free; 726782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_atoi"] = lle_X_atoi; 7270f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_pow"] = lle_X_pow; 72834dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner FuncNames["lle_X_exp"] = lle_X_exp; 7291b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_log"] = lle_X_log; 730dbcda22bf31e60e197f526fd3546cd196386937aChris Lattner FuncNames["lle_X_isnan"] = lle_X_isnan; 731782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_floor"] = lle_X_floor; 732782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_srand"] = lle_X_srand; 7331b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_drand48"] = lle_X_drand48; 7341b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_srand48"] = lle_X_srand48; 7351b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_lrand48"] = lle_X_lrand48; 736c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner FuncNames["lle_X_sqrt"] = lle_X_sqrt; 737b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner FuncNames["lle_X_puts"] = lle_X_puts; 7380f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_printf"] = lle_X_printf; 739e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FuncNames["lle_X_sprintf"] = lle_X_sprintf; 740665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_sscanf"] = lle_X_sscanf; 741f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner FuncNames["lle_X_scanf"] = lle_X_scanf; 742295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner FuncNames["lle_i_clock"] = lle_i_clock; 743665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fopen"] = lle_X_fopen; 744665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fclose"] = lle_X_fclose; 74525f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner FuncNames["lle_X_feof"] = lle_X_feof; 746665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fread"] = lle_X_fread; 747665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fwrite"] = lle_X_fwrite; 748665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fgets"] = lle_X_fgets; 749665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fflush"] = lle_X_fflush; 750a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_fgetc"] = lle_X_getc; 751005cbce20e55077d7e02255812e5df068188d302Chris Lattner FuncNames["lle_X_getc"] = lle_X_getc; 752a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_fputc"] = lle_X_fputc; 753a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_ungetc"] = lle_X_ungetc; 754cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner FuncNames["lle_X_fprintf"] = lle_X_fprintf; 755a4479cd94615f84fe87533081e521669113557c7Chris Lattner FuncNames["lle_X_freopen"] = lle_X_freopen; 7564721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner} 757