ExternalFunctions.cpp revision d1c881a8d4da8b4d99c2a40512fbcca652ab445e
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"
25df5a37efc997288da520ff4889443e3560d95387Reid Spencer#include "llvm/System/DynamicLibrary.h"
26005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "llvm/Target/TargetData.h"
27703379827f92c04f260c5c96cfe5b8450b434a6eBrian Gaeke#include <cmath>
28b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke#include <csignal>
29b8d15b2ad0a2266b275a00f07410e6c9d9ca6695Misha Brukman#include <map>
30697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::vector;
317720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
32f7a743d7ed6e96af4c836e512c9cd59812c8186eChris Lattnerusing namespace llvm;
33d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
34b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnertypedef GenericValue (*ExFunc)(FunctionType *, const vector<GenericValue> &);
35b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattnerstatic std::map<const Function *, ExFunc> Functions;
36697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstatic std::map<std::string, ExFunc> FuncNames;
377720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
38e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattnerstatic Interpreter *TheInterpreter;
39e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner
407720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerstatic char getTypeID(const Type *Ty) {
41f70c22b019494723d0e706f93d6542dfaa6e73a5Chris Lattner  switch (Ty->getTypeID()) {
427720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::VoidTyID:    return 'V';
437720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::BoolTyID:    return 'o';
447720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::UByteTyID:   return 'B';
457720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::SByteTyID:   return 'b';
467720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::UShortTyID:  return 'S';
477720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::ShortTyID:   return 's';
487720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::UIntTyID:    return 'I';
497720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::IntTyID:     return 'i';
507720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::ULongTyID:   return 'L';
517720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::LongTyID:    return 'l';
527720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::FloatTyID:   return 'F';
537720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::DoubleTyID:  return 'D';
547720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::PointerTyID: return 'P';
55b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner  case Type::FunctionTyID:  return 'M';
567720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::StructTyID:  return 'T';
577720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::ArrayTyID:   return 'A';
587720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  case Type::OpaqueTyID:  return 'O';
597720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  default: return 'U';
607720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  }
617720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner}
627720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
6358a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaekestatic ExFunc lookupFunction(const Function *F) {
647720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  // Function not found, look it up... start by figuring out what the
657720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  // composite function name should be.
66697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::string ExtName = "lle_";
6758a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke  const FunctionType *FT = F->getFunctionType();
6858a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke  for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i)
6958a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke    ExtName += getTypeID(FT->getContainedType(i));
7058a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke  ExtName += "_" + F->getName();
717720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
724721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner  ExFunc FnPtr = FuncNames[ExtName];
734721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner  if (FnPtr == 0)
74df5a37efc997288da520ff4889443e3560d95387Reid Spencer    FnPtr = (ExFunc)sys::DynamicLibrary::SearchForAddressOfSymbol(ExtName);
754721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner  if (FnPtr == 0)
7658a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke    FnPtr = FuncNames["lle_X_"+F->getName()];
777720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  if (FnPtr == 0)  // Try calling a generic function... if it exists...
78df5a37efc997288da520ff4889443e3560d95387Reid Spencer    FnPtr = (ExFunc)sys::DynamicLibrary::SearchForAddressOfSymbol(
79df5a37efc997288da520ff4889443e3560d95387Reid Spencer            ("lle_X_"+F->getName()).c_str());
807720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  if (FnPtr != 0)
8158a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke    Functions.insert(std::make_pair(F, FnPtr));  // Cache for later
827720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  return FnPtr;
837720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner}
847720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
854e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris LattnerGenericValue Interpreter::callExternalFunction(Function *F,
8644edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner                                     const std::vector<GenericValue> &ArgVals) {
87e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner  TheInterpreter = this;
88e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner
892fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner  // Do a lookup to see if the function is in our cache... this should just be a
90d5d96b9fcd779806555cf5db602f80d5a308a471Misha Brukman  // deferred annotation!
914e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner  std::map<const Function *, ExFunc>::iterator FI = Functions.find(F);
924e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner  ExFunc Fn = (FI == Functions.end()) ? lookupFunction(F) : FI->second;
937720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  if (Fn == 0) {
94da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner    std::cout << "Tried to execute an unknown external function: "
954e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner              << F->getType()->getDescription() << " " << F->getName() << "\n";
964e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner    if (F->getName() == "__main")
974e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner      return GenericValue();
984e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner    abort();
997720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  }
1007720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
1017720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  // TODO: FIXME when types are not const!
1024e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris Lattner  GenericValue Result = Fn(const_cast<FunctionType*>(F->getFunctionType()),
1032fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner                           ArgVals);
1044721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner  return Result;
1057720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner}
1067720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
1077720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
1087720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===//
109b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner//  Functions "exported" to the running application...
1107720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//
1117720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerextern "C" {  // Don't add C++ manglings to llvm mangling :)
1127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
113005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void putchar(sbyte)
114b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_Vb_putchar(FunctionType *M, const vector<GenericValue> &Args) {
115da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  std::cout << Args[0].SByteVal;
1167720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner  return GenericValue();
1177720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner}
1187720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner
119005cbce20e55077d7e02255812e5df068188d302Chris Lattner// int putchar(int)
120b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_ii_putchar(FunctionType *M, const vector<GenericValue> &Args) {
121da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  std::cout << ((char)Args[0].IntVal) << std::flush;
122e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner  return Args[0];
123e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner}
124e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner
125005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void putchar(ubyte)
126b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_VB_putchar(FunctionType *M, const vector<GenericValue> &Args) {
127da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  std::cout << Args[0].SByteVal << std::flush;
128e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner  return Args[0];
1292e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner}
1302e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner
13144edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner// void atexit(Function*)
13244edb6bdd2edc48eb31ed160a09006b610cead67Chris LattnerGenericValue lle_X_atexit(FunctionType *M, const vector<GenericValue> &Args) {
13344edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  assert(Args.size() == 1);
13444edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
13544edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  GenericValue GV;
13644edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  GV.IntVal = 0;
13744edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  return GV;
138f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner}
139f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner
140005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void exit(int)
141b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_exit(FunctionType *M, const vector<GenericValue> &Args) {
142e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner  TheInterpreter->exitCalled(Args[0]);
143e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner  return GenericValue();
144e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner}
145e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner
146005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void abort(void)
1471ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris LattnerGenericValue lle_X_abort(FunctionType *M, const vector<GenericValue> &Args) {
148b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke  raise (SIGABRT);
1491ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner  return GenericValue();
1501ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner}
1511ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner
152c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void *malloc(uint)
153b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_malloc(FunctionType *M, const vector<GenericValue> &Args) {
1544721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner  assert(Args.size() == 1 && "Malloc expects one argument!");
155b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  return PTOGV(malloc(Args[0].UIntVal));
156c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner}
157c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner
158957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// void *calloc(uint, uint)
159957d62aa791078ba9e09307d43fff27b68ce8d51Chris LattnerGenericValue lle_X_calloc(FunctionType *M, const vector<GenericValue> &Args) {
160957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  assert(Args.size() == 2 && "calloc expects two arguments!");
161957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  return PTOGV(calloc(Args[0].UIntVal, Args[1].UIntVal));
162957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
163957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
164c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// void free(void *)
165b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_free(FunctionType *M, const vector<GenericValue> &Args) {
166c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  assert(Args.size() == 1);
167b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  free(GVTOP(Args[0]));
168c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner  return GenericValue();
169c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner}
170c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner
171782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// int atoi(char *)
172b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_atoi(FunctionType *M, const vector<GenericValue> &Args) {
173782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  assert(Args.size() == 1);
174782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  GenericValue GV;
175b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = atoi((char*)GVTOP(Args[0]));
176782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  return GV;
177782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner}
178782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner
179c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner// double pow(double, double)
180b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_pow(FunctionType *M, const vector<GenericValue> &Args) {
181c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  assert(Args.size() == 2);
182c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner  GenericValue GV;
18308845a242c574d695566cbc61e46da1c86c810acChris Lattner  GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal);
184c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner  return GV;
185c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner}
186c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner
18734dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner// double exp(double)
188b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_exp(FunctionType *M, const vector<GenericValue> &Args) {
18934dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner  assert(Args.size() == 1);
19034dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner  GenericValue GV;
19134dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner  GV.DoubleVal = exp(Args[0].DoubleVal);
19234dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner  return GV;
19334dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner}
19434dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner
195c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner// double sqrt(double)
196b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sqrt(FunctionType *M, const vector<GenericValue> &Args) {
197c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  assert(Args.size() == 1);
198c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  GenericValue GV;
199c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  GV.DoubleVal = sqrt(Args[0].DoubleVal);
200c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  return GV;
201c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner}
202c25931673092b1dae646aeeac1d18f75d9640ec7Chris Lattner
2038679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double log(double)
204b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_log(FunctionType *M, const vector<GenericValue> &Args) {
2058679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  assert(Args.size() == 1);
2068679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  GenericValue GV;
2078679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  GV.DoubleVal = log(Args[0].DoubleVal);
2088679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  return GV;
2098679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner}
2108679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner
211782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// double floor(double)
212b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_floor(FunctionType *M, const vector<GenericValue> &Args) {
213782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  assert(Args.size() == 1);
214782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  GenericValue GV;
215782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  GV.DoubleVal = floor(Args[0].DoubleVal);
216782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  return GV;
217782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner}
218782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner
219abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#ifdef HAVE_RAND48
220abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer
2218679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner// double drand48()
222b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_drand48(FunctionType *M, const vector<GenericValue> &Args) {
2238679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  assert(Args.size() == 0);
2248679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  GenericValue GV;
2258679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  GV.DoubleVal = drand48();
2268679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner  return GV;
2278679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner}
2288679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner
2291b600144bda9717804ae3b998c95223947200075Chris Lattner// long lrand48()
230b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_lrand48(FunctionType *M, const vector<GenericValue> &Args) {
2311b600144bda9717804ae3b998c95223947200075Chris Lattner  assert(Args.size() == 0);
2321b600144bda9717804ae3b998c95223947200075Chris Lattner  GenericValue GV;
2331b600144bda9717804ae3b998c95223947200075Chris Lattner  GV.IntVal = lrand48();
2341b600144bda9717804ae3b998c95223947200075Chris Lattner  return GV;
2351b600144bda9717804ae3b998c95223947200075Chris Lattner}
2361b600144bda9717804ae3b998c95223947200075Chris Lattner
2371b600144bda9717804ae3b998c95223947200075Chris Lattner// void srand48(long)
238b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_srand48(FunctionType *M, const vector<GenericValue> &Args) {
2391b600144bda9717804ae3b998c95223947200075Chris Lattner  assert(Args.size() == 1);
2401b600144bda9717804ae3b998c95223947200075Chris Lattner  srand48(Args[0].IntVal);
2411b600144bda9717804ae3b998c95223947200075Chris Lattner  return GenericValue();
2421b600144bda9717804ae3b998c95223947200075Chris Lattner}
2431b600144bda9717804ae3b998c95223947200075Chris Lattner
244abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#endif
245abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer
246abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer// int rand()
247abec8f96e3e35fbb306c957674809c4ace04a620Reid SpencerGenericValue lle_X_rand(FunctionType *M, const vector<GenericValue> &Args) {
248abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer  assert(Args.size() == 0);
249abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer  GenericValue GV;
250abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer  GV.IntVal = rand();
251abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer  return GV;
252abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer}
253abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer
254782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner// void srand(uint)
255b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_srand(FunctionType *M, const vector<GenericValue> &Args) {
256782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  assert(Args.size() == 1);
257782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  srand(Args[0].UIntVal);
258782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  return GenericValue();
259782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner}
2608679005193a8a3f8c0eb975a321bd08dec4793d7Chris Lattner
261b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner// int puts(const char*)
262b111874b386f5e3d807a8f78edb010b40d507115Chris LattnerGenericValue lle_X_puts(FunctionType *M, const vector<GenericValue> &Args) {
263b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  assert(Args.size() == 1);
264b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GenericValue GV;
265b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = puts((char*)GVTOP(Args[0]));
266b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  return GV;
267b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner}
268b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner
269e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make
270e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// output useful.
271b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sprintf(FunctionType *M, const vector<GenericValue> &Args) {
272b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  char *OutputBuffer = (char *)GVTOP(Args[0]);
273b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  const char *FmtStr = (const char *)GVTOP(Args[1]);
274e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  unsigned ArgNo = 2;
27508845a242c574d695566cbc61e46da1c86c810acChris Lattner
27608845a242c574d695566cbc61e46da1c86c810acChris Lattner  // printf should return # chars printed.  This is completely incorrect, but
27708845a242c574d695566cbc61e46da1c86c810acChris Lattner  // close enough for now.
27808845a242c574d695566cbc61e46da1c86c810acChris Lattner  GenericValue GV; GV.IntVal = strlen(FmtStr);
27908845a242c574d695566cbc61e46da1c86c810acChris Lattner  while (1) {
28008845a242c574d695566cbc61e46da1c86c810acChris Lattner    switch (*FmtStr) {
28108845a242c574d695566cbc61e46da1c86c810acChris Lattner    case 0: return GV;             // Null terminator...
28208845a242c574d695566cbc61e46da1c86c810acChris Lattner    default:                       // Normal nonspecial character
283e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner      sprintf(OutputBuffer++, "%c", *FmtStr++);
28408845a242c574d695566cbc61e46da1c86c810acChris Lattner      break;
28508845a242c574d695566cbc61e46da1c86c810acChris Lattner    case '\\': {                   // Handle escape codes
286e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner      sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1));
287e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner      FmtStr += 2; OutputBuffer += 2;
28808845a242c574d695566cbc61e46da1c86c810acChris Lattner      break;
28908845a242c574d695566cbc61e46da1c86c810acChris Lattner    }
29008845a242c574d695566cbc61e46da1c86c810acChris Lattner    case '%': {                    // Handle format specifiers
291ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      char FmtBuf[100] = "", Buffer[1000] = "";
292ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      char *FB = FmtBuf;
293ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      *FB++ = *FmtStr++;
294ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      char Last = *FB++ = *FmtStr++;
295ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      unsigned HowLong = 0;
296ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
297ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner             Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
298ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner             Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
299ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner             Last != 'p' && Last != 's' && Last != '%') {
300ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner        if (Last == 'l' || Last == 'L') HowLong++;  // Keep track of l's
301ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner        Last = *FB++ = *FmtStr++;
30208845a242c574d695566cbc61e46da1c86c810acChris Lattner      }
303ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      *FB = 0;
304d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman
305ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      switch (Last) {
306ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case '%':
307ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner        sprintf(Buffer, FmtBuf); break;
308ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'c':
3092012d5e33ffa601eb1c58f6830017dce1a1774b3Chris Lattner        sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break;
310ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'd': case 'i':
311ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'u': case 'o':
312ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'x': case 'X':
31369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner        if (HowLong >= 1) {
3141543e40cea50d244979f0667f453cf3466a6106cChris Lattner          if (HowLong == 1 &&
3151543e40cea50d244979f0667f453cf3466a6106cChris Lattner              TheInterpreter->getModule().getPointerSize()==Module::Pointer64 &&
3167471c486c03e36721bd43988774b1c43b9cc54e9Chris Lattner              sizeof(long) < sizeof(long long)) {
31769ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            // Make sure we use %lld with a 64 bit argument because we might be
31869ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            // compiling LLI on a 32 bit compiler.
31969ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            unsigned Size = strlen(FmtBuf);
32069ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            FmtBuf[Size] = FmtBuf[Size-1];
32169ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            FmtBuf[Size+1] = 0;
32269ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner            FmtBuf[Size-1] = 'l';
32369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner          }
324ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner          sprintf(Buffer, FmtBuf, Args[ArgNo++].ULongVal);
32569ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner        } else
326ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner          sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break;
327ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'e': case 'E': case 'g': case 'G': case 'f':
328ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner        sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
329ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      case 'p':
330b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner        sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break;
331d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman      case 's':
332b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner        sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break;
333da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner      default:  std::cout << "<unknown printf code '" << *FmtStr << "'!>";
334ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner        ArgNo++; break;
335ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner      }
336e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner      strcpy(OutputBuffer, Buffer);
337e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner      OutputBuffer += strlen(Buffer);
33808845a242c574d695566cbc61e46da1c86c810acChris Lattner      }
33908845a242c574d695566cbc61e46da1c86c810acChris Lattner      break;
34008845a242c574d695566cbc61e46da1c86c810acChris Lattner    }
34108845a242c574d695566cbc61e46da1c86c810acChris Lattner  }
34208845a242c574d695566cbc61e46da1c86c810acChris Lattner}
34308845a242c574d695566cbc61e46da1c86c810acChris Lattner
344e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// int printf(sbyte *, ...) - a very rough implementation to make output useful.
345b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_printf(FunctionType *M, const vector<GenericValue> &Args) {
346e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  char Buffer[10000];
347e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  vector<GenericValue> NewArgs;
348b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  NewArgs.push_back(PTOGV(Buffer));
349e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  NewArgs.insert(NewArgs.end(), Args.begin(), Args.end());
350b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GenericValue GV = lle_X_sprintf(M, NewArgs);
351da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  std::cout << Buffer;
352e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  return GV;
353e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner}
354e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner
355f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattnerstatic void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1,
356f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner                                 void *Arg2, void *Arg3, void *Arg4, void *Arg5,
357f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner                                 void *Arg6, void *Arg7, void *Arg8) {
358f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 };
359f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
360f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  // Loop over the format string, munging read values as appropriate (performs
3615560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman  // byteswaps as necessary).
362f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  unsigned ArgNo = 0;
363f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  while (*Fmt) {
364f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner    if (*Fmt++ == '%') {
365f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      // Read any flag characters that may be present...
366f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      bool Suppress = false;
367f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      bool Half = false;
368f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      bool Long = false;
369f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      bool LongLong = false;  // long long or long double
370f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
371f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      while (1) {
372f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        switch (*Fmt++) {
373f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case '*': Suppress = true; break;
374f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'a': /*Allocate = true;*/ break;  // We don't need to track this
375f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'h': Half = true; break;
376f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'l': Long = true; break;
377f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'q':
378f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'L': LongLong = true; break;
379f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        default:
380f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          if (Fmt[-1] > '9' || Fmt[-1] < '0')   // Ignore field width specs
381f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            goto Out;
382f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        }
383f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      }
384f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner    Out:
385f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
386f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      // Read the conversion character
387f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      if (!Suppress && Fmt[-1] != '%') { // Nothing to do?
388f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        unsigned Size = 0;
389f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        const Type *Ty = 0;
390f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
391f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        switch (Fmt[-1]) {
392f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p':
393f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'd':
394f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          if (Long || LongLong) {
395f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            Size = 8; Ty = Type::ULongTy;
396f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          } else if (Half) {
397f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            Size = 4; Ty = Type::UShortTy;
398f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          } else {
399f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            Size = 4; Ty = Type::UIntTy;
400f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          }
401f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          break;
402f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
403f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'e': case 'g': case 'E':
404f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 'f':
405f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          if (Long || LongLong) {
406f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            Size = 8; Ty = Type::DoubleTy;
407f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          } else {
408f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner            Size = 4; Ty = Type::FloatTy;
409f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          }
410f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          break;
411f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
412f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        case 's': case 'c': case '[':  // No byteswap needed
413f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          Size = 1;
414f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          Ty = Type::SByteTy;
415f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          break;
416f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
417f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        default: break;
418f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        }
419f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
420f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        if (Size) {
421f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          GenericValue GV;
422f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          void *Arg = Args[ArgNo++];
423f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          memcpy(&GV, Arg, Size);
424f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner          TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty);
425f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner        }
426f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner      }
427f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner    }
428f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  }
429f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner}
430f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
431665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int sscanf(const char *format, ...);
432b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_sscanf(FunctionType *M, const vector<GenericValue> &args) {
433665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");
434665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
435f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  char *Args[10];
436665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  for (unsigned i = 0; i < args.size(); ++i)
437f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner    Args[i] = (char*)GVTOP(args[i]);
438665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
439665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  GenericValue GV;
440665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  GV.IntVal = sscanf(Args[0], Args[1], Args[2], Args[3], Args[4],
441665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner                     Args[5], Args[6], Args[7], Args[8], Args[9]);
442f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4],
443f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner                       Args[5], Args[6], Args[7], Args[8], Args[9], 0);
444f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  return GV;
445f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner}
446f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
447f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner// int scanf(const char *format, ...);
448f9a88b684d8ca368ad51695c61a3580f4700da52Chris LattnerGenericValue lle_X_scanf(FunctionType *M, const vector<GenericValue> &args) {
449f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");
450f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
451f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  char *Args[10];
452f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  for (unsigned i = 0; i < args.size(); ++i)
453f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner    Args[i] = (char*)GVTOP(args[i]);
454f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner
455f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  GenericValue GV;
456f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  GV.IntVal = scanf(Args[0], Args[1], Args[2], Args[3], Args[4],
457f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner                    Args[5], Args[6], Args[7], Args[8], Args[9]);
458f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4],
459f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner                       Args[5], Args[6], Args[7], Args[8], Args[9]);
460665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  return GV;
461665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
462665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
463665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
464295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner// int clock(void) - Profiling implementation
465b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_i_clock(FunctionType *M, const vector<GenericValue> &Args) {
466638559aaa3a30cef596fae20292295cb0a329df1Chris Lattner  extern unsigned int clock(void);
467295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner  GenericValue GV; GV.IntVal = clock();
468295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner  return GV;
469295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner}
470e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner
471957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
472957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner//===----------------------------------------------------------------------===//
473957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// String Functions...
474957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner//===----------------------------------------------------------------------===//
475957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
476957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// int strcmp(const char *S1, const char *S2);
477957d62aa791078ba9e09307d43fff27b68ce8d51Chris LattnerGenericValue lle_X_strcmp(FunctionType *M, const vector<GenericValue> &Args) {
478957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  assert(Args.size() == 2);
479957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  GenericValue Ret;
480957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  Ret.IntVal = strcmp((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]));
481957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  return Ret;
482957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
483957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
484957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// char *strcat(char *Dest, const char *src);
485957d62aa791078ba9e09307d43fff27b68ce8d51Chris LattnerGenericValue lle_X_strcat(FunctionType *M, const vector<GenericValue> &Args) {
486957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  assert(Args.size() == 2);
487957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  return PTOGV(strcat((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
488957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
489957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
490957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// char *strcpy(char *Dest, const char *src);
491957d62aa791078ba9e09307d43fff27b68ce8d51Chris LattnerGenericValue lle_X_strcpy(FunctionType *M, const vector<GenericValue> &Args) {
492957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  assert(Args.size() == 2);
493957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  return PTOGV(strcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
494957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
495957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
4963c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaekestatic GenericValue size_t_to_GV (size_t n) {
497957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  GenericValue Ret;
4986c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke  if (sizeof (size_t) == sizeof (uint64_t)) {
4993c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke    Ret.ULongVal = n;
5006c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke  } else {
5016c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke    assert (sizeof (size_t) == sizeof (unsigned int));
5023c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke    Ret.UIntVal = n;
5036c9d5827388d5b5a84ed5d1c5d5c8261ffcf014fBrian Gaeke  }
504957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  return Ret;
505957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
506957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
507d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukmanstatic size_t GV_to_size_t (GenericValue GV) {
5083c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t count;
5093c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  if (sizeof (size_t) == sizeof (uint64_t)) {
5109dacd128b4539b8100e97b973ec10cc36d712849Chris Lattner    count = (size_t)GV.ULongVal;
5113c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  } else {
5123c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke    assert (sizeof (size_t) == sizeof (unsigned int));
5139dacd128b4539b8100e97b973ec10cc36d712849Chris Lattner    count = (size_t)GV.UIntVal;
5143c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  }
5153c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return count;
5163c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke}
5173c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke
5183c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke// size_t strlen(const char *src);
5193c66c355b6e88407fd77a90bf8be0e2f7297409eBrian GaekeGenericValue lle_X_strlen(FunctionType *M, const vector<GenericValue> &Args) {
5203c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  assert(Args.size() == 1);
5213c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t strlenResult = strlen ((char *) GVTOP (Args[0]));
5223c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return size_t_to_GV (strlenResult);
5233c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke}
5243c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke
52570975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke// char *strdup(const char *src);
52670975eef572b9e132bbaade16ba9edb76f15f287Brian GaekeGenericValue lle_X_strdup(FunctionType *M, const vector<GenericValue> &Args) {
52770975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  assert(Args.size() == 1);
52870975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  return PTOGV(strdup((char*)GVTOP(Args[0])));
52970975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke}
53070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke
531c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner// char *__strdup(const char *src);
532c8cff9e6432a901166de2c7488d811aabfa20f48Chris LattnerGenericValue lle_X___strdup(FunctionType *M, const vector<GenericValue> &Args) {
533c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner  assert(Args.size() == 1);
534c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner  return PTOGV(strdup((char*)GVTOP(Args[0])));
535c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner}
536c8cff9e6432a901166de2c7488d811aabfa20f48Chris Lattner
537957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner// void *memset(void *S, int C, size_t N)
538957d62aa791078ba9e09307d43fff27b68ce8d51Chris LattnerGenericValue lle_X_memset(FunctionType *M, const vector<GenericValue> &Args) {
539957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  assert(Args.size() == 3);
5403c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t count = GV_to_size_t (Args[2]);
5413c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return PTOGV(memset(GVTOP(Args[0]), Args[1].IntVal, count));
542957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner}
543957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
5445f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner// void *memcpy(void *Dest, void *src, size_t Size);
5455f311a7bce065e8d8cccec2245411ec76e23fdd6Chris LattnerGenericValue lle_X_memcpy(FunctionType *M, const vector<GenericValue> &Args) {
5465f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner  assert(Args.size() == 3);
5473c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t count = GV_to_size_t (Args[2]);
5483c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return PTOGV(memcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count));
5495f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner}
550957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
551665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===//
552665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// IO Functions...
553665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner//===----------------------------------------------------------------------===//
554665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
555005cbce20e55077d7e02255812e5df068188d302Chris Lattner// getFILE - Turn a pointer in the host address space into a legit pointer in
5560098bdfb9723c48c144fa9534ae1fe2ffb1c0f13Reid Spencer// the interpreter address space.  This is an identity transformation.
5570098bdfb9723c48c144fa9534ae1fe2ffb1c0f13Reid Spencer#define getFILE(ptr) ((FILE*)ptr)
558005cbce20e55077d7e02255812e5df068188d302Chris Lattner
559665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// FILE *fopen(const char *filename, const char *mode);
560b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fopen(FunctionType *M, const vector<GenericValue> &Args) {
561665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 2);
562b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  return PTOGV(fopen((const char *)GVTOP(Args[0]),
563b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner		     (const char *)GVTOP(Args[1])));
564665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
565665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
566665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fclose(FILE *F);
567b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fclose(FunctionType *M, const vector<GenericValue> &Args) {
568665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 1);
569665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  GenericValue GV;
570b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = fclose(getFILE(GVTOP(Args[0])));
571665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  return GV;
572665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
573665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
57425f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner// int feof(FILE *stream);
57525f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris LattnerGenericValue lle_X_feof(FunctionType *M, const vector<GenericValue> &Args) {
57625f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner  assert(Args.size() == 1);
57725f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner  GenericValue GV;
57825f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner
579b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = feof(getFILE(GVTOP(Args[0])));
58025f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner  return GV;
58125f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner}
58225f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner
583665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
584b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fread(FunctionType *M, const vector<GenericValue> &Args) {
585665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 4);
5863c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t result;
587665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
5883c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  result = fread((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
5893c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke                 GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
5903c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return size_t_to_GV (result);
591665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
592665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
593665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
594b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fwrite(FunctionType *M, const vector<GenericValue> &Args) {
595665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 4);
5963c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  size_t result;
597665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
5983c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  result = fwrite((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
5993c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke                  GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
6003c66c355b6e88407fd77a90bf8be0e2f7297409eBrian Gaeke  return size_t_to_GV (result);
601665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
602665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
603665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// char *fgets(char *s, int n, FILE *stream);
604b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fgets(FunctionType *M, const vector<GenericValue> &Args) {
605665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 3);
606b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  return GVTOP(fgets((char*)GVTOP(Args[0]), Args[1].IntVal,
607b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner		     getFILE(GVTOP(Args[2]))));
608665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
609665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
610a4479cd94615f84fe87533081e521669113557c7Chris Lattner// FILE *freopen(const char *path, const char *mode, FILE *stream);
611a4479cd94615f84fe87533081e521669113557c7Chris LattnerGenericValue lle_X_freopen(FunctionType *M, const vector<GenericValue> &Args) {
612a4479cd94615f84fe87533081e521669113557c7Chris Lattner  assert(Args.size() == 3);
613b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]),
614b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner		       getFILE(GVTOP(Args[2]))));
615a4479cd94615f84fe87533081e521669113557c7Chris Lattner}
616a4479cd94615f84fe87533081e521669113557c7Chris Lattner
617665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int fflush(FILE *stream);
618b408b1255646f31895dcbf099184e087bfa1ca39Chris LattnerGenericValue lle_X_fflush(FunctionType *M, const vector<GenericValue> &Args) {
619665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  assert(Args.size() == 1);
620665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  GenericValue GV;
621b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = fflush(getFILE(GVTOP(Args[0])));
622005cbce20e55077d7e02255812e5df068188d302Chris Lattner  return GV;
623005cbce20e55077d7e02255812e5df068188d302Chris Lattner}
624005cbce20e55077d7e02255812e5df068188d302Chris Lattner
625005cbce20e55077d7e02255812e5df068188d302Chris Lattner// int getc(FILE *stream);
626005cbce20e55077d7e02255812e5df068188d302Chris LattnerGenericValue lle_X_getc(FunctionType *M, const vector<GenericValue> &Args) {
627005cbce20e55077d7e02255812e5df068188d302Chris Lattner  assert(Args.size() == 1);
628005cbce20e55077d7e02255812e5df068188d302Chris Lattner  GenericValue GV;
629b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = getc(getFILE(GVTOP(Args[0])));
630665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  return GV;
631665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner}
632665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner
633f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner// int _IO_getc(FILE *stream);
634f87a198dcbaf95a6608b1484b42c6044d61003f6Chris LattnerGenericValue lle_X__IO_getc(FunctionType *F, const vector<GenericValue> &Args) {
635f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner  return lle_X_getc(F, Args);
636f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner}
637f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner
638a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int fputc(int C, FILE *stream);
639a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris LattnerGenericValue lle_X_fputc(FunctionType *M, const vector<GenericValue> &Args) {
640a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  assert(Args.size() == 2);
641a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  GenericValue GV;
642b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = fputc(Args[0].IntVal, getFILE(GVTOP(Args[1])));
643a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  return GV;
644a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner}
645a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner
646a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner// int ungetc(int C, FILE *stream);
647a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris LattnerGenericValue lle_X_ungetc(FunctionType *M, const vector<GenericValue> &Args) {
648a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  assert(Args.size() == 2);
649a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  GenericValue GV;
650b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GV.IntVal = ungetc(Args[0].IntVal, getFILE(GVTOP(Args[1])));
651a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  return GV;
652a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner}
653a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner
65459108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke// int ferror (FILE *stream);
65559108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian GaekeGenericValue lle_X_ferror(FunctionType *M, const vector<GenericValue> &Args) {
65659108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke  assert(Args.size() == 1);
65759108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke  GenericValue GV;
65859108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke  GV.IntVal = ferror (getFILE(GVTOP(Args[0])));
65959108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke  return GV;
66059108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke}
66159108d3d4010e6d9c4e289cc113a9f6d79da5acaBrian Gaeke
662cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output
663cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner// useful.
664cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris LattnerGenericValue lle_X_fprintf(FunctionType *M, const vector<GenericValue> &Args) {
6659dbf6dddcec7a627fabfc722e124311321de8fa0Chris Lattner  assert(Args.size() >= 2);
666cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner  char Buffer[10000];
667cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner  vector<GenericValue> NewArgs;
668b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  NewArgs.push_back(PTOGV(Buffer));
669cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner  NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end());
670b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  GenericValue GV = lle_X_sprintf(M, NewArgs);
671cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner
672b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  fputs(Buffer, getFILE(GVTOP(Args[0])));
673cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner  return GV;
674cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner}
675cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner
6767720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} // End extern "C"
6774721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner
6784721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner
679da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattnervoid Interpreter::initializeExternalFunctions() {
6800f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_Vb_putchar"]     = lle_Vb_putchar;
6810f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_ii_putchar"]     = lle_ii_putchar;
6820f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_VB_putchar"]     = lle_VB_putchar;
6830f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_X_exit"]         = lle_X_exit;
6841ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner  FuncNames["lle_X_abort"]        = lle_X_abort;
6850f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_X_malloc"]       = lle_X_malloc;
686957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_calloc"]       = lle_X_calloc;
6870f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_X_free"]         = lle_X_free;
688782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  FuncNames["lle_X_atoi"]         = lle_X_atoi;
6890f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_X_pow"]          = lle_X_pow;
69034dd24b0b83885a3992c02ce91fe02c244e83e97Chris Lattner  FuncNames["lle_X_exp"]          = lle_X_exp;
6911b600144bda9717804ae3b998c95223947200075Chris Lattner  FuncNames["lle_X_log"]          = lle_X_log;
692782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  FuncNames["lle_X_floor"]        = lle_X_floor;
693782b939db105c1ead1ee9420d95fae8c341dbf47Chris Lattner  FuncNames["lle_X_srand"]        = lle_X_srand;
694abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer  FuncNames["lle_X_rand"]         = lle_X_rand;
695abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#ifdef HAVE_RAND48
6961b600144bda9717804ae3b998c95223947200075Chris Lattner  FuncNames["lle_X_drand48"]      = lle_X_drand48;
6971b600144bda9717804ae3b998c95223947200075Chris Lattner  FuncNames["lle_X_srand48"]      = lle_X_srand48;
6981b600144bda9717804ae3b998c95223947200075Chris Lattner  FuncNames["lle_X_lrand48"]      = lle_X_lrand48;
699abec8f96e3e35fbb306c957674809c4ace04a620Reid Spencer#endif
700c063d385fa4d7255639ef0db5c506190e7cabcb4Chris Lattner  FuncNames["lle_X_sqrt"]         = lle_X_sqrt;
701b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner  FuncNames["lle_X_puts"]         = lle_X_puts;
7020f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner  FuncNames["lle_X_printf"]       = lle_X_printf;
703e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner  FuncNames["lle_X_sprintf"]      = lle_X_sprintf;
704665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_sscanf"]       = lle_X_sscanf;
705f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner  FuncNames["lle_X_scanf"]        = lle_X_scanf;
706295fe670596ed0f80850fa289f9bedd74d391b2dChris Lattner  FuncNames["lle_i_clock"]        = lle_i_clock;
707957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
708957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_strcmp"]       = lle_X_strcmp;
709957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_strcat"]       = lle_X_strcat;
710957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_strcpy"]       = lle_X_strcpy;
711957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_strlen"]       = lle_X_strlen;
712da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  FuncNames["lle_X___strdup"]     = lle_X___strdup;
713957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner  FuncNames["lle_X_memset"]       = lle_X_memset;
7145f311a7bce065e8d8cccec2245411ec76e23fdd6Chris Lattner  FuncNames["lle_X_memcpy"]       = lle_X_memcpy;
715957d62aa791078ba9e09307d43fff27b68ce8d51Chris Lattner
716665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fopen"]        = lle_X_fopen;
717665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fclose"]       = lle_X_fclose;
71825f6f373b88199d861c1c618d3aa8f7b69d1e2aeChris Lattner  FuncNames["lle_X_feof"]         = lle_X_feof;
719665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fread"]        = lle_X_fread;
720665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fwrite"]       = lle_X_fwrite;
721665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fgets"]        = lle_X_fgets;
722665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner  FuncNames["lle_X_fflush"]       = lle_X_fflush;
723a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  FuncNames["lle_X_fgetc"]        = lle_X_getc;
724005cbce20e55077d7e02255812e5df068188d302Chris Lattner  FuncNames["lle_X_getc"]         = lle_X_getc;
725f87a198dcbaf95a6608b1484b42c6044d61003f6Chris Lattner  FuncNames["lle_X__IO_getc"]     = lle_X__IO_getc;
726a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  FuncNames["lle_X_fputc"]        = lle_X_fputc;
727a5c0bfe09aad45e30805ef8a3c9358e96a39a3b5Chris Lattner  FuncNames["lle_X_ungetc"]       = lle_X_ungetc;
728cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner  FuncNames["lle_X_fprintf"]      = lle_X_fprintf;
729a4479cd94615f84fe87533081e521669113557c7Chris Lattner  FuncNames["lle_X_freopen"]      = lle_X_freopen;
7304721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner}
731d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
732