ExternalFunctions.cpp revision 42346f58d810204606ea5ec3d2e583b0a6da2531
12fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner//===-- ExternalFunctions.cpp - Implement External Functions --------------===// 2d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 7d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 102fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// This file contains both code to deal with invoking "external" functions, but 112fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// also contains code that implements "exported" external functions. 127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 13d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// External functions in the interpreter are implemented by 1458a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke// using the system's dynamic loader to look up the address of the function 1558a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke// we want to invoke. If a function is found, then one of the 1658a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke// many lle_* wrapper functions in this file will translate its arguments from 1758a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke// GenericValues to the types the function is actually expecting, before the 1858a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke// function is called. 197720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 207720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 217720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 227720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "Interpreter.h" 237720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "llvm/DerivedTypes.h" 24b8d15b2ad0a2266b275a00f07410e6c9d9ca6695Misha Brukman#include "llvm/Module.h" 25480f093dc2b6aff9b501cc56cf5728513e55be81Bill Wendling#include "llvm/Support/Streams.h" 26df5a37efc997288da520ff4889443e3560d95387Reid Spencer#include "llvm/System/DynamicLibrary.h" 27005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "llvm/Target/TargetData.h" 28936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose III#include "llvm/Support/ManagedStatic.h" 29b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke#include <csignal> 30b8d15b2ad0a2266b275a00f07410e6c9d9ca6695Misha Brukman#include <map> 3197af751deb9b26fd42fbcee082da9ccc4ded5b45Jeff Cohen#include <cmath> 32697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::vector; 337720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 34f7a743d7ed6e96af4c836e512c9cd59812c8186eChris Lattnerusing namespace llvm; 35d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 36b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnertypedef GenericValue (*ExFunc)(FunctionType *, const vector<GenericValue> &); 37936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose IIIstatic ManagedStatic<std::map<const Function *, ExFunc> > Functions; 38697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstatic std::map<std::string, ExFunc> FuncNames; 397720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 40e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattnerstatic Interpreter *TheInterpreter; 41e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 427720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerstatic char getTypeID(const Type *Ty) { 43f70c22b019494723d0e706f93d6542dfaa6e73a5Chris Lattner switch (Ty->getTypeID()) { 447720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::VoidTyID: return 'V'; 45a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case Type::IntegerTyID: 46a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer switch (cast<IntegerType>(Ty)->getBitWidth()) { 47a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 1: return 'o'; 48a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 8: return 'B'; 49a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 16: return 'S'; 50a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 32: return 'I'; 51a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 64: return 'L'; 52a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer default: return 'N'; 53a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer } 547720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::FloatTyID: return 'F'; 557720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::DoubleTyID: return 'D'; 567720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::PointerTyID: return 'P'; 57e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer case Type::FunctionTyID:return 'M'; 587720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::StructTyID: return 'T'; 597720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::ArrayTyID: return 'A'; 607720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::OpaqueTyID: return 'O'; 617720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner default: return 'U'; 627720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 637720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 647720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 6542346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// Try to find address of external function given a Function object. 6642346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// Please note, that interpreter doesn't know how to assemble a 6742346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// real call in general case (this is JIT job), that's why it assumes, 6842346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// that all external functions has the same (and pretty "general") signature. 6942346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// The typical example of such functions are "lle_X_" ones. 7058a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaekestatic ExFunc lookupFunction(const Function *F) { 717720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // Function not found, look it up... start by figuring out what the 727720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // composite function name should be. 73697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string ExtName = "lle_"; 7458a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke const FunctionType *FT = F->getFunctionType(); 7558a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i) 7658a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke ExtName += getTypeID(FT->getContainedType(i)); 7758a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke ExtName += "_" + F->getName(); 787720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 794721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner ExFunc FnPtr = FuncNames[ExtName]; 804721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner if (FnPtr == 0) 8158a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke FnPtr = FuncNames["lle_X_"+F->getName()]; 827720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr == 0) // Try calling a generic function... if it exists... 8326e6e109d559fb644b59231c14346997290dc9d6Chris Lattner FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol( 84df5a37efc997288da520ff4889443e3560d95387Reid Spencer ("lle_X_"+F->getName()).c_str()); 85cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer if (FnPtr == 0) 86cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer FnPtr = (ExFunc)(intptr_t) 87cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName()); 887720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr != 0) 89936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose III Functions->insert(std::make_pair(F, FnPtr)); // Cache for later 907720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner return FnPtr; 917720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 927720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 934e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris LattnerGenericValue Interpreter::callExternalFunction(Function *F, 9444edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner const std::vector<GenericValue> &ArgVals) { 95e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter = this; 96e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 972fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // Do a lookup to see if the function is in our cache... this should just be a 98d5d96b9fcd779806555cf5db602f80d5a308a471Misha Brukman // deferred annotation! 99936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose III std::map<const Function *, ExFunc>::iterator FI = Functions->find(F); 100936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose III ExFunc Fn = (FI == Functions->end()) ? lookupFunction(F) : FI->second; 1017720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (Fn == 0) { 102e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << "Tried to execute an unknown external function: " 103e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling << F->getType()->getDescription() << " " << F->getName() << "\n"; 1044e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner if (F->getName() == "__main") 1054e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner return GenericValue(); 1064e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner abort(); 1077720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 1087720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1097720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // TODO: FIXME when types are not const! 1104e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner GenericValue Result = Fn(const_cast<FunctionType*>(F->getFunctionType()), 1112fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner ArgVals); 1124721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner return Result; 1137720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 1147720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1157720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 1167720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 117b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner// Functions "exported" to the running application... 1187720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 1197720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerextern "C" { // Don't add C++ manglings to llvm mangling :) 1207720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 121005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void putchar(ubyte) 122b3b0727032e58c8b8f3017c2b3f560616c6905afReid SpencerGenericValue lle_X_putchar(FunctionType *FT, const vector<GenericValue> &Args){ 123bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer cout << ((char)Args[0].IntVal.getZExtValue()) << std::flush; 124e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return Args[0]; 1252e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner} 1262e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner 127cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer// void _IO_putc(int c, FILE* fp) 128cc442cabf6585084ae6238f8003c14e5ebc386f6Reid SpencerGenericValue lle_X__IO_putc(FunctionType *FT, const vector<GenericValue> &Args){ 129cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer#ifdef __linux__ 130cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer _IO_putc((char)Args[0].IntVal.getZExtValue(), (FILE*) Args[1].PointerVal); 131cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer#else 132cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer assert(0 && "Can't call _IO_putc on this platform"); 133cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer#endif 134cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer return Args[0]; 135cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer} 136cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer 13744edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner// void atexit(Function*) 13897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_atexit(FunctionType *FT, const vector<GenericValue> &Args) { 13944edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner assert(Args.size() == 1); 14044edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0])); 14144edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner GenericValue GV; 142bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = 0; 14344edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner return GV; 144f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner} 145f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner 146005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void exit(int) 14797e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_exit(FunctionType *FT, const vector<GenericValue> &Args) { 148e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter->exitCalled(Args[0]); 149e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return GenericValue(); 150e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner} 151e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 152005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void abort(void) 15397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_abort(FunctionType *FT, const vector<GenericValue> &Args) { 154b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke raise (SIGABRT); 1551ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner return GenericValue(); 1561ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner} 1571ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner 158c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void *malloc(uint) 15997e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_malloc(FunctionType *FT, const vector<GenericValue> &Args) { 1604721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner assert(Args.size() == 1 && "Malloc expects one argument!"); 16197e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "malloc must return pointer"); 162bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer return PTOGV(malloc(Args[0].IntVal.getZExtValue())); 163c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 164c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 165957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// void *calloc(uint, uint) 16697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_calloc(FunctionType *FT, const vector<GenericValue> &Args) { 167957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner assert(Args.size() == 2 && "calloc expects two arguments!"); 16897e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "calloc must return pointer"); 169bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer return PTOGV(calloc(Args[0].IntVal.getZExtValue(), 170bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Args[1].IntVal.getZExtValue())); 171957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 172957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 17397e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer// void *calloc(uint, uint) 17497e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_realloc(FunctionType *FT, const vector<GenericValue> &Args) { 17597e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(Args.size() == 2 && "calloc expects two arguments!"); 17697e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) &&"realloc must return pointer"); 17797e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer return PTOGV(realloc(GVTOP(Args[0]), Args[1].IntVal.getZExtValue())); 17897e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer} 17997e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer 180c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void free(void *) 18197e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_free(FunctionType *FT, const vector<GenericValue> &Args) { 182c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 1); 183b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner free(GVTOP(Args[0])); 184c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner return GenericValue(); 185c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 186c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 187782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// int atoi(char *) 18897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_atoi(FunctionType *FT, const vector<GenericValue> &Args) { 189782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 190782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GenericValue GV; 191bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, atoi((char*)GVTOP(Args[0]))); 192782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GV; 193782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 194782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner 195c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// double pow(double, double) 19697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_pow(FunctionType *FT, const vector<GenericValue> &Args) { 197c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 2); 198c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner GenericValue GV; 19908845a242c574d695566cbc61e46da1c86c810acChris Lattner GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal); 200c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner return GV; 201c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner} 202c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 20334dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner// double exp(double) 20497e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_exp(FunctionType *FT, const vector<GenericValue> &Args) { 20534dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner assert(Args.size() == 1); 20634dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner GenericValue GV; 20734dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner GV.DoubleVal = exp(Args[0].DoubleVal); 20834dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner return GV; 20934dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner} 21034dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner 211c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner// double sqrt(double) 21297e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_sqrt(FunctionType *FT, const vector<GenericValue> &Args) { 213c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner assert(Args.size() == 1); 214c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner GenericValue GV; 215c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner GV.DoubleVal = sqrt(Args[0].DoubleVal); 216c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner return GV; 217c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner} 218c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner 2198679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double log(double) 22097e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_log(FunctionType *FT, const vector<GenericValue> &Args) { 2218679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner assert(Args.size() == 1); 2228679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GenericValue GV; 2238679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GV.DoubleVal = log(Args[0].DoubleVal); 2248679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner return GV; 2258679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner} 2268679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 227782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// double floor(double) 22897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_floor(FunctionType *FT, const vector<GenericValue> &Args) { 229782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 230782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GenericValue GV; 231782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner GV.DoubleVal = floor(Args[0].DoubleVal); 232782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GV; 233782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 234782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner 235abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#ifdef HAVE_RAND48 236abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer 2378679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double drand48() 23897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_drand48(FunctionType *FT, const vector<GenericValue> &Args) { 2398679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner assert(Args.size() == 0); 2408679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GenericValue GV; 2418679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner GV.DoubleVal = drand48(); 2428679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner return GV; 2438679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner} 2448679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 2451b600144bda9717804ae3b998c95223947200075Chris Lattner// long lrand48() 24697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_lrand48(FunctionType *FT, const vector<GenericValue> &Args) { 2471b600144bda9717804ae3b998c95223947200075Chris Lattner assert(Args.size() == 0); 2481b600144bda9717804ae3b998c95223947200075Chris Lattner GenericValue GV; 249e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer GV.Int32Val = lrand48(); 2501b600144bda9717804ae3b998c95223947200075Chris Lattner return GV; 2511b600144bda9717804ae3b998c95223947200075Chris Lattner} 2521b600144bda9717804ae3b998c95223947200075Chris Lattner 2531b600144bda9717804ae3b998c95223947200075Chris Lattner// void srand48(long) 25497e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_srand48(FunctionType *FT, const vector<GenericValue> &Args) { 2551b600144bda9717804ae3b998c95223947200075Chris Lattner assert(Args.size() == 1); 256e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer srand48(Args[0].Int32Val); 2571b600144bda9717804ae3b998c95223947200075Chris Lattner return GenericValue(); 2581b600144bda9717804ae3b998c95223947200075Chris Lattner} 2591b600144bda9717804ae3b998c95223947200075Chris Lattner 260abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#endif 261abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer 262abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer// int rand() 26397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_rand(FunctionType *FT, const vector<GenericValue> &Args) { 264abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer assert(Args.size() == 0); 265abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer GenericValue GV; 266bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, rand()); 267abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer return GV; 268abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer} 269abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer 270782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// void srand(uint) 27197e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_srand(FunctionType *FT, const vector<GenericValue> &Args) { 272782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner assert(Args.size() == 1); 273bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer srand(Args[0].IntVal.getZExtValue()); 274782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner return GenericValue(); 275782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner} 2768679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner 277b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner// int puts(const char*) 27897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_puts(FunctionType *FT, const vector<GenericValue> &Args) { 279b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner assert(Args.size() == 1); 280b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner GenericValue GV; 281bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, puts((char*)GVTOP(Args[0]))); 282b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return GV; 283b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner} 284b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner 285e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make 286e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// output useful. 28797e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_sprintf(FunctionType *FT, const vector<GenericValue> &Args) { 288b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner char *OutputBuffer = (char *)GVTOP(Args[0]); 289b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const char *FmtStr = (const char *)GVTOP(Args[1]); 290e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner unsigned ArgNo = 2; 29108845a242c574d695566cbc61e46da1c86c810acChris Lattner 29208845a242c574d695566cbc61e46da1c86c810acChris Lattner // printf should return # chars printed. This is completely incorrect, but 29308845a242c574d695566cbc61e46da1c86c810acChris Lattner // close enough for now. 294bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GenericValue GV; 295bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, strlen(FmtStr)); 29608845a242c574d695566cbc61e46da1c86c810acChris Lattner while (1) { 29708845a242c574d695566cbc61e46da1c86c810acChris Lattner switch (*FmtStr) { 29808845a242c574d695566cbc61e46da1c86c810acChris Lattner case 0: return GV; // Null terminator... 29908845a242c574d695566cbc61e46da1c86c810acChris Lattner default: // Normal nonspecial character 300e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer++, "%c", *FmtStr++); 30108845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 30208845a242c574d695566cbc61e46da1c86c810acChris Lattner case '\\': { // Handle escape codes 303e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1)); 304e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FmtStr += 2; OutputBuffer += 2; 30508845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 30608845a242c574d695566cbc61e46da1c86c810acChris Lattner } 30708845a242c574d695566cbc61e46da1c86c810acChris Lattner case '%': { // Handle format specifiers 308ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char FmtBuf[100] = "", Buffer[1000] = ""; 309ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char *FB = FmtBuf; 310ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB++ = *FmtStr++; 311ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char Last = *FB++ = *FmtStr++; 312ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner unsigned HowLong = 0; 313ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' && 314ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' && 315ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' && 316ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'p' && Last != 's' && Last != '%') { 317ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner if (Last == 'l' || Last == 'L') HowLong++; // Keep track of l's 318ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last = *FB++ = *FmtStr++; 31908845a242c574d695566cbc61e46da1c86c810acChris Lattner } 320ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB = 0; 321d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman 322ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner switch (Last) { 323ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case '%': 324ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf); break; 325ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'c': 326bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue())); 327bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer break; 328ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'd': case 'i': 329ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'u': case 'o': 330ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'x': case 'X': 33169ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner if (HowLong >= 1) { 3321543e40cea50d244979f0667f453cf3466a6106cChris Lattner if (HowLong == 1 && 333fe854034677f59baca1e38075e71f6efca247a03Chris Lattner TheInterpreter->getTargetData()->getPointerSizeInBits() == 64 && 33419b7e0e0cabfa6dfc559c64e3d6ed053832c4047Reid Spencer sizeof(long) < sizeof(int64_t)) { 33569ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // Make sure we use %lld with a 64 bit argument because we might be 33669ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // compiling LLI on a 32 bit compiler. 33769ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner unsigned Size = strlen(FmtBuf); 33869ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size] = FmtBuf[Size-1]; 33969ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size+1] = 0; 34069ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size-1] = 'l'; 34169ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } 342bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal.getZExtValue()); 34369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } else 344bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf,uint32_t(Args[ArgNo++].IntVal.getZExtValue())); 345bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer break; 346ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'e': case 'E': case 'g': case 'G': case 'f': 347ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break; 348ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'p': 349b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break; 350d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman case 's': 351b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break; 352e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling default: cerr << "<unknown printf code '" << *FmtStr << "'!>"; 353ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner ArgNo++; break; 354ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner } 355e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner strcpy(OutputBuffer, Buffer); 356e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner OutputBuffer += strlen(Buffer); 35708845a242c574d695566cbc61e46da1c86c810acChris Lattner } 35808845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 35908845a242c574d695566cbc61e46da1c86c810acChris Lattner } 36008845a242c574d695566cbc61e46da1c86c810acChris Lattner } 361b3b0727032e58c8b8f3017c2b3f560616c6905afReid Spencer return GV; 36208845a242c574d695566cbc61e46da1c86c810acChris Lattner} 36308845a242c574d695566cbc61e46da1c86c810acChris Lattner 364e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int printf(sbyte *, ...) - a very rough implementation to make output useful. 36597e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_printf(FunctionType *FT, const vector<GenericValue> &Args) { 366e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner char Buffer[10000]; 367e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner vector<GenericValue> NewArgs; 368b3b0727032e58c8b8f3017c2b3f560616c6905afReid Spencer NewArgs.push_back(PTOGV((void*)&Buffer[0])); 369e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin(), Args.end()); 37097e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer GenericValue GV = lle_X_sprintf(FT, NewArgs); 371e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cout << Buffer; 372e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner return GV; 373e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner} 374e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner 375f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattnerstatic void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1, 376f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg2, void *Arg3, void *Arg4, void *Arg5, 377f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg6, void *Arg7, void *Arg8) { 378f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 }; 379f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 380f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Loop over the format string, munging read values as appropriate (performs 3815560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman // byteswaps as necessary). 382f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned ArgNo = 0; 383f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (*Fmt) { 384f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (*Fmt++ == '%') { 385f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read any flag characters that may be present... 386f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Suppress = false; 387f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Half = false; 388f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Long = false; 389f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool LongLong = false; // long long or long double 390f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 391f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (1) { 392f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (*Fmt++) { 393f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case '*': Suppress = true; break; 394f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'a': /*Allocate = true;*/ break; // We don't need to track this 395f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'h': Half = true; break; 396f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'l': Long = true; break; 397f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'q': 398f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'L': LongLong = true; break; 399f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: 400f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Fmt[-1] > '9' || Fmt[-1] < '0') // Ignore field width specs 401f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner goto Out; 402f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 403f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 404f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Out: 405f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 406f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read the conversion character 407f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (!Suppress && Fmt[-1] != '%') { // Nothing to do? 408f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned Size = 0; 409f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner const Type *Ty = 0; 410f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 411f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (Fmt[-1]) { 412f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p': 413f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'd': 414f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 415e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 8; Ty = Type::Int64Ty; 416f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else if (Half) { 417e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 4; Ty = Type::Int16Ty; 418f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 419e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 4; Ty = Type::Int32Ty; 420f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 421f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 422f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 423f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'e': case 'g': case 'E': 424f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'f': 425f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 426f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 8; Ty = Type::DoubleTy; 427f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 428f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 4; Ty = Type::FloatTy; 429f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 430f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 431f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 432f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 's': case 'c': case '[': // No byteswap needed 433f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 1; 434e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Ty = Type::Int8Ty; 435f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 436f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 437f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: break; 438f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 439f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 440f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Size) { 441f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 442f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg = Args[ArgNo++]; 443f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner memcpy(&GV, Arg, Size); 444f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty); 445f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 446f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 447f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 448f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 449f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 450f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 451665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int sscanf(const char *format, ...); 45297e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_sscanf(FunctionType *FT, const vector<GenericValue> &args) { 453665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); 454665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 455f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 456665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 457f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 458665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 459665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 460bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, sscanf(Args[0], Args[1], Args[2], Args[3], Args[4], 461bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Args[5], Args[6], Args[7], Args[8], Args[9])); 462f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4], 463f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9], 0); 464f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner return GV; 465f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 466f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 467f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner// int scanf(const char *format, ...); 46897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_scanf(FunctionType *FT, const vector<GenericValue> &args) { 469f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); 470f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 471f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 472f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 473f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 474f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 475f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 476bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4], 477bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Args[5], Args[6], Args[7], Args[8], Args[9])); 478f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4], 479f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9]); 480665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 481665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 482665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 483665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 484295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner// int clock(void) - Profiling implementation 48597e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_i_clock(FunctionType *FT, const vector<GenericValue> &Args) { 486638559aaa3a30cef596fae20292295cb0a329df1Chris Lattner extern unsigned int clock(void); 487bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GenericValue GV; 488bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, clock()); 489295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner return GV; 490295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner} 491e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner 492957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 493957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner//===----------------------------------------------------------------------===// 494957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// String Functions... 495957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner//===----------------------------------------------------------------------===// 496957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 497957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// int strcmp(const char *S1, const char *S2); 49897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_strcmp(FunctionType *FT, const vector<GenericValue> &Args) { 499957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner assert(Args.size() == 2); 500957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner GenericValue Ret; 501bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Ret.IntVal = APInt(32, strcmp((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); 502957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner return Ret; 503957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 504957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 505957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// char *strcat(char *Dest, const char *src); 50697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_strcat(FunctionType *FT, const vector<GenericValue> &Args) { 507957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner assert(Args.size() == 2); 50897e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) &&"strcat must return pointer"); 509957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner return PTOGV(strcat((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); 510957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 511957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 512957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// char *strcpy(char *Dest, const char *src); 51397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_strcpy(FunctionType *FT, const vector<GenericValue> &Args) { 514957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner assert(Args.size() == 2); 51597e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) &&"strcpy must return pointer"); 516957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner return PTOGV(strcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); 517957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 518957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 5193c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaekestatic GenericValue size_t_to_GV (size_t n) { 520957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner GenericValue Ret; 5216c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke if (sizeof (size_t) == sizeof (uint64_t)) { 522bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Ret.IntVal = APInt(64, n); 5236c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke } else { 5246c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke assert (sizeof (size_t) == sizeof (unsigned int)); 525bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Ret.IntVal = APInt(32, n); 5266c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke } 527957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner return Ret; 528957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 529957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 530d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukmanstatic size_t GV_to_size_t (GenericValue GV) { 5313c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t count; 5323c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke if (sizeof (size_t) == sizeof (uint64_t)) { 533bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer count = (size_t)GV.IntVal.getZExtValue(); 5343c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke } else { 5353c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke assert (sizeof (size_t) == sizeof (unsigned int)); 536bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer count = (size_t)GV.IntVal.getZExtValue(); 5373c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke } 5383c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke return count; 5393c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke} 5403c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke 5413c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke// size_t strlen(const char *src); 54297e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_strlen(FunctionType *FT, const vector<GenericValue> &Args) { 5433c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke assert(Args.size() == 1); 5443c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t strlenResult = strlen ((char *) GVTOP (Args[0])); 5453c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke return size_t_to_GV (strlenResult); 5463c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke} 5473c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke 54870975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke// char *strdup(const char *src); 54997e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_strdup(FunctionType *FT, const vector<GenericValue> &Args) { 55070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke assert(Args.size() == 1); 55197e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "strdup must return pointer"); 55270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke return PTOGV(strdup((char*)GVTOP(Args[0]))); 55370975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke} 55470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke 555c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner// char *__strdup(const char *src); 55697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X___strdup(FunctionType *FT, const vector<GenericValue> &Args) { 557c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner assert(Args.size() == 1); 55897e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) &&"_strdup must return pointer"); 559c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner return PTOGV(strdup((char*)GVTOP(Args[0]))); 560c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner} 561c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner 562957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// void *memset(void *S, int C, size_t N) 56397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_memset(FunctionType *FT, const vector<GenericValue> &Args) { 564957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner assert(Args.size() == 3); 5653c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t count = GV_to_size_t (Args[2]); 56697e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "memset must return pointer"); 567bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer return PTOGV(memset(GVTOP(Args[0]), uint32_t(Args[1].IntVal.getZExtValue()), 568bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer count)); 569957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner} 570957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 5715f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner// void *memcpy(void *Dest, void *src, size_t Size); 57297e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_memcpy(FunctionType *FT, const vector<GenericValue> &Args) { 5735f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner assert(Args.size() == 3); 57497e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "memcpy must return pointer"); 5753c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t count = GV_to_size_t (Args[2]); 5763c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke return PTOGV(memcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count)); 5775f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner} 578957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 579665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===// 580665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// IO Functions... 581665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===// 582665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 583005cbce20e55077d7e02255812e5df068188d302Chris Lattner// getFILE - Turn a pointer in the host address space into a legit pointer in 5840098bdfb9723c48c144fa9534ae1fe2ffb1c0f13Reid Spencer// the interpreter address space. This is an identity transformation. 5850098bdfb9723c48c144fa9534ae1fe2ffb1c0f13Reid Spencer#define getFILE(ptr) ((FILE*)ptr) 586005cbce20e55077d7e02255812e5df068188d302Chris Lattner 587665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// FILE *fopen(const char *filename, const char *mode); 58897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fopen(FunctionType *FT, const vector<GenericValue> &Args) { 589665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 2); 59097e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) && "fopen must return pointer"); 591b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return PTOGV(fopen((const char *)GVTOP(Args[0]), 5923c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman (const char *)GVTOP(Args[1]))); 593665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 594665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 595665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fclose(FILE *F); 59697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fclose(FunctionType *FT, const vector<GenericValue> &Args) { 597665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 1); 598665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 599bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, fclose(getFILE(GVTOP(Args[0])))); 600665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 601665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 602665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 60325f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner// int feof(FILE *stream); 60497e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_feof(FunctionType *FT, const vector<GenericValue> &Args) { 60525f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner assert(Args.size() == 1); 60625f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner GenericValue GV; 60725f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner 608bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, feof(getFILE(GVTOP(Args[0])))); 60925f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner return GV; 61025f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner} 61125f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner 612665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); 61397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fread(FunctionType *FT, const vector<GenericValue> &Args) { 614665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 4); 6153c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t result; 616665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 6173c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke result = fread((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]), 6183c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3]))); 6193c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke return size_t_to_GV (result); 620665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 621665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 622665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); 62397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fwrite(FunctionType *FT, const vector<GenericValue> &Args) { 624665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 4); 6253c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke size_t result; 626665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 6273c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke result = fwrite((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]), 6283c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3]))); 6293c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke return size_t_to_GV (result); 630665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 631665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 632665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// char *fgets(char *s, int n, FILE *stream); 63397e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fgets(FunctionType *FT, const vector<GenericValue> &Args) { 634665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 3); 635bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer return GVTOP(fgets((char*)GVTOP(Args[0]), Args[1].IntVal.getZExtValue(), 6363c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman getFILE(GVTOP(Args[2])))); 637665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 638665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 639a4479cd94615f84fe87533081e521669113557c7Chris Lattner// FILE *freopen(const char *path, const char *mode, FILE *stream); 64097e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_freopen(FunctionType *FT, const vector<GenericValue> &Args) { 641a4479cd94615f84fe87533081e521669113557c7Chris Lattner assert(Args.size() == 3); 64297e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer assert(isa<PointerType>(FT->getReturnType()) &&"freopen must return pointer"); 643b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), 6443c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman getFILE(GVTOP(Args[2])))); 645a4479cd94615f84fe87533081e521669113557c7Chris Lattner} 646a4479cd94615f84fe87533081e521669113557c7Chris Lattner 647665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fflush(FILE *stream); 64897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fflush(FunctionType *FT, const vector<GenericValue> &Args) { 649665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(Args.size() == 1); 650665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 651bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, fflush(getFILE(GVTOP(Args[0])))); 652005cbce20e55077d7e02255812e5df068188d302Chris Lattner return GV; 653005cbce20e55077d7e02255812e5df068188d302Chris Lattner} 654005cbce20e55077d7e02255812e5df068188d302Chris Lattner 655005cbce20e55077d7e02255812e5df068188d302Chris Lattner// int getc(FILE *stream); 65697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_getc(FunctionType *FT, const vector<GenericValue> &Args) { 657005cbce20e55077d7e02255812e5df068188d302Chris Lattner assert(Args.size() == 1); 658005cbce20e55077d7e02255812e5df068188d302Chris Lattner GenericValue GV; 659bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, getc(getFILE(GVTOP(Args[0])))); 660665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 661665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 662665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 663f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner// int _IO_getc(FILE *stream); 664f87a198dcbaf95a6608b1484b42c6044d61003f6Chris LattnerGenericValue lle_X__IO_getc(FunctionType *F, const vector<GenericValue> &Args) { 665f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner return lle_X_getc(F, Args); 666f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner} 667f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner 668a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int fputc(int C, FILE *stream); 66997e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fputc(FunctionType *FT, const vector<GenericValue> &Args) { 670a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner assert(Args.size() == 2); 671a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner GenericValue GV; 672bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, fputc(Args[0].IntVal.getZExtValue(), 673bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer getFILE(GVTOP(Args[1])))); 674a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner return GV; 675a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner} 676a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner 677a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int ungetc(int C, FILE *stream); 67897e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_ungetc(FunctionType *FT, const vector<GenericValue> &Args) { 679a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner assert(Args.size() == 2); 680a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner GenericValue GV; 681bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, ungetc(Args[0].IntVal.getZExtValue(), 682bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer getFILE(GVTOP(Args[1])))); 683a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner return GV; 684a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner} 685a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner 68659108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke// int ferror (FILE *stream); 68797e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_ferror(FunctionType *FT, const vector<GenericValue> &Args) { 68859108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke assert(Args.size() == 1); 68959108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke GenericValue GV; 690bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, ferror (getFILE(GVTOP(Args[0])))); 69159108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke return GV; 69259108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke} 69359108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke 694cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output 695cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// useful. 69697e0c22330f1856a7e026d162040aafdb2a70d0eReid SpencerGenericValue lle_X_fprintf(FunctionType *FT, const vector<GenericValue> &Args) { 6979dbf6dddcec7a627fabfc722e124311321de8fa0Chris Lattner assert(Args.size() >= 2); 698cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner char Buffer[10000]; 699cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner vector<GenericValue> NewArgs; 700b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner NewArgs.push_back(PTOGV(Buffer)); 701cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end()); 70297e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer GenericValue GV = lle_X_sprintf(FT, NewArgs); 703cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 704b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner fputs(Buffer, getFILE(GVTOP(Args[0]))); 705cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner return GV; 706cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner} 707cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 7087720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} // End extern "C" 7094721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 7104721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 711da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattnervoid Interpreter::initializeExternalFunctions() { 712b3b0727032e58c8b8f3017c2b3f560616c6905afReid Spencer FuncNames["lle_X_putchar"] = lle_X_putchar; 713cc442cabf6585084ae6238f8003c14e5ebc386f6Reid Spencer FuncNames["lle_X__IO_putc"] = lle_X__IO_putc; 7140f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_exit"] = lle_X_exit; 7151ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner FuncNames["lle_X_abort"] = lle_X_abort; 7160f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_malloc"] = lle_X_malloc; 717957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_calloc"] = lle_X_calloc; 71897e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer FuncNames["lle_X_realloc"] = lle_X_realloc; 7190f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_free"] = lle_X_free; 720782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_atoi"] = lle_X_atoi; 7210f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_pow"] = lle_X_pow; 72234dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner FuncNames["lle_X_exp"] = lle_X_exp; 7231b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_log"] = lle_X_log; 724782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_floor"] = lle_X_floor; 725782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner FuncNames["lle_X_srand"] = lle_X_srand; 726abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer FuncNames["lle_X_rand"] = lle_X_rand; 727abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#ifdef HAVE_RAND48 7281b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_drand48"] = lle_X_drand48; 7291b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_srand48"] = lle_X_srand48; 7301b600144bda9717804ae3b998c95223947200075Chris Lattner FuncNames["lle_X_lrand48"] = lle_X_lrand48; 731abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#endif 732c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner FuncNames["lle_X_sqrt"] = lle_X_sqrt; 733b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner FuncNames["lle_X_puts"] = lle_X_puts; 7340f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_printf"] = lle_X_printf; 735e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FuncNames["lle_X_sprintf"] = lle_X_sprintf; 736665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_sscanf"] = lle_X_sscanf; 737f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner FuncNames["lle_X_scanf"] = lle_X_scanf; 738295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner FuncNames["lle_i_clock"] = lle_i_clock; 739957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 740957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_strcmp"] = lle_X_strcmp; 741957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_strcat"] = lle_X_strcat; 742957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_strcpy"] = lle_X_strcpy; 743957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_strlen"] = lle_X_strlen; 744da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner FuncNames["lle_X___strdup"] = lle_X___strdup; 745957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner FuncNames["lle_X_memset"] = lle_X_memset; 7465f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner FuncNames["lle_X_memcpy"] = lle_X_memcpy; 747957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner 748665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fopen"] = lle_X_fopen; 749665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fclose"] = lle_X_fclose; 75025f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner FuncNames["lle_X_feof"] = lle_X_feof; 751665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fread"] = lle_X_fread; 752665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fwrite"] = lle_X_fwrite; 753665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fgets"] = lle_X_fgets; 754665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_fflush"] = lle_X_fflush; 755a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_fgetc"] = lle_X_getc; 756005cbce20e55077d7e02255812e5df068188d302Chris Lattner FuncNames["lle_X_getc"] = lle_X_getc; 757f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner FuncNames["lle_X__IO_getc"] = lle_X__IO_getc; 758a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_fputc"] = lle_X_fputc; 759a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner FuncNames["lle_X_ungetc"] = lle_X_ungetc; 760cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner FuncNames["lle_X_fprintf"] = lle_X_fprintf; 761a4479cd94615f84fe87533081e521669113557c7Chris Lattner FuncNames["lle_X_freopen"] = lle_X_freopen; 7624721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner} 763d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 764