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