[llvm-commits] [hlvm] r38411 - in /hlvm/trunk: hlvm/CodeGen/LLVMEmitter.cpp hlvm/CodeGen/LLVMEmitter.h hlvm/CodeGen/LLVMGenerator.cpp hlvm/Pass/Validate.cpp hlvm/Reader/HLVM.rng hlvm/Reader/XMLReader.cpp hlvm/Writer/XMLWriter.cpp test/generate/dg.exp tools/hlvm-gentestcase/Generate.cpp

Reid Spencer reid at x10sys.com
Sat Jul 7 17:03:08 PDT 2007


Author: reid
Date: Sat Jul  7 19:03:08 2007
New Revision: 38411

URL: http://llvm.org/viewvc/llvm-project?rev=38411&view=rev
Log:
More test case generation changes:
1. Reduce number of generated test cases from 400 to 100. The higher order
   test cases were getting too complex and taking several minutes to 
   generate.
2. Fix several bugs in Generate.cpp so it doesn't assert out.
3. Implement the math library functions in the code generator and provide stubs
   for them in the runtime.
4. Fix HLVM.rng to match current AST nodes.
5. Revamp LLVMEmitter to reduce clutter in the .h file and provide a cleaner
   interface for LLVMGenerator.cpp. The methods for accessing runtime things are
   now all completely hidden in LLVMEmitter.cpp.

Of 103 generated tests, we now pass 11 of them.

Modified:
    hlvm/trunk/hlvm/CodeGen/LLVMEmitter.cpp
    hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/Pass/Validate.cpp
    hlvm/trunk/hlvm/Reader/HLVM.rng
    hlvm/trunk/hlvm/Reader/XMLReader.cpp
    hlvm/trunk/hlvm/Writer/XMLWriter.cpp
    hlvm/trunk/test/generate/dg.exp
    hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp

Modified: hlvm/trunk/hlvm/CodeGen/LLVMEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMEmitter.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMEmitter.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMEmitter.cpp Sat Jul  7 19:03:08 2007
@@ -32,34 +32,1112 @@
 
 using namespace llvm;
 
+namespace {
+
+class LLVMEmitterImpl : public hlvm::LLVMEmitter
+{
+  /// @name Data
+  /// @{
+  private:
+    // Caches of things to interface with the HLVM Runtime Library
+    PointerType*  hlvm_text;          ///< Opaque type for text objects
+    Function*     hlvm_text_create;   ///< Create a new text object
+    Function*     hlvm_text_delete;   ///< Delete a text object
+    Function*     hlvm_text_to_buffer;///< Convert text to a buffer
+    PointerType*  hlvm_buffer;        ///< Pointer To octet
+    Function*     hlvm_buffer_create; ///< Create a new buffer object
+    Function*     hlvm_buffer_delete; ///< Delete a buffer
+    PointerType*  hlvm_stream;        ///< Pointer to stream type
+    Function*     hlvm_stream_open;   ///< Function for stream_open
+    Function*     hlvm_stream_read;   ///< Function for stream_read
+    Function*     hlvm_stream_write_buffer; ///< Write buffer to stream
+    Function*     hlvm_stream_write_text;   ///< Write text to stream
+    Function*     hlvm_stream_write_string; ///< Write string to stream
+    Function*     hlvm_stream_close;  ///< Function for stream_close
+    Function*     hlvm_f32_ispinf;
+    Function*     hlvm_f32_isninf ;
+    Function*     hlvm_f32_isnan ;
+    Function*     hlvm_f32_trunc ;
+    Function*     hlvm_f32_round ;
+    Function*     hlvm_f32_floor ;
+    Function*     hlvm_f32_ceiling ;
+    Function*     hlvm_f32_loge ;
+    Function*     hlvm_f32_log2 ;
+    Function*     hlvm_f32_log10 ;
+    Function*     hlvm_f32_squareroot ;
+    Function*     hlvm_f32_cuberoot ;
+    Function*     hlvm_f32_factorial ;
+    Function*     hlvm_f32_power ;
+    Function*     hlvm_f32_root ;
+    Function*     hlvm_f32_gcd ;
+    Function*     hlvm_f32_lcm;
+    Function*     hlvm_f64_ispinf;
+    Function*     hlvm_f64_isninf ;
+    Function*     hlvm_f64_isnan ;
+    Function*     hlvm_f64_trunc ;
+    Function*     hlvm_f64_round ;
+    Function*     hlvm_f64_floor ;
+    Function*     hlvm_f64_ceiling ;
+    Function*     hlvm_f64_loge ;
+    Function*     hlvm_f64_log2 ;
+    Function*     hlvm_f64_log10 ;
+    Function*     hlvm_f64_squareroot ;
+    Function*     hlvm_f64_cuberoot ;
+    Function*     hlvm_f64_factorial ;
+    Function*     hlvm_f64_power ;
+    Function*     hlvm_f64_root ;
+    Function*     hlvm_f64_gcd ;
+    Function*     hlvm_f64_lcm;
+
+    FunctionType* hlvm_program_signature; ///< The llvm type for programs
+
+    // Caches of LLVM Intrinsic functions
+    Function*     llvm_memcpy;         ///< llvm.memcpy.i64
+    Function*     llvm_memmove;        ///< llvm.memmove.i64
+    Function*     llvm_memset;         ///< llvm.memset.i64
+
+  /// @}
+  /// @name Constructor
+  /// @{
+  public:
+    LLVMEmitterImpl() : hlvm::LLVMEmitter(), 
+      hlvm_text(0), hlvm_text_create(0), hlvm_text_delete(0),
+      hlvm_text_to_buffer(0), 
+      hlvm_buffer(0), hlvm_buffer_create(0), hlvm_buffer_delete(0),
+      hlvm_stream(0), hlvm_stream_open(0), hlvm_stream_read(0),
+      hlvm_stream_write_buffer(0), hlvm_stream_write_text(0), 
+      hlvm_stream_write_string(0), hlvm_stream_close(0), 
+      hlvm_f32_ispinf(0), hlvm_f32_isninf(0), hlvm_f32_isnan(0),
+      hlvm_f32_trunc(0), hlvm_f32_round(0), hlvm_f32_floor (0),
+      hlvm_f32_ceiling(0), hlvm_f32_loge(0), hlvm_f32_log2(0),
+      hlvm_f32_log10(0), hlvm_f32_squareroot(0), hlvm_f32_cuberoot(0),
+      hlvm_f32_factorial(0), hlvm_f32_power(0), hlvm_f32_root(0),
+      hlvm_f32_gcd(0), hlvm_f32_lcm(0), hlvm_f64_ispinf(0), hlvm_f64_isninf(0),
+      hlvm_f64_isnan(0), hlvm_f64_trunc(0), hlvm_f64_round(0),
+      hlvm_f64_floor(0), hlvm_f64_ceiling(0), hlvm_f64_loge(0),
+      hlvm_f64_log2(0), hlvm_f64_log10(0), hlvm_f64_squareroot(0),
+      hlvm_f64_cuberoot(0), hlvm_f64_factorial(0), hlvm_f64_power(0),
+      hlvm_f64_root(0), hlvm_f64_gcd(0), hlvm_f64_lcm(0),
+      hlvm_program_signature(0),
+      llvm_memcpy(0), llvm_memmove(0), llvm_memset(0)
+    { 
+    }
+
+  /// @}
+  /// @name Methods
+  /// @{
+  public:
+    Type* get_hlvm_size() { return Type::ULongTy; }
+
+    PointerType* get_hlvm_text()
+    {
+      if (! hlvm_text) {
+        // An hlvm_text is a variable length array of signed bytes preceded by
+        // an
+        // Arglist args;
+        // args.push_back(Type::UIntTy);
+        // args.push_back(ArrayType::Get(Type::SByteTy,0));
+        OpaqueType* opq = OpaqueType::get();
+        TheModule->addTypeName("hlvm_text_obj", opq);
+        hlvm_text = PointerType::get(opq);
+        TheModule->addTypeName("hlvm_text", hlvm_text);
+      }
+      return hlvm_text;
+    }
+
+    Function* get_hlvm_text_create()
+    {
+      if (! hlvm_text_create) {
+        Type* result = get_hlvm_text();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(PointerType::get(Type::SByteTy));
+        FunctionType* FT = 
+          FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_text_create",FT);
+        hlvm_text_create = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_text_create", TheModule);
+      }
+      return hlvm_text_create;
+    }
+
+    CallInst* call_hlvm_text_create(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_text_create();
+      return new CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
+    }
+
+    Function* get_hlvm_text_delete()
+    {
+      if (! hlvm_text_delete) {
+        Type* result = get_hlvm_text();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_text());
+        FunctionType* FT = 
+          FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_text_delete",FT);
+        hlvm_text_delete = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_text_delete", TheModule);
+      }
+      return hlvm_text_delete;
+    }
+
+    CallInst* call_hlvm_text_delete(const hlvm::ArgList& args)
+    {
+      Function* F = get_hlvm_text_delete();
+      return new CallInst(F, args, "hlvm_text_delete", TheBlock);
+    }
+
+    Function* get_hlvm_text_to_buffer()
+    {
+      if (! hlvm_text_to_buffer) {
+        Type* result = get_hlvm_buffer();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_text());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_text_to_buffer_signature",FT);
+        hlvm_text_to_buffer = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_text_to_buffer", TheModule);
+      }
+      return hlvm_text_to_buffer;
+    }
+
+    CallInst* call_hlvm_text_to_buffer(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_text_to_buffer();
+      return new CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
+    }
+
+    PointerType* get_hlvm_buffer()
+    {
+      if (! hlvm_buffer) {
+        OpaqueType* opq = OpaqueType::get();
+        TheModule->addTypeName("hlvm_buffer_obj", opq);
+        hlvm_buffer = PointerType::get(opq);
+        TheModule->addTypeName("hlvm_buffer", hlvm_buffer);
+      }
+      return hlvm_buffer;
+    }
+
+    Function* get_hlvm_buffer_create()
+    {
+      if (! hlvm_buffer_create) {
+        Type* result = get_hlvm_buffer();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_size());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_buffer_create",FT);
+        hlvm_buffer_create = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_buffer_create", TheModule);
+      }
+      return hlvm_buffer_create;
+    }
+
+    CallInst* call_hlvm_buffer_create(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_buffer_create();
+      return new CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
+    }
+
+    Function* get_hlvm_buffer_delete()
+    {
+      if (! hlvm_buffer_delete) {
+        Type* result = get_hlvm_buffer();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_buffer());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_buffer_delete",FT);
+        hlvm_buffer_delete = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_buffer_delete", TheModule);
+      }
+      return hlvm_buffer_delete;
+    }
+
+    CallInst* call_hlvm_buffer_delete(const hlvm::ArgList& args)
+    {
+      Function* F = get_hlvm_buffer_delete();
+      return new CallInst(F, args, "", TheBlock);
+    }
+
+    PointerType* get_hlvm_stream()
+    {
+      if (! hlvm_stream) {
+        OpaqueType* opq = OpaqueType::get();
+        TheModule->addTypeName("hlvm_stream_obj", opq);
+        hlvm_stream= PointerType::get(opq);
+        TheModule->addTypeName("hlvm_stream", hlvm_stream);
+      }
+      return hlvm_stream;
+    }
+
+    Function* get_hlvm_stream_open()
+    {
+      if (!hlvm_stream_open) {
+        Type* result = get_hlvm_stream();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(PointerType::get(Type::SByteTy));
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_open_signature",FT);
+        hlvm_stream_open = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+            "hlvm_stream_open", TheModule);
+      }
+      return hlvm_stream_open;
+    }
+
+    CallInst* call_hlvm_stream_open(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_stream_open();
+      return new CallInst(F, args, (nm ? nm : "stream"), TheBlock);
+    }
+
+    Function* get_hlvm_stream_read()
+    {
+      if (!hlvm_stream_read) {
+        Type* result = get_hlvm_size();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_stream());
+        arg_types.push_back(get_hlvm_buffer());
+        arg_types.push_back(get_hlvm_size());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_read_signature",FT);
+        hlvm_stream_read = 
+          new Function(FT, GlobalValue::ExternalLinkage,
+          "hlvm_stream_read", TheModule);
+      }
+      return hlvm_stream_read;
+    }
+
+    CallInst* call_hlvm_stream_read(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_stream_read();
+      return new CallInst(F, args, (nm ? nm : "readlen"), TheBlock);
+    }
+
+    Function* get_hlvm_stream_write_buffer()
+    {
+      if (!hlvm_stream_write_buffer) {
+        Type* result = get_hlvm_size();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_stream());
+        arg_types.push_back(get_hlvm_buffer());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_write_buffer_signature",FT);
+        hlvm_stream_write_buffer = 
+          new Function(FT, GlobalValue::ExternalLinkage,
+          "hlvm_stream_write_buffer", TheModule);
+      }
+      return hlvm_stream_write_buffer;
+    }
+
+    CallInst* call_hlvm_stream_write_buffer(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_stream_write_buffer();
+      return new CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
+    }
+
+    Function* get_hlvm_stream_write_string()
+    {
+      if (!hlvm_stream_write_string) {
+        Type* result = get_hlvm_size();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_stream());
+        arg_types.push_back(PointerType::get(Type::SByteTy));
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_write_string_signature",FT);
+        hlvm_stream_write_string = 
+          new Function(FT, GlobalValue::ExternalLinkage,
+          "hlvm_stream_write_string", TheModule);
+      }
+      return hlvm_stream_write_string;
+    }
+
+    CallInst* call_hlvm_stream_write_string(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_stream_write_string();
+      return new CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
+    }
+
+    Function* get_hlvm_stream_write_text()
+    {
+      if (!hlvm_stream_write_text) {
+        Type* result = get_hlvm_size();
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_stream());
+        arg_types.push_back(get_hlvm_text());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_write_text_signature",FT);
+        hlvm_stream_write_text = 
+          new Function(FT, GlobalValue::ExternalLinkage,
+          "hlvm_stream_write_text", TheModule);
+      }
+      return hlvm_stream_write_text;
+    }
+
+    CallInst* call_hlvm_stream_write_text(const hlvm::ArgList& args, const char* nm)
+    {
+      Function* F = get_hlvm_stream_write_text();
+      return new CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
+    }
+
+    Function* get_hlvm_stream_close()
+    {
+      if (!hlvm_stream_close) {
+        Type* result = Type::VoidTy;
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(get_hlvm_stream());
+        FunctionType* FT = FunctionType::get(result,arg_types,false);
+        TheModule->addTypeName("hlvm_stream_close_signature",FT);
+        hlvm_stream_close = 
+          new Function(FT, GlobalValue::ExternalLinkage,
+          "hlvm_stream_close", TheModule);
+      }
+      return hlvm_stream_close;
+    }
+
+    CallInst* call_hlvm_stream_close(const hlvm::ArgList& args)
+    {
+      Function* F = get_hlvm_stream_close();
+      return new CallInst(F, args, "", TheBlock);
+    }
+
+    FunctionType* get_hlvm_program_signature()
+    {
+      if (!hlvm_program_signature) {
+        // Get the type of function that all entry points must have
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::IntTy);
+        arg_types.push_back(
+          PointerType::get(PointerType::get(Type::SByteTy)));
+        hlvm_program_signature = 
+          FunctionType::get(Type::IntTy,arg_types,false);
+        TheModule->addTypeName("hlvm_program_signature",hlvm_program_signature);
+      }
+      return hlvm_program_signature;
+    }
+
+    Function* get_llvm_memcpy()
+    {
+      if (!llvm_memcpy) {
+        const Type *SBP = PointerType::get(Type::SByteTy);
+        llvm_memcpy = TheModule->getOrInsertFunction(
+          "llvm.memcpy.i64", Type::VoidTy, SBP, SBP, Type::ULongTy,
+          Type::UIntTy, NULL);
+      }
+      return llvm_memcpy;
+    }
+
+    Function* get_llvm_memmove()
+    {
+      if (!llvm_memmove) {
+        const Type *SBP = PointerType::get(Type::SByteTy);
+        llvm_memmove = TheModule->getOrInsertFunction(
+          "llvm.memmove.i64", Type::VoidTy, SBP, SBP, Type::ULongTy, 
+          Type::UIntTy, NULL);
+      }
+      return llvm_memmove;
+    }
+
+    Function* get_llvm_memset()
+    {
+      if (!llvm_memset) {
+        const Type *SBP = PointerType::get(Type::SByteTy);
+        llvm_memset = TheModule->getOrInsertFunction(
+          "llvm.memset.i64", Type::VoidTy, SBP, Type::UByteTy, Type::ULongTy, 
+          Type::UIntTy, NULL);
+      }
+      return llvm_memset;
+    }
+
+    Function* get_hlvm_f32_ispinf()
+    {
+      if (! hlvm_f32_ispinf) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_ispinf",FT);
+        hlvm_f32_ispinf = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_ispinf", TheModule);
+      }
+      return hlvm_f32_ispinf;
+    }
+
+    Function* get_hlvm_f32_isninf()
+    {
+      if (! hlvm_f32_isninf) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_isninf",FT);
+        hlvm_f32_isninf = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_isninf", TheModule);
+      }
+      return hlvm_f32_isninf;
+    }
+
+    Function* get_hlvm_f32_isnan()
+    {
+      if (! hlvm_f32_isnan) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_isnan",FT);
+        hlvm_f32_isnan = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_isnan", TheModule);
+      }
+      return hlvm_f32_isnan;
+    }
+
+    Function* get_hlvm_f32_trunc()
+    {
+      if (! hlvm_f32_trunc) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_trunc",FT);
+        hlvm_f32_trunc = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_trunc", TheModule);
+      }
+      return hlvm_f32_trunc;
+    }
+
+    Function* get_hlvm_f32_round()
+    {
+      if (! hlvm_f32_round) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_round",FT);
+        hlvm_f32_round = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_round", TheModule);
+      }
+      return hlvm_f32_round;
+    }
+
+    Function* get_hlvm_f32_floor()
+    {
+      if (! hlvm_f32_floor) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_floor",FT);
+        hlvm_f32_floor = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_floor", TheModule);
+      }
+      return hlvm_f32_floor;
+    }
+
+    Function* get_hlvm_f32_ceiling()
+    {
+      if (! hlvm_f32_ceiling) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_ceiling",FT);
+        hlvm_f32_ceiling = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_ceiling", TheModule);
+      }
+      return hlvm_f32_ceiling;
+    }
+
+    Function* get_hlvm_f32_loge()
+    {
+      if (! hlvm_f32_loge) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_loge",FT);
+        hlvm_f32_loge = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_loge", TheModule);
+      }
+      return hlvm_f32_loge;
+    }
+
+    Function* get_hlvm_f32_log2()
+    {
+      if (! hlvm_f32_log2) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_log2",FT);
+        hlvm_f32_log2 = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_log2", TheModule);
+      }
+      return hlvm_f32_log2;
+    }
+
+    Function* get_hlvm_f32_log10()
+    {
+      if (! hlvm_f32_log10) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_log10",FT);
+        hlvm_f32_log10 = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_log10", TheModule);
+      }
+      return hlvm_f32_log10;
+    }
+
+    Function* get_hlvm_f32_squareroot()
+    {
+      if (! hlvm_f32_squareroot) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_squareroot",FT);
+        hlvm_f32_squareroot = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_squareroot", TheModule);
+      }
+      return hlvm_f32_squareroot;
+    }
+
+    Function* get_hlvm_f32_cuberoot()
+    {
+      if (! hlvm_f32_cuberoot) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_cuberoot",FT);
+        hlvm_f32_cuberoot = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_cuberoot", TheModule);
+      }
+      return hlvm_f32_cuberoot;
+    }
+
+    Function* get_hlvm_f32_factorial()
+    {
+      if (! hlvm_f32_factorial) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_factorial",FT);
+        hlvm_f32_factorial = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_factorial", TheModule);
+      }
+      return hlvm_f32_factorial;
+    }
+
+    Function* get_hlvm_f32_power()
+    {
+      if (! hlvm_f32_power) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_power",FT);
+        hlvm_f32_power = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_power", TheModule);
+      }
+      return hlvm_f32_ispinf;
+    }
+
+    Function* get_hlvm_f32_root()
+    {
+      if (! hlvm_f32_root) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_root",FT);
+        hlvm_f32_root = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_root", TheModule);
+      }
+      return hlvm_f32_ispinf;
+    }
+
+    Function* get_hlvm_f32_gcd()
+    {
+      if (! hlvm_f32_gcd) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_gcd",FT);
+        hlvm_f32_gcd = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_gcd", TheModule);
+      }
+      return hlvm_f32_ispinf;
+    }
+
+    Function* get_hlvm_f32_lcm()
+    {
+      if (! hlvm_f32_lcm) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::FloatTy);
+        arg_types.push_back(Type::FloatTy);
+        FunctionType* FT = FunctionType::get(Type::FloatTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f32_lcm",FT);
+        hlvm_f32_lcm = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f32_lcm", TheModule);
+      }
+      return hlvm_f32_ispinf;
+    }
+
+    CallInst* call_hlvm_f32_ispinf(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_ispinf(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_isninf(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_isninf(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_isnan(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_isnan(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_trunc(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_trunc(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_round(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_round(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_floor(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_floor(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_ceiling(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_ceiling(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_loge(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_loge(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_log2(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_log2(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_log10(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_log10(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_squareroot(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_squareroot(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_cuberoot(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_cuberoot(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_factorial(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_factorial(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_power(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_power(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_root(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_root(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_gcd(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_gcd(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f32_lcm(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f32_lcm(), args, "", TheBlock);
+    }
+
+    Function* get_hlvm_f64_ispinf()
+    {
+      if (! hlvm_f64_ispinf) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_ispinf",FT);
+        hlvm_f64_ispinf = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_ispinf", TheModule);
+      }
+      return hlvm_f64_ispinf;
+    }
+
+    Function* get_hlvm_f64_isninf()
+    {
+      if (! hlvm_f64_isninf) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_isninf",FT);
+        hlvm_f64_isninf = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_isninf", TheModule);
+      }
+      return hlvm_f64_isninf;
+    }
+
+    Function* get_hlvm_f64_isnan()
+    {
+      if (! hlvm_f64_isnan) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_isnan",FT);
+        hlvm_f64_isnan = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_isnan", TheModule);
+      }
+      return hlvm_f64_isnan;
+    }
+
+    Function* get_hlvm_f64_trunc()
+    {
+      if (! hlvm_f64_trunc) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_trunc",FT);
+        hlvm_f64_trunc = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_trunc", TheModule);
+      }
+      return hlvm_f64_trunc;
+    }
+
+    Function* get_hlvm_f64_round()
+    {
+      if (! hlvm_f64_round) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_round",FT);
+        hlvm_f64_round = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_round", TheModule);
+      }
+      return hlvm_f64_round;
+    }
+
+    Function* get_hlvm_f64_floor()
+    {
+      if (! hlvm_f64_floor) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_floor",FT);
+        hlvm_f64_floor = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_floor", TheModule);
+      }
+      return hlvm_f64_floor;
+    }
+
+    Function* get_hlvm_f64_ceiling()
+    {
+      if (! hlvm_f64_ceiling) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_ceiling",FT);
+        hlvm_f64_ceiling = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_ceiling", TheModule);
+      }
+      return hlvm_f64_ceiling;
+    }
+
+    Function* get_hlvm_f64_loge()
+    {
+      if (! hlvm_f64_loge) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_loge",FT);
+        hlvm_f64_loge = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_loge", TheModule);
+      }
+      return hlvm_f64_loge;
+    }
+
+    Function* get_hlvm_f64_log2()
+    {
+      if (! hlvm_f64_log2) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_log2",FT);
+        hlvm_f64_log2 = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_log2", TheModule);
+      }
+      return hlvm_f64_log2;
+    }
+
+    Function* get_hlvm_f64_log10()
+    {
+      if (! hlvm_f64_log10) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_log10",FT);
+        hlvm_f64_log10 = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_log10", TheModule);
+      }
+      return hlvm_f64_log10;
+    }
+
+    Function* get_hlvm_f64_squareroot()
+    {
+      if (! hlvm_f64_squareroot) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_squareroot",FT);
+        hlvm_f64_squareroot = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_squareroot", TheModule);
+      }
+      return hlvm_f64_squareroot;
+    }
+
+    Function* get_hlvm_f64_cuberoot()
+    {
+      if (! hlvm_f64_cuberoot) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_cuberoot",FT);
+        hlvm_f64_cuberoot = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_cuberoot", TheModule);
+      }
+      return hlvm_f64_cuberoot;
+    }
+
+    Function* get_hlvm_f64_factorial()
+    {
+      if (! hlvm_f64_factorial) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_factorial",FT);
+        hlvm_f64_factorial = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_factorial", TheModule);
+      }
+      return hlvm_f64_factorial;
+    }
+
+    Function* get_hlvm_f64_power()
+    {
+      if (! hlvm_f64_power) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_power",FT);
+        hlvm_f64_power = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_power", TheModule);
+      }
+      return hlvm_f64_ispinf;
+    }
+
+    Function* get_hlvm_f64_root()
+    {
+      if (! hlvm_f64_root) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_root",FT);
+        hlvm_f64_root = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_root", TheModule);
+      }
+      return hlvm_f64_ispinf;
+    }
+
+    Function* get_hlvm_f64_gcd()
+    {
+      if (! hlvm_f64_gcd) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_gcd",FT);
+        hlvm_f64_gcd = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_gcd", TheModule);
+      }
+      return hlvm_f64_ispinf;
+    }
+
+    Function* get_hlvm_f64_lcm()
+    {
+      if (! hlvm_f64_lcm) {
+        std::vector<const Type*> arg_types;
+        arg_types.push_back(Type::DoubleTy);
+        arg_types.push_back(Type::DoubleTy);
+        FunctionType* FT = FunctionType::get(Type::DoubleTy,arg_types,false);
+        TheModule->addTypeName("hlvm_f64_lcm",FT);
+        hlvm_f64_lcm = 
+          new Function(FT, GlobalValue::ExternalLinkage, 
+          "hlvm_f64_lcm", TheModule);
+      }
+      return hlvm_f64_ispinf;
+    }
+
+    CallInst* call_hlvm_f64_ispinf(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_ispinf(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_isninf(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_isninf(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_isnan(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_isnan(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_trunc(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_trunc(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_round(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_round(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_floor(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_floor(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_ceiling(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_ceiling(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_loge(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_loge(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_log2(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_log2(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_log10(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_log10(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_squareroot(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_squareroot(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_cuberoot(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_cuberoot(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_factorial(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_factorial(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_power(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_power(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_root(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_root(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_gcd(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_gcd(), args, "", TheBlock);
+    }
+
+    CallInst* call_hlvm_f64_lcm(const hlvm::ArgList& args)
+    {
+      return new CallInst(get_hlvm_f64_lcm(), args, "", TheBlock);
+    }
+
+  /// @}
+};
+
+}
+
 namespace hlvm {
 
 LLVMEmitter::LLVMEmitter()
   : TheModule(0), TheFunction(0), TheEntryBlock(0), TheExitBlock(0), 
-    EntryInsertionPoint(0), TheBlock(0),
-    hlvm_text(0), hlvm_text_create(0), hlvm_text_delete(0),
-    hlvm_text_to_buffer(0), 
-    hlvm_buffer(0), hlvm_buffer_create(0), hlvm_buffer_delete(0),
-    hlvm_stream(0), hlvm_stream_open(0), hlvm_stream_read(0),
-    hlvm_stream_write_buffer(0), hlvm_stream_write_text(0), 
-    hlvm_stream_write_string(0), hlvm_stream_close(0), 
-    hlvm_program_signature(0),
-    llvm_memcpy(0), llvm_memmove(0), llvm_memset(0)
-{ 
+    EntryInsertionPoint(0), TheBlock(0)
+{
 }
 
-llvm::Module*
+LLVMEmitter* 
+new_LLVMEmitter()
+{
+  return new LLVMEmitterImpl();
+}
+
+Module*
 LLVMEmitter::StartModule(const std::string& ID)
 {
   hlvmAssert(TheModule == 0);
-  return TheModule = new llvm::Module(ID);
+  return TheModule = new Module(ID);
 }
 
-llvm::Module*
+Module*
 LLVMEmitter::FinishModule()
 {
   hlvmAssert(TheModule != 0);
-  llvm::Module* result = TheModule;
+  Module* result = TheModule;
   TheModule = 0;
   return result;
 }
@@ -107,24 +1185,24 @@
   // The entry block was created to hold the automatic variables. We now
   // need to terminate the block by branching it to the first active block
   // in the function.
-  new llvm::BranchInst(TheFunction->front().getNext(),&TheFunction->front());
+  new BranchInst(TheFunction->front().getNext(),&TheFunction->front());
   hlvmAssert(blocks.empty());
   hlvmAssert(breaks.empty());
   hlvmAssert(continues.empty());
 }
 
-llvm::BasicBlock*
+BasicBlock*
 LLVMEmitter::pushBlock(const std::string& name)
 {
-  TheBlock = new llvm::BasicBlock(name,TheFunction);
+  TheBlock = new BasicBlock(name,TheFunction);
   blocks.push_back(TheBlock);
   return TheBlock;
 }
 
-llvm::BasicBlock* 
+BasicBlock* 
 LLVMEmitter::popBlock()
 {
-  llvm::BasicBlock* result = blocks.back();
+  BasicBlock* result = blocks.back();
   blocks.pop_back();
   if (blocks.empty())
     TheBlock = 0;
@@ -133,45 +1211,45 @@
   return result;
 }
 
-llvm::BasicBlock*
+BasicBlock*
 LLVMEmitter::newBlock(const std::string& name)
 {
   blocks.pop_back();
-  TheBlock = new llvm::BasicBlock(name,TheFunction);
+  TheBlock = new BasicBlock(name,TheFunction);
   blocks.push_back(TheBlock);
   return TheBlock;
 }
 
-llvm::Value* 
-LLVMEmitter::ConvertToBoolean(llvm::Value* V) const
+Value* 
+LLVMEmitter::ConvertToBoolean(Value* V) const
 {
-  const llvm::Type* Ty = V->getType();
-  if (Ty == llvm::Type::BoolTy)
+  const Type* Ty = V->getType();
+  if (Ty == Type::BoolTy)
     return V;
 
   if (Ty->isInteger() || Ty->isFloatingPoint()) {
-    llvm::Constant* CI = llvm::Constant::getNullValue(V->getType());
-    return new llvm::SetCondInst(llvm::Instruction::SetNE, V, CI, "i2b", 
+    Constant* CI = Constant::getNullValue(V->getType());
+    return new SetCondInst(Instruction::SetNE, V, CI, "i2b", 
         TheBlock);
-  } else if (llvm::isa<llvm::GlobalValue>(V)) {
+  } else if (isa<GlobalValue>(V)) {
     // GlobalValues always have non-zero constant address values, so always true
-    return llvm::ConstantBool::get(true);
+    return ConstantBool::get(true);
   }
   hlvmAssert(!"Don't know how to convert V into bool");
-  return llvm::ConstantBool::get(true);
+  return ConstantBool::get(true);
 }
 
 Value* 
-LLVMEmitter::Pointer2Value(llvm::Value* V) const
+LLVMEmitter::Pointer2Value(Value* V) const
 {
-  if (!llvm::isa<llvm::PointerType>(V->getType()))
+  if (!isa<PointerType>(V->getType()))
     return V;
 
- // llvm::GetElementPtrInst* GEP = new llvm::GetElementPtrIns(V,
-  //    llvm::ConstantInt::get(llvm::Type::UIntTy,0),
-   //   llvm::ConstantInt::get(llvm::Type::UIntTy,0),
+ // GetElementPtrInst* GEP = new GetElementPtrIns(V,
+  //    ConstantInt::get(Type::UIntTy,0),
+   //   ConstantInt::get(Type::UIntTy,0),
     //  "ptr2Value", TheBlock);
-  return new llvm::LoadInst(V,"ptr2Value", TheBlock);
+  return new LoadInst(V,"ptr2Value", TheBlock);
 }
 
 bool
@@ -220,7 +1298,7 @@
 }
 
 void 
-LLVMEmitter::ResolveBreaks(llvm::BasicBlock* exit)
+LLVMEmitter::ResolveBreaks(BasicBlock* exit)
 {
   for (BranchList::iterator I = breaks.begin(), E = breaks.end(); I != E; ++I) {
     (*I)->setOperand(0,exit);
@@ -229,7 +1307,7 @@
 }
 
 void 
-LLVMEmitter::ResolveContinues(llvm::BasicBlock* entry)
+LLVMEmitter::ResolveContinues(BasicBlock* entry)
 {
   for (BranchList::iterator I = continues.begin(), E = continues.end(); 
        I != E; ++I) {
@@ -298,6 +1376,30 @@
   return result;
 }
 
+Type*
+LLVMEmitter::getTextType()
+{
+  return static_cast<LLVMEmitterImpl*>(this)->get_hlvm_text();
+}
+
+Type*
+LLVMEmitter::getStreamType()
+{
+  return static_cast<LLVMEmitterImpl*>(this)->get_hlvm_stream();
+}
+
+Type*
+LLVMEmitter::getBufferType()
+{
+  return static_cast<LLVMEmitterImpl*>(this)->get_hlvm_buffer();
+}
+
+FunctionType* 
+LLVMEmitter::getProgramType()
+{
+  return static_cast<LLVMEmitterImpl*>(this)->get_hlvm_program_signature();
+}
+
 void
 LLVMEmitter::emitAssign(Value* dest, Value* src)
 {
@@ -408,7 +1510,7 @@
   if (getNumElements(Ty) <= 8) 
     CopyAggregate(DestPtr, false, SrcPtr, false, TheBlock);
   else 
-    emitMemCpy(DestPtr, SrcPtr, llvm::ConstantExpr::getSizeOf(Ty));
+    emitMemCpy(DestPtr, SrcPtr, ConstantExpr::getSizeOf(Ty));
 }
 
 ReturnInst*
@@ -417,14 +1519,14 @@
   // First deal with the degenerate case, a void return
   if (retVal == 0) {
     hlvmAssert(getReturnType() == Type::VoidTy);
-    return new llvm::ReturnInst(0,TheBlock);
+    return new ReturnInst(0,TheBlock);
   }
 
   // Now, deal with first class result types. Becasue of the way function
   // types are generated, a void type at this point indicates an aggregate
   // result. If we don't have a void type, then it must be a first class result.
   const Type* resultTy = retVal->getType();
-  if (getReturnType() != llvm::Type::VoidTy) {
+  if (getReturnType() != Type::VoidTy) {
     Value* result = 0;
     if (const PointerType* PTy = dyn_cast<PointerType>(resultTy)) {
       // must be an autovar or global var, just load the value
@@ -438,7 +1540,7 @@
       result = retVal;
     }
     hlvmAssert(result && "No result for function");
-    return new llvm::ReturnInst(result,TheBlock);
+    return new ReturnInst(result,TheBlock);
   }
 
   // Now, deal with the aggregate result case. At this point the function return
@@ -458,11 +1560,11 @@
   emitAggregateCopy(result_arg, retVal);
 
   // Emit the void return
-  return new llvm::ReturnInst(0, TheBlock);
+  return new ReturnInst(0, TheBlock);
 }
 
-llvm::CallInst* 
-LLVMEmitter::emitCall(llvm::Function* F, const ArgList& args) 
+CallInst* 
+LLVMEmitter::emitCall(Function* F, const ArgList& args) 
 {
   // Detect the aggregate result case
   if ((F->getReturnType() == Type::VoidTy) &&
@@ -493,7 +1595,7 @@
           newArgs.push_back(*I);
 
       // Generate the call
-      return new llvm::CallInst(F, newArgs, "", TheBlock);
+      return new CallInst(F, newArgs, "", TheBlock);
     }
   }
 
@@ -510,14 +1612,14 @@
         cast<Constant>(*I), (*I)->getName()));
     else
       newArgs.push_back(*I);
-  return new llvm::CallInst(F, newArgs, F->getName() + "_result", TheBlock);
+  return new CallInst(F, newArgs, F->getName() + "_result", TheBlock);
 }
 
 void 
 LLVMEmitter::emitMemCpy(
-  llvm::Value *dest, 
-  llvm::Value *src, 
-  llvm::Value *size
+  Value *dest, 
+  Value *src, 
+  Value *size
 )
 {
   const Type *SBP = PointerType::get(Type::SByteTy);
@@ -526,15 +1628,16 @@
   args.push_back(CastToType(src, SBP));
   args.push_back(size);
   args.push_back(ConstantUInt::get(Type::UIntTy, 0));
-  new CallInst(get_llvm_memcpy(), args, "", TheBlock);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  new CallInst(emimp->get_llvm_memcpy(), args, "", TheBlock);
 }
 
 /// Emit an llvm.memmove.i64 intrinsic
 void 
 LLVMEmitter::emitMemMove(
-  llvm::Value *dest,
-  llvm::Value *src, 
-  llvm::Value *size
+  Value *dest,
+  Value *src, 
+  Value *size
 )
 {
   const Type *SBP = PointerType::get(Type::SByteTy);
@@ -543,15 +1646,16 @@
   args.push_back(CastToType(src, SBP));
   args.push_back(size);
   args.push_back(ConstantUInt::get(Type::UIntTy, 0));
-  new CallInst(get_llvm_memmove(), args, "", TheBlock);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  new CallInst(emimp->get_llvm_memmove(), args, "", TheBlock);
 }
 
 /// Emit an llvm.memset.i64 intrinsic
 void 
 LLVMEmitter::emitMemSet(
-  llvm::Value *dest, 
-  llvm::Value *val, 
-  llvm::Value *size 
+  Value *dest, 
+  Value *val, 
+  Value *size 
 )
 {
   const Type *SBP = PointerType::get(Type::SByteTy);
@@ -560,365 +1664,283 @@
   args.push_back(CastToType(val, Type::UByteTy));
   args.push_back(size);
   args.push_back(ConstantUInt::get(Type::UIntTy, 0));
-  new CallInst(get_llvm_memset(), args, "", TheBlock);
-}
-
-llvm::Type*
-LLVMEmitter::get_hlvm_size()
-{
-  return llvm::Type::ULongTy;
-}
-
-llvm::PointerType*
-LLVMEmitter::get_hlvm_text()
-{
-  if (! hlvm_text) {
-    // An hlvm_text is a variable length array of signed bytes preceded by
-    // an
-    // Arglist args;
-    // args.push_back(Type::UIntTy);
-    // args.push_back(ArrayType::Get(Type::SByteTy,0));
-    llvm::OpaqueType* opq = llvm::OpaqueType::get();
-    TheModule->addTypeName("hlvm_text_obj", opq);
-    hlvm_text = llvm::PointerType::get(opq);
-    TheModule->addTypeName("hlvm_text", hlvm_text);
-  }
-  return hlvm_text;
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_text_create()
-{
-  if (! hlvm_text_create) {
-    llvm::Type* result = get_hlvm_text();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(llvm::PointerType::get(llvm::Type::SByteTy));
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_text_create",FT);
-    hlvm_text_create = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-      "hlvm_text_create", TheModule);
-  }
-  return hlvm_text_create;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_text_create(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_text_create();
-  return new llvm::CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_text_delete()
-{
-  if (! hlvm_text_delete) {
-    llvm::Type* result = get_hlvm_text();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_text());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_text_delete",FT);
-    hlvm_text_delete = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-      "hlvm_text_delete", TheModule);
-  }
-  return hlvm_text_delete;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_text_delete(const ArgList& args)
-{
-  Function* F = get_hlvm_text_delete();
-  return new llvm::CallInst(F, args, "hlvm_text_delete", TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_text_to_buffer()
-{
-  if (! hlvm_text_to_buffer) {
-    llvm::Type* result = get_hlvm_buffer();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_text());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_text_to_buffer_signature",FT);
-    hlvm_text_to_buffer = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-      "hlvm_text_to_buffer", TheModule);
-  }
-  return hlvm_text_to_buffer;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_text_to_buffer(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_text_to_buffer();
-  return new llvm::CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
-}
-
-llvm::PointerType*
-LLVMEmitter::get_hlvm_buffer()
-{
-  if (! hlvm_buffer) {
-    llvm::OpaqueType* opq = llvm::OpaqueType::get();
-    TheModule->addTypeName("hlvm_buffer_obj", opq);
-    hlvm_buffer = llvm::PointerType::get(opq);
-    TheModule->addTypeName("hlvm_buffer", hlvm_buffer);
-  }
-  return hlvm_buffer;
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_buffer_create()
-{
-  if (! hlvm_buffer_create) {
-    llvm::Type* result = get_hlvm_buffer();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_size());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_buffer_create",FT);
-    hlvm_buffer_create = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-      "hlvm_buffer_create", TheModule);
-  }
-  return hlvm_buffer_create;
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  new CallInst(emimp->get_llvm_memset(), args, "", TheBlock);
 }
 
-CallInst*
-LLVMEmitter::call_hlvm_buffer_create(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_buffer_create();
-  return new llvm::CallInst(F, args, (nm ? nm : "buffer"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_buffer_delete()
+CallInst* 
+LLVMEmitter::emitOpen(llvm::Value* strm)
 {
-  if (! hlvm_buffer_delete) {
-    llvm::Type* result = get_hlvm_buffer();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_buffer());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_buffer_delete",FT);
-    hlvm_buffer_delete = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-      "hlvm_buffer_delete", TheModule);
-  }
-  return hlvm_buffer_delete;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_buffer_delete(const ArgList& args)
-{
-  Function* F = get_hlvm_buffer_delete();
-  return new llvm::CallInst(F, args, "", TheBlock);
-}
-
-llvm::PointerType* 
-LLVMEmitter::get_hlvm_stream()
-{
-  if (! hlvm_stream) {
-    llvm::OpaqueType* opq = llvm::OpaqueType::get();
-    TheModule->addTypeName("hlvm_stream_obj", opq);
-    hlvm_stream= llvm::PointerType::get(opq);
-    TheModule->addTypeName("hlvm_stream", hlvm_stream);
-  }
-  return hlvm_stream;
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_open()
-{
-  if (!hlvm_stream_open) {
-    llvm::Type* result = get_hlvm_stream();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(llvm::PointerType::get(llvm::Type::SByteTy));
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_open_signature",FT);
-    hlvm_stream_open = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, 
-        "hlvm_stream_open", TheModule);
-  }
-  return hlvm_stream_open;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_stream_open(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_stream_open();
-  return new llvm::CallInst(F, args, (nm ? nm : "stream"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_read()
-{
-  if (!hlvm_stream_read) {
-    llvm::Type* result = get_hlvm_size();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_stream());
-    arg_types.push_back(get_hlvm_buffer());
-    arg_types.push_back(get_hlvm_size());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_read_signature",FT);
-    hlvm_stream_read = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage,
-      "hlvm_stream_read", TheModule);
-  }
-  return hlvm_stream_read;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_stream_read(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_stream_read();
-  return new llvm::CallInst(F, args, (nm ? nm : "readlen"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_write_buffer()
-{
-  if (!hlvm_stream_write_buffer) {
-    llvm::Type* result = get_hlvm_size();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_stream());
-    arg_types.push_back(get_hlvm_buffer());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_write_buffer_signature",FT);
-    hlvm_stream_write_buffer = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage,
-      "hlvm_stream_write_buffer", TheModule);
-  }
-  return hlvm_stream_write_buffer;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_stream_write_buffer(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_stream_write_buffer();
-  return new llvm::CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_write_string()
-{
-  if (!hlvm_stream_write_string) {
-    llvm::Type* result = get_hlvm_size();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_stream());
-    arg_types.push_back(llvm::PointerType::get(llvm::Type::SByteTy));
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_write_string_signature",FT);
-    hlvm_stream_write_string = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage,
-      "hlvm_stream_write_string", TheModule);
-  }
-  return hlvm_stream_write_string;
-}
-
-CallInst*
-LLVMEmitter::call_hlvm_stream_write_string(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_stream_write_string();
-  return new llvm::CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
-}
-
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_write_text()
-{
-  if (!hlvm_stream_write_text) {
-    llvm::Type* result = get_hlvm_size();
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_stream());
-    arg_types.push_back(get_hlvm_text());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_write_text_signature",FT);
-    hlvm_stream_write_text = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage,
-      "hlvm_stream_write_text", TheModule);
-  }
-  return hlvm_stream_write_text;
-}
+  std::vector<llvm::Value*> args;
+  if (const llvm::PointerType* PT = 
+      llvm::dyn_cast<llvm::PointerType>(strm->getType())) 
+  {
+    const llvm::Type* Ty = PT->getElementType();
+    if (Ty == llvm::Type::SByteTy) {
+      args.push_back(strm);
+    } else if (llvm::isa<ArrayType>(Ty) && 
+             cast<ArrayType>(Ty)->getElementType() == Type::SByteTy) {
+      ArgList indices;
+      this->TwoZeroIndices(indices);
+      args.push_back(this->emitGEP(strm,indices));
+    } else
+      hlvmAssert(!"Array element type is not SByteTy");
+  } else
+    hlvmAssert(!"OpenOp parameter is not a pointer");
 
-CallInst*
-LLVMEmitter::call_hlvm_stream_write_text(const ArgList& args, const char* nm)
-{
-  Function* F = get_hlvm_stream_write_text();
-  return new llvm::CallInst(F, args, (nm ? nm : "writelen"), TheBlock);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  return emimp->call_hlvm_stream_open(args,"open");
 }
 
-llvm::Function*
-LLVMEmitter::get_hlvm_stream_close()
+CallInst* 
+LLVMEmitter::emitClose(llvm::Value* strm)
 {
-  if (!hlvm_stream_close) {
-    llvm::Type* result = llvm::Type::VoidTy;
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(get_hlvm_stream());
-    llvm::FunctionType* FT = llvm::FunctionType::get(result,arg_types,false);
-    TheModule->addTypeName("hlvm_stream_close_signature",FT);
-    hlvm_stream_close = 
-      new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage,
-      "hlvm_stream_close", TheModule);
-  }
-  return hlvm_stream_close;
+  std::vector<llvm::Value*> args;
+  args.push_back(strm);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  return emimp->call_hlvm_stream_close(args);
+}
+
+CallInst* 
+LLVMEmitter::emitRead(llvm::Value* strm,llvm::Value* arg2, llvm::Value* arg3)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(strm);
+  args.push_back(arg2);
+  args.push_back(arg3);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  return emimp->call_hlvm_stream_read(args,"read");
+}
+
+CallInst* 
+LLVMEmitter::emitWrite(llvm::Value* strm,llvm::Value* arg2)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(strm);
+  args.push_back(arg2);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  CallInst* result = 0;
+  if (llvm::isa<llvm::PointerType>(arg2->getType()))
+    if (llvm::cast<llvm::PointerType>(arg2->getType())->getElementType() ==
+        llvm::Type::SByteTy)
+      result = emimp->call_hlvm_stream_write_string(args,"write");
+  if (arg2->getType() == emimp->get_hlvm_text())
+    result = emimp->call_hlvm_stream_write_text(args,"write");
+  else if (arg2->getType() == emimp->get_hlvm_buffer())
+    result = emimp->call_hlvm_stream_write_buffer(args,"write");
+  return result;
 }
 
 CallInst*
-LLVMEmitter::call_hlvm_stream_close(const ArgList& args)
-{
-  Function* F = get_hlvm_stream_close();
-  return new llvm::CallInst(F, args, "", TheBlock);
-}
-
-llvm::FunctionType*
-LLVMEmitter::get_hlvm_program_signature()
-{
-  if (!hlvm_program_signature) {
-    // Get the type of function that all entry points must have
-    std::vector<const llvm::Type*> arg_types;
-    arg_types.push_back(llvm::Type::IntTy);
-    arg_types.push_back(
-      llvm::PointerType::get(llvm::PointerType::get(llvm::Type::SByteTy)));
-    hlvm_program_signature = 
-      llvm::FunctionType::get(llvm::Type::IntTy,arg_types,false);
-    TheModule->addTypeName("hlvm_program_signature",hlvm_program_signature);
-  }
-  return hlvm_program_signature;
-}
-
-llvm::Function* 
-LLVMEmitter::get_llvm_memcpy()
-{
-  if (!llvm_memcpy) {
-    const Type *SBP = PointerType::get(Type::SByteTy);
-    llvm_memcpy = TheModule->getOrInsertFunction(
-      "llvm.memcpy.i64", Type::VoidTy, SBP, SBP, Type::ULongTy, Type::UIntTy, 
-      NULL);
-  }
-  return llvm_memcpy;
-}
-
-llvm::Function* 
-LLVMEmitter::get_llvm_memmove()
+LLVMEmitter::emitIsPInf(Value* V)
 {
-  if (!llvm_memmove) {
-    const Type *SBP = PointerType::get(Type::SByteTy);
-    llvm_memmove = TheModule->getOrInsertFunction(
-      "llvm.memmove.i64", Type::VoidTy, SBP, SBP, Type::ULongTy, Type::UIntTy, 
-      NULL);
-  }
-
-  return llvm_memmove;
-}
-
-llvm::Function* 
-LLVMEmitter::get_llvm_memset()
-{
-  if (!llvm_memset) {
-    const Type *SBP = PointerType::get(Type::SByteTy);
-    llvm_memset = TheModule->getOrInsertFunction(
-      "llvm.memset.i64", Type::VoidTy, SBP, Type::UByteTy, Type::ULongTy, 
-      Type::UIntTy, NULL);
-  }
-  return llvm_memset;
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_ispinf(args);
+  return emimp->call_hlvm_f64_ispinf(args);
+}
+
+CallInst* 
+LLVMEmitter::emitIsNInf(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_isninf(args);
+  return emimp->call_hlvm_f64_isninf(args);
+}
+
+CallInst* 
+LLVMEmitter::emitIsNan(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_isnan(args);
+  return emimp->call_hlvm_f64_isnan(args);
+}
+
+CallInst* 
+LLVMEmitter::emitTrunc(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_trunc(args);
+  return emimp->call_hlvm_f64_trunc(args);
+}
+
+CallInst* 
+LLVMEmitter::emitRound(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_round(args);
+  return emimp->call_hlvm_f64_round(args);
+}
+
+CallInst* 
+LLVMEmitter::emitFloor(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_floor(args);
+  return emimp->call_hlvm_f64_floor(args);
+}
+
+CallInst* 
+LLVMEmitter::emitCeiling(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_ceiling(args);
+  return emimp->call_hlvm_f64_ceiling(args);
+}
+
+CallInst* 
+LLVMEmitter::emitLogE(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_loge(args);
+  return emimp->call_hlvm_f64_loge(args);
+}
+
+CallInst* 
+LLVMEmitter::emitLog2(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_log2(args);
+  return emimp->call_hlvm_f64_log2(args);
+}
+
+CallInst* 
+LLVMEmitter::emitLog10(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_log10(args);
+  return emimp->call_hlvm_f64_log10(args);
+}
+
+CallInst* 
+LLVMEmitter::emitSquareRoot(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_squareroot(args);
+  return emimp->call_hlvm_f64_squareroot(args);
+}
+
+CallInst* 
+LLVMEmitter::emitCubeRoot(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_cuberoot(args);
+  return emimp->call_hlvm_f64_cuberoot(args);
+}
+
+CallInst* 
+LLVMEmitter::emitFactorial(Value* V)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V->getType()->isFloatingPoint());
+  if (Type::FloatTy == V->getType())
+    return emimp->call_hlvm_f32_factorial(args);
+  return emimp->call_hlvm_f64_factorial(args);
+}
+
+CallInst* 
+LLVMEmitter::emitPower(Value* V1,Value*V2)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V1);
+  args.push_back(V2);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V1->getType()->isFloatingPoint());
+  hlvmAssert(V2->getType()->isFloatingPoint());
+  if (Type::FloatTy == V1->getType())
+    return emimp->call_hlvm_f32_power(args);
+  return emimp->call_hlvm_f64_power(args);
+}
+
+CallInst* 
+LLVMEmitter::emitRoot(Value* V1,Value*V2)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V1);
+  args.push_back(V2);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V1->getType()->isFloatingPoint());
+  hlvmAssert(V2->getType()->isFloatingPoint());
+  if (Type::FloatTy == V1->getType())
+    return emimp->call_hlvm_f32_root(args);
+  return emimp->call_hlvm_f64_root(args);
+}
+
+CallInst* 
+LLVMEmitter::emitGCD(Value* V1,Value*V2)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V1);
+  args.push_back(V2);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V1->getType()->isFloatingPoint());
+  hlvmAssert(V2->getType()->isFloatingPoint());
+  if (Type::FloatTy == V1->getType())
+    return emimp->call_hlvm_f32_gcd(args);
+  return emimp->call_hlvm_f64_gcd(args);
+}
+
+CallInst* 
+LLVMEmitter::emitLCM(Value* V1,Value*V2)
+{
+  std::vector<llvm::Value*> args;
+  args.push_back(V1);
+  args.push_back(V2);
+  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
+  hlvmAssert(V1->getType()->isFloatingPoint());
+  hlvmAssert(V2->getType()->isFloatingPoint());
+  if (Type::FloatTy == V1->getType())
+    return emimp->call_hlvm_f32_lcm(args);
+  return emimp->call_hlvm_f64_lcm(args);
 }
 
 }

Modified: hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h Sat Jul  7 19:03:08 2007
@@ -71,7 +71,7 @@
 {
   /// @name Constructors
   /// @{
-  public:
+  protected:
     LLVMEmitter();
 
   /// @}
@@ -233,6 +233,11 @@
       bool varargs                   ///< Whether its a varargs function or not
     );
 
+    llvm::Type* getTextType();
+    llvm::Type* getStreamType();
+    llvm::Type* getBufferType();
+    llvm::FunctionType* getProgramType();
+
   /// @}
   /// @name Simple Value getters
   /// @{
@@ -308,7 +313,7 @@
       return new llvm::CastInst(V1,Ty,name,TheBlock);
     }
     llvm::LoadInst* emitLoad(llvm::Value* V, const std::string& name) const {
-      return  new llvm::LoadInst(V,name,TheBlock);
+      return new llvm::LoadInst(V,name,TheBlock);
     }
     llvm::StoreInst* emitStore(llvm::Value* from, llvm::Value* to) const {
       return new llvm::StoreInst(from,to,TheBlock);
@@ -454,6 +459,37 @@
     );
 
   /// @}
+  /// @name Emitters for Stream Operations
+  /// @{
+  public:
+    llvm::CallInst* emitOpen(llvm::Value* strm);
+    llvm::CallInst* emitClose(llvm::Value* strm);
+    llvm::CallInst* emitRead(llvm::Value* strm,llvm::Value* V2,llvm::Value* V3);
+    llvm::CallInst* emitWrite(llvm::Value* strm,llvm::Value*V2);
+
+  /// @}
+  /// @name Emitters for Math functions
+  /// @{
+  public:
+    llvm::CallInst* emitIsPInf(llvm::Value* V);
+    llvm::CallInst* emitIsNInf(llvm::Value* V);
+    llvm::CallInst* emitIsNan(llvm::Value* V);
+    llvm::CallInst* emitTrunc(llvm::Value* V);
+    llvm::CallInst* emitRound(llvm::Value* V);
+    llvm::CallInst* emitFloor(llvm::Value* V);
+    llvm::CallInst* emitCeiling(llvm::Value* V);
+    llvm::CallInst* emitLogE(llvm::Value* V);
+    llvm::CallInst* emitLog2(llvm::Value* V);
+    llvm::CallInst* emitLog10(llvm::Value* V);
+    llvm::CallInst* emitSquareRoot(llvm::Value* V);
+    llvm::CallInst* emitCubeRoot(llvm::Value* V);
+    llvm::CallInst* emitFactorial(llvm::Value* V);
+    llvm::CallInst* emitPower(llvm::Value* V1,llvm::Value*V2);
+    llvm::CallInst* emitRoot(llvm::Value* V1,llvm::Value*V2);
+    llvm::CallInst* emitGCD(llvm::Value* V1,llvm::Value*V2);
+    llvm::CallInst* emitLCM(llvm::Value* V1,llvm::Value*V2);
+
+  /// @}
   /// @name Other miscellaneous functions
   /// @{
   public:
@@ -480,66 +516,9 @@
     void AddBranchFixup(llvm::BranchInst *BI, bool isExceptionEdge);
 
   /// @}
-  /// @name Accessors for interface to HLVM Runtime Library
-  /// @{
-  public:
-    /// Buffer manipulation methods
-    llvm::PointerType*  get_hlvm_buffer();
-    llvm::Function*     get_hlvm_buffer_create();
-    llvm::CallInst*     call_hlvm_buffer_create(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_buffer_delete();
-    llvm::CallInst*     call_hlvm_buffer_delete(const ArgList& args);
-
-    /// Get the signature for an HLVM program
-    llvm::FunctionType* get_hlvm_program_signature();
-
-    /// Get the LLVM type for an HLVM "size" type
-    llvm::Type*         get_hlvm_size();
-
-    /// Stream manipulation methods
-    llvm::PointerType*  get_hlvm_stream();
-    llvm::Function*     get_hlvm_stream_open();
-    llvm::CallInst*     call_hlvm_stream_open(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_stream_read();
-    llvm::CallInst*     call_hlvm_stream_read(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_stream_write_buffer();
-    llvm::CallInst*     call_hlvm_stream_write_buffer(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_stream_write_text();
-    llvm::CallInst*     call_hlvm_stream_write_text(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_stream_write_string();
-    llvm::CallInst*     call_hlvm_stream_write_string(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_stream_close();
-    llvm::CallInst*     call_hlvm_stream_close(const ArgList& args);
-
-    /// Text manipulation methods.
-    llvm::PointerType*  get_hlvm_text();
-    llvm::Function*     get_hlvm_text_create();
-    llvm::CallInst*     call_hlvm_text_create(
-        const ArgList& args, const char* name = 0);
-    llvm::Function*     get_hlvm_text_delete();
-    llvm::CallInst*     call_hlvm_text_delete(const ArgList& args);
-    llvm::Function*     get_hlvm_text_to_buffer();
-    llvm::CallInst*     call_hlvm_text_to_buffer(
-        const ArgList& args, const char* name = 0);
-
-  /// @}
-  /// @name Accessors for LLVM intrinsics
-  /// @{
-  public:
-    llvm::Function* get_llvm_memcpy();
-    llvm::Function* get_llvm_memmove();
-    llvm::Function* get_llvm_memset();
-
-  /// @}
   /// @name Data Members
   /// @{
-  private:
+  protected:
     BlockStack blocks;              ///< The stack of nested blocks 
     BranchList breaks;              ///< The list of breaks to fix up later
     BranchList continues;           ///< The list of continues to fix up later
@@ -549,32 +528,11 @@
     llvm::BasicBlock* TheExitBlock; ///< The function's exit (return) block
     llvm::Instruction* EntryInsertionPoint; ///< Insertion point for entry stuff
     llvm::BasicBlock* TheBlock;     ///< The current block we're building
-
-    // Caches of things to interface with the HLVM Runtime Library
-    llvm::PointerType*  hlvm_text;          ///< Opaque type for text objects
-    llvm::Function*     hlvm_text_create;   ///< Create a new text object
-    llvm::Function*     hlvm_text_delete;   ///< Delete a text object
-    llvm::Function*     hlvm_text_to_buffer;///< Convert text to a buffer
-    llvm::PointerType*  hlvm_buffer;        ///< Pointer To octet
-    llvm::Function*     hlvm_buffer_create; ///< Create a new buffer object
-    llvm::Function*     hlvm_buffer_delete; ///< Delete a buffer
-    llvm::PointerType*  hlvm_stream;        ///< Pointer to stream type
-    llvm::Function*     hlvm_stream_open;   ///< Function for stream_open
-    llvm::Function*     hlvm_stream_read;   ///< Function for stream_read
-    llvm::Function*     hlvm_stream_write_buffer; ///< Write buffer to stream
-    llvm::Function*     hlvm_stream_write_text;   ///< Write text to stream
-    llvm::Function*     hlvm_stream_write_string; ///< Write string to stream
-    llvm::Function*     hlvm_stream_close;  ///< Function for stream_close
-    llvm::FunctionType* hlvm_program_signature; ///< The llvm type for programs
-
-    // Caches of LLVM Intrinsic functions
-    llvm::Function*     llvm_memcpy;         ///< llvm.memcpy.i64
-    llvm::Function*     llvm_memmove;        ///< llvm.memmove.i64
-    llvm::Function*     llvm_memset;         ///< llvm.memset.i64
-
   /// @}
 };
 
+extern LLVMEmitter* new_LLVMEmitter();
+
 } // end hlvm namespace
 
 #endif

Modified: hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:03:08 2007
@@ -71,7 +71,7 @@
 
 class LLVMGeneratorPass : public hlvm::Pass
 {
-  LLVMEmitter em;
+  LLVMEmitter* em;
   typedef std::map<const hlvm::Operator*,llvm::Value*> OperandMap;
   typedef std::map<const hlvm::Block*,llvm::BasicBlock*> BlockMap;
   typedef std::map<const hlvm::Operator*,llvm::BasicBlock*> LoopMap;
@@ -105,7 +105,9 @@
       continues(),
       gvars(), lvars(), ltypes(), consts(), funcs(),
       ast(tree), bundle(0), function(0), block(0)
-      { }
+      { 
+        em = new_LLVMEmitter();
+      }
     ~LLVMGeneratorPass() { }
 
   /// Conversion functions
@@ -236,13 +238,13 @@
       break;
     }
     case TextTypeID:
-      result = em.get_hlvm_text();
+      result = em->getTextType();
       break;
     case StreamTypeID: 
-      result = em.get_hlvm_stream();
+      result = em->getStreamType();
       break;
     case BufferTypeID: 
-      result = em.get_hlvm_buffer();
+      result = em->getBufferType();
       break;
     case PointerTypeID: 
     {
@@ -254,7 +256,7 @@
       // If the element type is opaque then we need to add a type name for this
       // pointer type because all opaques are unique unless named similarly.
       if (llvm::isa<llvm::OpaqueType>(lElemType))
-        em.AddType(result, ty->getName());
+        em->AddType(result, ty->getName());
       break;
     }
     case VectorTypeID: {
@@ -292,7 +294,7 @@
       // Get the Result Type
       const llvm::Type* resultTy = getType(st->getResultType());
       result = 
-        em.getFunctionType(st->getName(), resultTy, params, st->isVarArgs());
+        em->getFunctionType(st->getName(), resultTy, params, st->isVarArgs());
       break;
     }
     case OpaqueTypeID: {
@@ -354,7 +356,7 @@
       } else {
         val = cVal[0];
       }
-      result = em.getUVal(llvm::Type::UIntTy,val);
+      result = em->getUVal(llvm::Type::UIntTy,val);
       break;
     }
     case ConstantEnumeratorID:
@@ -364,7 +366,7 @@
       uint64_t val = 0;
       bool gotEnumValue = eType->getEnumValue( CE->getValue(), val );
       hlvmAssert(gotEnumValue && "Enumerator not valid for type");
-      result = em.getUVal(lType,val);
+      result = em->getUVal(lType,val);
       break;
     }
     case ConstantIntegerID:
@@ -373,15 +375,15 @@
       if (const IntegerType* iType = llvm::dyn_cast<IntegerType>(hType)) {
         if (iType->isSigned()) {
           int64_t val = strtoll(CI->getValue().c_str(),0,CI->getBase());
-          result = em.getSVal(lType,val);
+          result = em->getSVal(lType,val);
         }
         else {
           uint64_t val = strtoull(CI->getValue().c_str(),0,CI->getBase());
-          result = em.getUVal(lType,val);
+          result = em->getUVal(lType,val);
         }
       } else if (const RangeType* rType = llvm::dyn_cast<RangeType>(hType)) {
         int64_t val = strtoll(CI->getValue().c_str(),0,CI->getBase());
-        result = em.getSVal(lType,val);
+        result = em->getSVal(lType,val);
       }
       break;
     }
@@ -396,7 +398,7 @@
     {
       const ConstantString* CT = llvm::cast<ConstantString>(C);
       llvm::Constant* CA = llvm::ConstantArray::get(CT->getValue(), true);
-      llvm::GlobalVariable* GV  = em.NewGConst(CA->getType(), CA, C->getName());
+      llvm::GlobalVariable* GV  = em->NewGConst(CA->getType(), CA, C->getName());
       std::vector<llvm::Constant*> indices;
       indices.push_back(llvm::Constant::getNullValue(llvm::Type::UIntTy));
       indices.push_back(llvm::Constant::getNullValue(llvm::Type::UIntTy));
@@ -409,7 +411,7 @@
       const Constant* hC = hCT->getValue();
       const llvm::Type* Ty = getType(hC->getType());
       llvm::Constant* Init = getConstant(hC);
-      result = em.NewGConst(Ty,Init, hCT->getName());
+      result = em->NewGConst(Ty,Init, hCT->getName());
       break;
     }
     case ConstantArrayID:
@@ -422,12 +424,12 @@
            I != E; ++I )
         elems.push_back(getConstant(*I));
       llvm::Constant* lCA = llvm::ConstantArray::get(lAT,elems);
-      llvm::GlobalVariable* lGV = em.NewGConst(lAT,lCA,hCA->getName()+"_init");
-      llvm::Constant* lCE = em.getFirstElement(lGV);
+      llvm::GlobalVariable* lGV = em->NewGConst(lAT,lCA,hCA->getName()+"_init");
+      llvm::Constant* lCE = em->getFirstElement(lGV);
       const llvm::StructType* Ty = 
         llvm::cast<llvm::StructType>(getType(hCA->getType()));
       elems.clear();
-      elems.push_back(em.getUVal(llvm::Type::UIntTy,hCA->size()));
+      elems.push_back(em->getUVal(llvm::Type::UIntTy,hCA->size()));
       elems.push_back(lCE);
       result = llvm::ConstantStruct::get(Ty,elems);
       break;
@@ -498,7 +500,7 @@
   else
     Initializer = llvm::Constant::getNullValue(getType(V->getType()));
 
-  llvm::Value* gv = em.NewGVar(
+  llvm::Value* gv = em->NewGVar(
     /*Ty=*/ getType(V->getType()),
     /*Linkage=*/ getLinkageTypes(V->getLinkageKind()), 
     /*Initializer=*/ Initializer,
@@ -519,7 +521,7 @@
   if (I != funcs.end())
     return I->second;
 
-  return funcs[F] = em.NewFunction(
+  return funcs[F] = em->NewFunction(
     /*Type=*/ llvm::cast<llvm::FunctionType>(getType(F->getType())),
     /*Linkage=*/ getLinkageTypes(F->getLinkageKind()), 
     /*Name=*/ getLinkageName(F)
@@ -602,13 +604,13 @@
 
   if (Ty->isInteger() || Ty->isFloatingPoint()) {
     llvm::Constant* C = llvm::Constant::getNullValue(V->getType());
-    return em.emitNE(V,C);
+    return em->emitNE(V,C);
   } else if (llvm::isa<llvm::GlobalValue>(V)) {
     // GlobalValues always have non-zero constant address values, so always true
-    return em.getTrue(); 
+    return em->getTrue(); 
   }
   hlvmAssert(!"Don't know how to convert V into bool");
-  return em.getTrue();
+  return em->getTrue();
 }
 
 llvm::Value* 
@@ -617,7 +619,7 @@
   if (!llvm::isa<llvm::PointerType>(V->getType()))
     return V;
 
-  return em.emitLoad(V,"ptr2Value");
+  return em->emitLoad(V,"ptr2Value");
 }
 
 void 
@@ -664,7 +666,7 @@
     result = operand;
   } else {
     hlvmAssert(operand && "No operand for operator?");
-    entry_block = exit_block = new llvm::BasicBlock(name,em.getFunction()); 
+    entry_block = exit_block = new llvm::BasicBlock(name,em->getFunction()); 
     llvm::Value* V = operand;
     hlvmAssert(V && "No value for operand?");
     if (llvm::Instruction* ins = llvm::dyn_cast<llvm::Instruction>(V)) {
@@ -703,8 +705,8 @@
   llvm::AllocaInst* result = 0;
   if (!llvm::isa<Block>(op->getParent())) {
     const llvm::Type* Ty = getType(op->getType());
-    result = em.NewAutoVar(Ty, name + "_var");
-    em.emitAssign(result,em.getNullValue(Ty));
+    result = em->NewAutoVar(Ty, name + "_var");
+    em->emitAssign(result,em->getNullValue(Ty));
   }
   return result;
 }
@@ -712,11 +714,11 @@
 llvm::Value* 
 LLVMGeneratorPass::getBlockResult(Block* B)
 {
-  if (B->getResult() && !em.getBlockTerminator()) {
+  if (B->getResult() && !em->getBlockTerminator()) {
     llvm::Value* result = operands[B];
     if (llvm::isa<llvm::LoadInst>(result))
       result = llvm::cast<llvm::LoadInst>(result)->getOperand(0);
-    result = em.emitLoad(result,em.getBlockName()+"_result");
+    result = em->emitLoad(result,em->getBlockName()+"_result");
     pushOperand(result,B);
     return result;
   }
@@ -734,7 +736,7 @@
 void
 LLVMGeneratorPass::startNewFunction(llvm::Function* F)
 {
-  em.StartFunction(F);
+  em->StartFunction(F);
   // Clear the function related variables
   operands.clear();
   enters.clear();
@@ -751,13 +753,13 @@
   // variables zero cost as well as safeguarding against stack growth if the
   // alloca is in a block that is in a loop.
   const llvm::Type* elemType = getType(av->getType());
-  llvm::Value* alloca = em.NewAutoVar(elemType,av->getName()); 
+  llvm::Value* alloca = em->NewAutoVar(elemType,av->getName()); 
   llvm::Value* init = 0;
   if (av->hasInitializer())
     init = popOperand(av->getInitializer());
   else
-    init = em.getNullValue(elemType);
-  em.emitAssign(alloca,init);
+    init = em->getNullValue(elemType);
+  em->emitAssign(alloca,init);
   pushOperand(alloca,av);
   lvars[av] = alloca;
 }
@@ -770,7 +772,7 @@
   hlvmAssert((operand->getType()->isInteger() || 
             operand->getType()->isFloatingPoint()) && 
             "Can't negate non-numeric");
-  pushOperand(em.emitNeg(operand),op);
+  pushOperand(em->emitNeg(operand),op);
 }
 
 template<> void
@@ -780,7 +782,7 @@
   operand = ptr2Value(operand);
   const llvm::Type* lType = operand->getType();
   hlvmAssert(lType->isInteger() && "Can't complement non-integral type");
-  pushOperand(em.emitCmpl(operand),op);
+  pushOperand(em->emitCmpl(operand),op);
 }
 
 template<> void
@@ -791,15 +793,15 @@
   hlvmAssert(llvm::isa<llvm::PointerType>(lType));
   const llvm::PointerType* PT = llvm::cast<llvm::PointerType>(lType);
   lType = PT->getElementType();
-  llvm::LoadInst* load = em.emitLoad(operand,"preincr");
+  llvm::LoadInst* load = em->emitLoad(operand,"preincr");
   if (lType->isFloatingPoint()) {
-    llvm::Constant* one = em.getFPOne(lType);
-    llvm::BinaryOperator* add = em.emitAdd(load,one); 
-    pushOperand(em.emitStore(add,operand),op);
+    llvm::Constant* one = em->getFPOne(lType);
+    llvm::BinaryOperator* add = em->emitAdd(load,one); 
+    pushOperand(em->emitStore(add,operand),op);
   } else if (lType->isInteger()) {
-    llvm::Constant* one = em.getIOne(lType);
-    llvm::BinaryOperator* add = em.emitAdd(load,one); 
-    pushOperand(em.emitStore(add,operand),op);
+    llvm::Constant* one = em->getIOne(lType);
+    llvm::BinaryOperator* add = em->emitAdd(load,one); 
+    pushOperand(em->emitStore(add,operand),op);
   } else {
     hlvmAssert(!"PreIncrOp on non-numeric");
   }
@@ -813,15 +815,15 @@
   hlvmAssert(llvm::isa<llvm::PointerType>(lType));
   const llvm::PointerType* PT = llvm::cast<llvm::PointerType>(lType);
   lType = PT->getElementType();
-  llvm::LoadInst* load = em.emitLoad(operand,"predecr");
+  llvm::LoadInst* load = em->emitLoad(operand,"predecr");
   if (lType->isFloatingPoint()) {
-    llvm::Constant* one = em.getFPOne(lType);
-    llvm::BinaryOperator* sub = em.emitSub(load,one);
-    pushOperand(em.emitStore(sub,operand),op);
+    llvm::Constant* one = em->getFPOne(lType);
+    llvm::BinaryOperator* sub = em->emitSub(load,one);
+    pushOperand(em->emitStore(sub,operand),op);
   } else if (lType->isInteger()) {
-    llvm::Constant* one = em.getIOne(lType);
-    llvm::BinaryOperator* sub = em.emitSub(load, one);
-    pushOperand(em.emitStore(sub,operand),op);
+    llvm::Constant* one = em->getIOne(lType);
+    llvm::BinaryOperator* sub = em->emitSub(load, one);
+    pushOperand(em->emitStore(sub,operand),op);
   } else {
     hlvmAssert(!"PreIncrOp on non-numeric");
   }
@@ -835,16 +837,16 @@
   hlvmAssert(llvm::isa<llvm::PointerType>(lType));
   const llvm::PointerType* PT = llvm::cast<llvm::PointerType>(lType);
   lType = PT->getElementType();
-  llvm::LoadInst* load = em.emitLoad(operand,"postincr");
+  llvm::LoadInst* load = em->emitLoad(operand,"postincr");
   if (lType->isFloatingPoint()) {
-    llvm::Constant* one = em.getFPOne(lType);
-    llvm::BinaryOperator* add = em.emitAdd(load,one); 
-    em.emitStore(add,operand);
+    llvm::Constant* one = em->getFPOne(lType);
+    llvm::BinaryOperator* add = em->emitAdd(load,one); 
+    em->emitStore(add,operand);
     pushOperand(load,op);
   } else if (lType->isInteger()) {
-    llvm::Constant* one = em.getIOne(lType);
-    llvm::BinaryOperator* add = em.emitAdd(load,one); 
-    em.emitStore(add,operand);
+    llvm::Constant* one = em->getIOne(lType);
+    llvm::BinaryOperator* add = em->emitAdd(load,one); 
+    em->emitStore(add,operand);
     pushOperand(load,op);
   } else {
     hlvmAssert(!"PostDecrOp on non-numeric");
@@ -859,16 +861,16 @@
   hlvmAssert(llvm::isa<llvm::PointerType>(lType));
   const llvm::PointerType* PT = llvm::cast<llvm::PointerType>(lType);
   lType = PT->getElementType();
-  llvm::LoadInst* load = em.emitLoad(operand,"postdecr");
+  llvm::LoadInst* load = em->emitLoad(operand,"postdecr");
   if (lType->isFloatingPoint()) {
-    llvm::Constant* one = em.getFPOne(lType);
-    llvm::BinaryOperator* sub = em.emitSub(load, one);
-    em.emitStore(sub,operand);
+    llvm::Constant* one = em->getFPOne(lType);
+    llvm::BinaryOperator* sub = em->emitSub(load, one);
+    em->emitStore(sub,operand);
     pushOperand(load,op);
   } else if (lType->isInteger()) {
-    llvm::Constant* one = em.getIOne(lType);
-    llvm::BinaryOperator* sub = em.emitSub(load, one);
-    em.emitStore(sub,operand);
+    llvm::Constant* one = em->getIOne(lType);
+    llvm::BinaryOperator* sub = em->emitSub(load, one);
+    em->emitStore(sub,operand);
     pushOperand(load,op);
   } else {
     hlvmAssert(!"PostDecrOp on non-numeric");
@@ -879,7 +881,7 @@
 LLVMGeneratorPass::gen(SizeOfOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0));
-  pushOperand(em.emitSizeOf(op1),op);
+  pushOperand(em->emitSizeOf(op1),op);
 }
 
 template<> void
@@ -902,7 +904,7 @@
   // First, deal with the easy case of conversion of first class types. This
   // can just be done with the LLVM cast operator
   if (lsrcTy->isFirstClassType() && ltgtTy->isFirstClassType()) {
-    pushOperand(em.emitCast(v1,ltgtTy,v1->getName() + "_converted"),op);
+    pushOperand(em->emitCast(v1,ltgtTy,v1->getName() + "_converted"),op);
     return;
   }
 
@@ -923,7 +925,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitAdd(op1,op2),op);
+  pushOperand(em->emitAdd(op1,op2),op);
 }
 
 template<> void
@@ -933,7 +935,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitSub(op1,op2),op);
+  pushOperand(em->emitSub(op1,op2),op);
 }
 
 template<> void
@@ -943,7 +945,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitMul(op1,op2),op);
+  pushOperand(em->emitMul(op1,op2),op);
 }
 
 template<> void
@@ -953,7 +955,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitDiv(op1,op2),op);
+  pushOperand(em->emitDiv(op1,op2),op);
 }
 
 template<> void
@@ -963,7 +965,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitMod(op1,op2),op);
+  pushOperand(em->emitMod(op1,op2),op);
 }
 
 template<> void
@@ -973,7 +975,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitBAnd(op1,op2),op);
+  pushOperand(em->emitBAnd(op1,op2),op);
 }
 
 template<> void
@@ -983,7 +985,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitBOr(op1,op2),op);
+  pushOperand(em->emitBOr(op1,op2),op);
 }
 
 template<> void
@@ -993,7 +995,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitBXor(op1,op2),op);
+  pushOperand(em->emitBXor(op1,op2),op);
 }
 
 template<> void
@@ -1003,7 +1005,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitBNor(op1,op2),op);
+  pushOperand(em->emitBNor(op1,op2),op);
 }
 
 template<> void
@@ -1012,7 +1014,7 @@
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
-  pushOperand(em.emitNot(op1),op);
+  pushOperand(em->emitNot(op1),op);
 }
 
 template<> void
@@ -1022,7 +1024,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitAnd(op1,op2),op);
+  pushOperand(em->emitAnd(op1,op2),op);
 }
 
 template<> void
@@ -1032,7 +1034,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitOr(op1,op2),op);
+  pushOperand(em->emitOr(op1,op2),op);
 }
 
 template<> void
@@ -1042,7 +1044,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitNor(op1,op2),op);
+  pushOperand(em->emitNor(op1,op2),op);
 }
 
 template<> void
@@ -1052,7 +1054,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitXor(op1,op2),op);
+  pushOperand(em->emitXor(op1,op2),op);
 }
 
 template<> void
@@ -1062,7 +1064,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitEQ(op1,op2),op);
+  pushOperand(em->emitEQ(op1,op2),op);
 }
 
 template<> void
@@ -1072,7 +1074,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitNE(op1,op2),op);
+  pushOperand(em->emitNE(op1,op2),op);
 }
 
 template<> void
@@ -1082,7 +1084,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitLT(op1,op2),op);
+  pushOperand(em->emitLT(op1,op2),op);
 }
 
 template<> void
@@ -1092,7 +1094,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitLT(op1,op2),op);
+  pushOperand(em->emitLT(op1,op2),op);
 }
 
 template<> void
@@ -1102,7 +1104,7 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitGE(op1,op2),op);
+  pushOperand(em->emitGE(op1,op2),op);
 }
 
 template<> void
@@ -1112,86 +1114,98 @@
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
   op1 = ptr2Value(op1);
   op2 = ptr2Value(op2);
-  pushOperand(em.emitLE(op1,op2),op);
+  pushOperand(em->emitLE(op1,op2),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(IsPInfOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
-  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+  pushOperand(em->emitIsPInf(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(IsNInfOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitIsNInf(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(IsNanOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitIsNan(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(TruncOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitTrunc(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(RoundOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitRound(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(FloorOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitFloor(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(CeilingOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitCeiling(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(LogEOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitLogE(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(Log2Op* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitLog2(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(Log10Op* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitLog10(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(SquareRootOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitSquareRoot(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(CubeRootOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitCubeRoot(op1),op);
 }
 
 template<> void
 LLVMGeneratorPass::gen(FactorialOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  pushOperand(em->emitFactorial(op1),op);
 }
 
 template<> void
@@ -1199,6 +1213,7 @@
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
+  pushOperand(em->emitPower(op1,op2),op);
 }
 
 template<> void
@@ -1206,6 +1221,7 @@
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
+  pushOperand(em->emitRoot(op1,op2),op);
 }
 
 template<> void
@@ -1213,6 +1229,7 @@
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
+  pushOperand(em->emitGCD(op1,op2),op);
 }
 
 template<> void
@@ -1220,6 +1237,7 @@
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
   llvm::Value* op2 = popOperand(op->getOperand(1)); 
+  pushOperand(em->emitLCM(op1,op2),op);
 }
 
 template<> void
@@ -1239,7 +1257,7 @@
     hlvmAssert(op1->getType() == llvm::Type::BoolTy);
     hlvmAssert(op2->getType()->isFirstClassType());
     hlvmAssert(op3->getType()->isFirstClassType());
-    pushOperand(em.emitSelect(op1,op2,op3,"select"),op);
+    pushOperand(em->emitSelect(op1,op2,op3,"select"),op);
     return;
   }
 
@@ -1255,7 +1273,7 @@
   popOperandAsCondition(op->getOperand(0),"select",cond_entry,cond_exit);
 
   // Branch the current block into the condition block
-  em.emitBranch(cond_entry); 
+  em->emitBranch(cond_entry); 
 
   // Get the true case
   llvm::BasicBlock *true_entry, *true_exit;
@@ -1274,7 +1292,7 @@
     new llvm::StoreInst(op3,select_result,false_exit);
 
   // Create the exit block
-  llvm::BasicBlock* select_exit = em.newBlock("select_exit");
+  llvm::BasicBlock* select_exit = em->newBlock("select_exit");
 
   // Branch the the true and false cases to the exit
   branchIfNotTerminated(select_exit,true_exit);
@@ -1306,7 +1324,7 @@
     popOperandAsCondition(op->getOperand(0),"while",cond_entry,cond_exit);
 
   // Branch the current block into the condition block
-  em.emitBranch(cond_entry);
+  em->emitBranch(cond_entry);
 
   // Get the while loop's body
   llvm::BasicBlock *body_entry, *body_exit;
@@ -1318,7 +1336,7 @@
     new llvm::StoreInst(op2,while_result,body_exit);
 
   // Create the exit block
-  llvm::BasicBlock* while_exit = em.newBlock("while_exit");
+  llvm::BasicBlock* while_exit = em->newBlock("while_exit");
 
   // Branch the the body block back to the condition branch
   branchIfNotTerminated(cond_entry,body_exit);
@@ -1331,8 +1349,8 @@
     pushOperand(new llvm::LoadInst(while_result,"while_result",while_exit),op);
 
   // Fix up any break or continue operators
-  em.ResolveBreaks(while_exit);
-  em.ResolveContinues(cond_entry);
+  em->ResolveBreaks(while_exit);
+  em->ResolveContinues(cond_entry);
 }
 
 template<> void
@@ -1347,7 +1365,7 @@
     popOperandAsCondition(op->getOperand(0),"unless",cond_entry,cond_exit);
 
   // Branch the current block into the condition block
-  em.emitBranch(cond_entry);
+  em->emitBranch(cond_entry);
 
   // Get the unless block's body
   llvm::BasicBlock *body_entry, *body_exit;
@@ -1359,7 +1377,7 @@
     new llvm::StoreInst(op2,unless_result,body_exit);
 
   // Create the exit block
-  llvm::BasicBlock* unless_exit = em.newBlock("unless_exit");
+  llvm::BasicBlock* unless_exit = em->newBlock("unless_exit");
 
   // Branch the the body block back to the condition branch
   branchIfNotTerminated(cond_entry,body_exit);
@@ -1373,8 +1391,8 @@
       new llvm::LoadInst(unless_result,"unless_result",unless_exit),op);
 
   // Fix up any break or continue operators
-  em.ResolveBreaks(unless_exit);
-  em.ResolveContinues(cond_entry);
+  em->ResolveBreaks(unless_exit);
+  em->ResolveContinues(cond_entry);
 }
 
 template<> void
@@ -1398,13 +1416,13 @@
     new llvm::StoreInst(op1,until_result,body_exit);
 
   // Branch the current block into the body block
-  em.emitBranch(body_entry);
+  em->emitBranch(body_entry);
 
   // Branch the body block to the condition block
   branchIfNotTerminated(cond_entry,body_exit);
 
   // Create the exit block
-  llvm::BasicBlock* until_exit = em.newBlock("until_exit");
+  llvm::BasicBlock* until_exit = em->newBlock("until_exit");
 
   // Finally, install the conditional branch into condition block
   new llvm::BranchInst(until_exit,body_entry,op2,cond_exit);
@@ -1414,8 +1432,8 @@
     pushOperand(new llvm::LoadInst(until_result,"until_result",until_exit),op);
 
   // Fix up any break or continue operators
-  em.ResolveBreaks(until_exit);
-  em.ResolveContinues(cond_entry);
+  em->ResolveBreaks(until_exit);
+  em->ResolveContinues(cond_entry);
 }
 
 template<> void
@@ -1431,7 +1449,7 @@
       start_cond_entry,start_cond_exit);
 
   // Branch the current block into the start condition block
-  em.emitBranch(start_cond_entry);
+  em->emitBranch(start_cond_entry);
 
   // Get the loop body
   llvm::BasicBlock *body_entry, *body_exit;
@@ -1452,7 +1470,7 @@
   branchIfNotTerminated(end_cond_entry,body_exit);
 
   // Create the exit block
-  llvm::BasicBlock* loop_exit = em.newBlock("loop_exit");
+  llvm::BasicBlock* loop_exit = em->newBlock("loop_exit");
 
   // Install the conditional branches for start and end condition blocks
   new llvm::BranchInst(body_entry,loop_exit,op1,start_cond_exit);
@@ -1463,8 +1481,8 @@
     pushOperand(new llvm::LoadInst(loop_result,"loop_result",loop_exit),op);
 
   // Fix up any break or continue operators
-  em.ResolveBreaks(loop_exit);
-  em.ResolveContinues(end_cond_entry);
+  em->ResolveBreaks(loop_exit);
+  em->ResolveContinues(end_cond_entry);
 }
 
 template<> void
@@ -1476,7 +1494,7 @@
 
   // Just push a place-holder branch onto the breaks list so it can
   // be fixed up later once we know the destination
-  llvm::BranchInst* brnch = em.emitBreak();
+  llvm::BranchInst* brnch = em->emitBreak();
   pushOperand(brnch,op);
 }
 
@@ -1489,7 +1507,7 @@
 
   // Just push a place-holder branch onto the continues list so it can
   // be fixed up later once we know the destination
-  llvm::BranchInst* brnch = em.emitContinue();
+  llvm::BranchInst* brnch = em->emitContinue();
   pushOperand(brnch,op);
 }
 
@@ -1499,7 +1517,7 @@
   // Get the result operand
   llvm::Value* src = popOperand(r->getOperand(0));
   if (llvm::isa<llvm::AllocaInst>(src))
-    src = em.emitLoad(src,src->getName() + "_load");
+    src = em->emitLoad(src,src->getName() + "_load");
 
   // Get the block this result applies to
   hlvm::Block* B = llvm::cast<hlvm::Block>(r->getParent());
@@ -1507,7 +1525,7 @@
   llvm::Value* dest = operands[B];
 
   // Assign the source to the destination
-  em.emitAssign(dest, src);
+  em->emitAssign(dest, src);
 }
 
 template<> void
@@ -1517,13 +1535,13 @@
   // return instruction.
   const Type* resTy = function->getResultType();
   if (resTy == 0) {
-    em.emitReturn(0);
+    em->emitReturn(0);
     return;
   }
 
   // If we get here then the function has a result. 
   llvm::Value* result = operands[function->getBlock()];
-  em.emitReturn(result);
+  em->emitReturn(result);
 }
 
 template<> void
@@ -1557,7 +1575,7 @@
     llvm::cast<llvm::Function>(funcToCall));
 
   // Make the call
-  pushOperand(em.emitCall(F,args),co);
+  pushOperand(em->emitCall(F,args),co);
 }
 
 template<> void
@@ -1567,7 +1585,7 @@
   llvm::Value* value =    popOperand(s->getOperand(1));
   // We don't push the StoreInst as an operand because it has no value and
   // therefore cannot be an operand.
-  em.emitAssign(location,value);
+  em->emitAssign(location,value);
 }
 
 template<> void
@@ -1582,7 +1600,7 @@
   if (!ET->isFirstClassType())
     pushOperand(location,l);
   else
-    pushOperand(em.emitLoad(location,location->getName()),l);
+    pushOperand(em->emitLoad(location,location->getName()),l);
 }
 
 template<> void
@@ -1608,7 +1626,7 @@
         hlvmAssert(index != 0 && "Invalid field name");
         llvm::Constant* idx = llvm::ConstantUInt::get(llvm::Type::UIntTy,index);
         llvm::Value* location = popOperand(loc);
-        pushOperand(em.emitGEP(location,idx),i);
+        pushOperand(em->emitGEP(location,idx),i);
         return;
       }
 
@@ -1623,30 +1641,14 @@
 {
   llvm::Value* location = popOperand(i->getOperand(0));
   llvm::Value* index = popOperand(i->getOperand(1));
-  pushOperand(em.emitGEP(location,index),i);
+  pushOperand(em->emitGEP(location,index),i);
 }
 
 template<> void
 LLVMGeneratorPass::gen(OpenOp* o)
 {
   llvm::Value* strm = popOperand(o->getOperand(0));
-  std::vector<llvm::Value*> args;
-  if (const llvm::PointerType* PT = 
-      llvm::dyn_cast<llvm::PointerType>(strm->getType())) {
-  const llvm::Type* Ty = PT->getElementType();
-  if (Ty == llvm::Type::SByteTy) {
-    args.push_back(strm);
-  } else if (llvm::isa<llvm::ArrayType>(Ty) && 
-             llvm::cast<llvm::ArrayType>(Ty)->getElementType() == 
-             llvm::Type::SByteTy) {
-    ArgList indices;
-    em.TwoZeroIndices(indices);
-    args.push_back(em.emitGEP(strm,indices));
-  } else
-    hlvmAssert(!"Array element type is not SByteTy");
-  } else
-    hlvmAssert(!"OpenOp parameter is not a pointer");
-  pushOperand(em.call_hlvm_stream_open(args,"open"),o);
+  pushOperand(em->emitOpen(strm),o);
 }
 
 template<> void
@@ -1654,17 +1656,7 @@
 {
   llvm::Value* strm = popOperand(o->getOperand(0));
   llvm::Value* arg2 = popOperand(o->getOperand(1));
-  std::vector<llvm::Value*> args;
-  args.push_back(strm);
-  args.push_back(arg2);
-  if (llvm::isa<llvm::PointerType>(arg2->getType()))
-  if (llvm::cast<llvm::PointerType>(arg2->getType())->getElementType() ==
-      llvm::Type::SByteTy)
-    pushOperand(em.call_hlvm_stream_write_string(args,"write"),o);
-  if (arg2->getType() == em.get_hlvm_text())
-    pushOperand(em.call_hlvm_stream_write_text(args,"write"),o);
-  else if (arg2->getType() == em.get_hlvm_buffer())
-    pushOperand(em.call_hlvm_stream_write_buffer(args,"write"),o);
+  pushOperand(em->emitWrite(strm,arg2),o); 
 }
 
 template<> void
@@ -1673,20 +1665,14 @@
   llvm::Value* strm = popOperand(o->getOperand(0));
   llvm::Value* arg2 = popOperand(o->getOperand(1));
   llvm::Value* arg3 = popOperand(o->getOperand(2));
-  std::vector<llvm::Value*> args;
-  args.push_back(strm);
-  args.push_back(arg2);
-  args.push_back(arg3);
-  pushOperand(em.call_hlvm_stream_read(args,"read"),o);
+  pushOperand(em->emitRead(strm,arg2,arg3),o);
 }
 
 template<> void
 LLVMGeneratorPass::gen(CloseOp* o)
 {
   llvm::Value* strm = popOperand(o->getOperand(0));
-  std::vector<llvm::Value*> args;
-  args.push_back(strm);
-  pushOperand(em.call_hlvm_stream_close(args),o);
+  pushOperand(em->emitClose(strm),o);
 }
 
 void 
@@ -1700,7 +1686,7 @@
   // a string and a pointer to the function).
   std::vector<const llvm::Type*> Fields;
   Fields.push_back(llvm::PointerType::get(llvm::Type::SByteTy));
-  Fields.push_back(llvm::PointerType::get(em.get_hlvm_program_signature()));
+  Fields.push_back(llvm::PointerType::get(em->getProgramType()));
   llvm::StructType* entry_elem_type = llvm::StructType::get(Fields);
 
   // Define the type of the array for the entry points
@@ -1718,7 +1704,7 @@
     llvm::Constant* name_val = llvm::ConstantArray::get(funcName,true);
 
     // Create a constant global variable to hold the name of the program.
-    llvm::GlobalVariable* name = em.NewGConst(
+    llvm::GlobalVariable* name = em->NewGConst(
       /*Type=*/name_val->getType(),
       /*Initializer=*/name_val, 
       /*name=*/"prog_name"
@@ -1748,7 +1734,7 @@
     /*Linkage=*/llvm::GlobalValue::AppendingLinkage,
     /*Initializer=*/entry_points_initializer,
     /*Name=*/"hlvm_programs",
-    /*Parent=*/em.getModule()
+    /*Parent=*/em->getModule()
   );
 }
 
@@ -1768,7 +1754,7 @@
     {
       case BundleID:
       {
-        em.StartModule(llvm::cast<Bundle>(n)->getName());
+        em->StartModule(llvm::cast<Bundle>(n)->getName());
         lvars.clear();
         gvars.clear();
         funcs.clear();
@@ -1824,8 +1810,8 @@
       {
         // Create a new function for the program based on the signature
         function = llvm::cast<hlvm::Program>(n);
-        llvm::Function* F = em.NewFunction(
-            /*Type=*/ em.get_hlvm_program_signature(),
+        llvm::Function* F = em->NewFunction(
+            /*Type=*/ em->getProgramType(),
             /*Linkage=*/llvm::GlobalValue::InternalLinkage,
             /*Name=*/ getLinkageName(function)
         );
@@ -1839,12 +1825,12 @@
       {
         Block* B = llvm::cast<Block>(n);
         std::string name = B->getLabel().empty() ? "block" : B->getLabel();
-        enters[B] = em.pushBlock(name);
+        enters[B] = em->pushBlock(name);
         if (B->getResult()) {
           const llvm::Type* Ty = getType(B->getType());
-          llvm::AllocaInst* result = em.NewAutoVar(Ty, name+"_var");
+          llvm::AllocaInst* result = em->NewAutoVar(Ty, name+"_var");
           // Initialize the autovar to null
-          em.emitAssign(result,em.getNullValue(Ty));
+          em->emitAssign(result,em->getNullValue(Ty));
           pushOperand(result,B); 
         }
         break;
@@ -1876,7 +1862,7 @@
       case VectorTypeID:
       {
         Type* t = llvm::cast<Type>(n);
-        em.AddType(getType(t), t->getName());
+        em->AddType(getType(t), t->getName());
         break;
       }
       case NegateOpID:              gen(llvm::cast<NegateOp>(n)); break;
@@ -1948,7 +1934,7 @@
 
       case BundleID:
         genProgramLinkage();
-        modules.push_back(em.FinishModule());
+        modules.push_back(em->FinishModule());
         break;
       case ConstantBooleanID:       
       case ConstantCharacterID:
@@ -1968,7 +1954,7 @@
       case ProgramID:
         /* FALL THROUGH */
       case FunctionID:
-        em.FinishFunction();
+        em->FinishFunction();
         // The entry block was created to hold the automatic variables. We now
         // need to terminate the block by branching it to the first active block
         // in the function.
@@ -1977,9 +1963,9 @@
       case BlockID:
       {
         Block* B = llvm::cast<Block>(n);
-        exits[B] = em.getBlock();
+        exits[B] = em->getBlock();
         getBlockResult(B);
-        em.popBlock();
+        em->popBlock();
         break;
       }
 

Modified: hlvm/trunk/hlvm/Pass/Validate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Pass/Validate.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Pass/Validate.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Validate.cpp Sat Jul  7 19:03:08 2007
@@ -1038,7 +1038,7 @@
 template<> inline void
 ValidateImpl::validate(GetFieldOp* n)
 {
-  if (checkOperator(n,GetFieldOpID,2)) {
+  if (checkOperator(n,GetFieldOpID,1)) {
     // FIXME: Implement check for reference on first operand
     // FIXME: Implement check for string type on second operand
   }

Modified: hlvm/trunk/hlvm/Reader/HLVM.rng
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/HLVM.rng?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/HLVM.rng (original)
+++ hlvm/trunk/hlvm/Reader/HLVM.rng Sat Jul  7 19:03:08 2007
@@ -733,6 +733,7 @@
       <ref name="BinaryRealMathOperators.pat"/>
       <ref name="MemoryOps.pat"/>
       <ref name="InputOutputOps.pat"/>
+      <ref name="StringOperators.pat"/>
       <ref name="ControlFlowOps.pat"/>
     </choice>
   </define>
@@ -847,9 +848,11 @@
 
   <define name="getfld.elem">
     <element name="getfld">
+      <attribute name="field">
+        <ref name="Identifier.type"/>
+      </attribute>
       <ref name="Documentation.pat"/>
       <ref name="Location.pat"/>
-      <ref name="Operators.pat"/>
     </element>
   </define>
 
@@ -1060,7 +1063,7 @@
       <ref name="round.elem"/>
       <ref name="floor.elem"/>
       <ref name="ceiling.elem"/>
-      <ref name="logE.elem"/>
+      <ref name="loge.elem"/>
       <ref name="log2.elem"/>
       <ref name="log10.elem"/>
       <ref name="squareroot.elem"/>
@@ -1111,8 +1114,8 @@
     </element>
   </define>
 
-  <define name="logE.elem">
-    <element name="logE">
+  <define name="loge.elem">
+    <element name="loge">
       <ref name="UnaryOperator.pat"/>
     </element>
   </define>

Modified: hlvm/trunk/hlvm/Reader/XMLReader.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/XMLReader.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/XMLReader.cpp (original)
+++ hlvm/trunk/hlvm/Reader/XMLReader.cpp Sat Jul  7 19:03:08 2007
@@ -1354,7 +1354,7 @@
       case TKN_round:        op = parseUnaryOp<RoundOp>(cur); break;
       case TKN_floor:        op = parseUnaryOp<FloorOp>(cur); break;
       case TKN_ceiling:      op = parseUnaryOp<CeilingOp>(cur); break;
-      case TKN_logE:         op = parseUnaryOp<LogEOp>(cur); break;
+      case TKN_loge:         op = parseUnaryOp<LogEOp>(cur); break;
       case TKN_log2:         op = parseUnaryOp<Log2Op>(cur); break;
       case TKN_log10:        op = parseUnaryOp<Log10Op>(cur); break;
       case TKN_squareroot:   op = parseUnaryOp<SquareRootOp>(cur); break;

Modified: hlvm/trunk/hlvm/Writer/XMLWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Writer/XMLWriter.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Writer/XMLWriter.cpp (original)
+++ hlvm/trunk/hlvm/Writer/XMLWriter.cpp Sat Jul  7 19:03:08 2007
@@ -1111,6 +1111,7 @@
 XMLWriterImpl::WriterPass::put(const GetFieldOp* r)
 {
   startElement("getfld");
+  writeAttribute("field",r->getFieldName());
   putDoc(r);
 }
 

Modified: hlvm/trunk/test/generate/dg.exp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/generate/dg.exp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/test/generate/dg.exp (original)
+++ hlvm/trunk/test/generate/dg.exp Sat Jul  7 19:03:08 2007
@@ -8,9 +8,9 @@
       return [expr {int(rand()*$range)}]
 }
 
-for { set complexity 1 } { $complexity < 10 } { incr complexity } {
-  for { set typecmplxt 1 } { $typecmplxt < 6 } { incr typecmplxt } {
-    for { set size 1 } { $size < 10 } { incr size } {
+for { set complexity 1 } { $complexity < 6 } { incr complexity } {
+  for { set typecmplxt 1 } { $typecmplxt < 5 } { incr typecmplxt } {
+    for { set size 1 } { $size < 6 } { incr size } {
       hlvm-generate-test $complexity $typecmplxt $size [random [clock second] ]
     }
   }

Modified: hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp?rev=38411&r1=38410&r2=38411&view=diff

==============================================================================
--- hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp (original)
+++ hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp Sat Jul  7 19:03:08 2007
@@ -745,7 +745,7 @@
 static Operator*
 genStringUnary(Operator* V1)
 {
-  hlvmAssert(isa<StringType>(V1));
+  hlvmAssert(isa<StringType>(V1->getType()));
   Operator* str = genValueAsOperator(bundle->getIntrinsicType(stringTy));
   return ast->new_BinaryOp<StrConcatOp>(V1,str,bundle,getLocator());
 }
@@ -753,8 +753,8 @@
 static Operator*
 genStringBinary(Operator* V1, Operator* V2)
 {
-  hlvmAssert(isa<StringType>(V1));
-  hlvmAssert(isa<StringType>(V2));
+  hlvmAssert(isa<StringType>(V1->getType()));
+  hlvmAssert(isa<StringType>(V2->getType()));
   ConstantInteger* CI = getConstantInteger(0);
   GetOp* get = ast->new_GetOp(CI,getLocator());
   return ast->new_BinaryOp<StrConcatOp>(V1,V2,bundle,getLocator());
@@ -763,7 +763,7 @@
 static Operator*
 genArrayUnary(Operator* V1)
 {
-  hlvmAssert(isa<ArrayType>(V1));
+  hlvmAssert(isa<ArrayType>(V1->getType()));
   const ArrayType* Ty = cast<ArrayType>(V1->getType());
   Block* blk = ast->new_Block(getLocator());
   AutoVarOp* val1 = ast->new_AutoVarOp("val1",Ty,getLocator());
@@ -806,7 +806,7 @@
   SelectOp* sel = 
     ast->new_TernaryOp<SelectOp>(le,len3,len4,bundle,getLocator());
   GetIndexOp* endIndex = 
-    ast->new_GetIndexOp(val1,endIndex,getLocator());
+    ast->new_GetIndexOp(val1,sel,getLocator());
   endIndex->setParent(end);
 
   LessThanOp* cond = 
@@ -836,8 +836,8 @@
 static Operator*
 genArrayBinary(Operator* V1, Operator* V2)
 {
-  hlvmAssert(isa<ArrayType>(V1));
-  hlvmAssert(isa<ArrayType>(V2));
+  hlvmAssert(isa<ArrayType>(V1->getType()));
+  hlvmAssert(isa<ArrayType>(V2->getType()));
   hlvmAssert(V1->getType() == V2->getType());
   const ArrayType* Ty = cast<ArrayType>(V1->getType());
   Block* blk = ast->new_Block(getLocator());
@@ -852,14 +852,16 @@
   GetOp* getNull1 = ast->new_GetOp(null,getLocator());
   AutoVarOp* ptr1 = ast->new_AutoVarOp("ptr1",ptr_type,getLocator());
   blk->addOperand(ptr1);
+  GetOp* val1get = ast->new_GetOp(val1,getLocator());
   GetIndexOp* idx1 = 
-    ast->new_GetIndexOp(val1,getNull1,getLocator());
+    ast->new_GetIndexOp(val1get,getNull1,getLocator());
   idx1->setParent(ptr1);
   GetOp* getNull2 = ast->new_GetOp(null,getLocator());
   AutoVarOp* ptr2 = ast->new_AutoVarOp("ptr2",ptr_type,getLocator());
   blk->addOperand(ptr2);
+  GetOp* val2get = ast->new_GetOp(val2,getLocator());
   GetIndexOp* idx2 = 
-    ast->new_GetIndexOp(val2,getNull2,getLocator());
+    ast->new_GetIndexOp(val2get,getNull2,getLocator());
   idx2->setParent(ptr2);
   GetOp* getNull3 = ast->new_GetOp(null,getLocator());
   AutoVarOp* ptr3 = ast->new_AutoVarOp("ptr3",ptr_type,getLocator());
@@ -881,7 +883,7 @@
   SelectOp* sel = 
     ast->new_TernaryOp<SelectOp>(le,len3,len4,bundle,getLocator());
   GetIndexOp* endIndex = 
-    ast->new_GetIndexOp(val1,endIndex,getLocator());
+    ast->new_GetIndexOp(ast->new_GetOp(val1,getLocator()),sel,getLocator());
   endIndex->setParent(end);
 
   LessThanOp* cond = 
@@ -911,7 +913,7 @@
 static Operator*
 genVectorUnary(Operator* V1)
 {
-  hlvmAssert(isa<VectorType>(V1));
+  hlvmAssert(isa<VectorType>(V1->getType()));
   const VectorType* Ty = cast<VectorType>(V1->getType());
   Block* blk = ast->new_Block(getLocator());
   AutoVarOp* autovar = ast->new_AutoVarOp("result",Ty,getLocator());
@@ -922,7 +924,7 @@
     ConstantInteger* cst = getConstantInteger(i);
     GetOp* index = ast->new_GetOp(cst,getLocator());
     GetIndexOp* elem = 
-      ast->new_GetIndexOp(val1,index,getLocator());
+      ast->new_GetIndexOp(ast->new_GetOp(val1,getLocator()),index,getLocator());
     LoadOp* load1 = ast->new_UnaryOp<LoadOp>(elem,bundle,getLocator());
     Operator* expr = genUnaryExpression(load1);
     GetOp* get = ast->new_GetOp(autovar,getLocator());
@@ -941,8 +943,8 @@
 static Operator*
 genVectorBinary(Operator* V1, Operator* V2)
 {
-  hlvmAssert(isa<StructureType>(V1));
-  hlvmAssert(isa<StructureType>(V2));
+  hlvmAssert(isa<VectorType>(V1->getType()));
+  hlvmAssert(isa<VectorType>(V2->getType()));
   hlvmAssert(V1->getType() == V2->getType());
   const VectorType* Ty = llvm::cast<VectorType>(V1->getType());
   Block* blk = ast->new_Block(getLocator());
@@ -957,7 +959,7 @@
     ConstantInteger* cst = getConstantInteger(i);
     GetOp* index = ast->new_GetOp(cst,getLocator());
     GetIndexOp* elem1 = 
-      ast->new_GetIndexOp(val1,index,getLocator());
+      ast->new_GetIndexOp(ast->new_GetOp(val1,getLocator()),index,getLocator());
     LoadOp* load1 = ast->new_UnaryOp<LoadOp>(elem1,bundle,getLocator());
     GetIndexOp* elem2 = 
       ast->new_GetIndexOp(val2,index,getLocator());





More information about the llvm-commits mailing list