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