//===-- LLVM Code Emitter Implementation ------------------------*- C++ -*-===//
//
//                      High Level Virtual Machine (HLVM)
//
// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
//
// This software is free software; you can redistribute it and/or modify it 
// under the terms of the GNU Lesser General Public License as published by 
// the Free Software Foundation; either version 2.1 of the License, or (at 
// your option) any later version.
//
// This software is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
// more details.
//
// You should have received a copy of the GNU Lesser General Public License 
// along with this library in the file named LICENSE.txt; if not, write to the 
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
// MA 02110-1301 USA
//
//===----------------------------------------------------------------------===//
/// @file hlvm/CodeGen/LLVMEmitter.cpp
/// @author Reid Spencer <rspencer@x10sys.com>
/// @date 2006/07/08
/// @since 0.2.0
/// @brief Provides the implementation of the LLVM Code Emitter
//===----------------------------------------------------------------------===//

#include <hlvm/CodeGen/LLVMEmitter.h>
#include <hlvm/Base/Assert.h>

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:
    const Type* get_hlvm_size() { return Type::Int64Ty; }

    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::Int32Ty);
        // args.push_back(ArrayType::Get(Type::Int8Ty,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::Int8Ty));
        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.begin(), args.end(), (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.begin(), args.end(), "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.begin(), args.end(), (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.begin(), args.end(), (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.begin(), args.end(), "", 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::Int8Ty));
        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.begin(), args.end(), (nm ? nm : "stream"), 
                          TheBlock);
    }

    Function* get_hlvm_stream_read()
    {
      if (!hlvm_stream_read) {
        const 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.begin(), args.end(), (nm ? nm : "readlen"), 
                          TheBlock);
    }

    Function* get_hlvm_stream_write_buffer()
    {
      if (!hlvm_stream_write_buffer) {
        const 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.begin(), args.end(), (nm ? nm : "writelen"), 
                          TheBlock);
    }

    Function* get_hlvm_stream_write_string()
    {
      if (!hlvm_stream_write_string) {
        const 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::Int8Ty));
        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.begin(), args.end(), (nm ? nm : "writelen"), 
                          TheBlock);
    }

    Function* get_hlvm_stream_write_text()
    {
      if (!hlvm_stream_write_text) {
        const 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.begin(), args.end(), (nm ? nm : "writelen"), 
                          TheBlock);
    }

    Function* get_hlvm_stream_close()
    {
      if (!hlvm_stream_close) {
        const 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.begin(), args.end(), "", 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::Int32Ty);
        arg_types.push_back(
          PointerType::get(PointerType::get(Type::Int8Ty)));
        hlvm_program_signature = 
          FunctionType::get(Type::Int32Ty,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::Int8Ty);
        llvm_memcpy = cast<Function>(TheModule->getOrInsertFunction(
          "llvm.memcpy.i64", Type::VoidTy, SBP, SBP, Type::Int64Ty,
          Type::Int32Ty, NULL));
      }
      return llvm_memcpy;
    }

    Function* get_llvm_memmove()
    {
      if (!llvm_memmove) {
        const Type *SBP = PointerType::get(Type::Int8Ty);
        llvm_memmove = cast<Function>(TheModule->getOrInsertFunction(
          "llvm.memmove.i64", Type::VoidTy, SBP, SBP, Type::Int64Ty, 
          Type::Int32Ty, NULL));
      }
      return llvm_memmove;
    }

    Function* get_llvm_memset()
    {
      if (!llvm_memset) {
        const Type *SBP = PointerType::get(Type::Int8Ty);
        llvm_memset = cast<Function>(TheModule->getOrInsertFunction(
          "llvm.memset.i64", Type::VoidTy, SBP, Type::Int8Ty, Type::Int64Ty, 
          Type::Int32Ty, 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.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_isninf(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_isninf(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_isnan(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_isnan(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_trunc(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_trunc(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_round(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_round(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_floor(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_floor(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_ceiling(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_ceiling(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_loge(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_loge(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_log2(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_log2(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_log10(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_log10(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_squareroot(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_squareroot(), args.begin(), args.end(), 
                          "", TheBlock);
    }

    CallInst* call_hlvm_f32_cuberoot(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_cuberoot(), args.begin(), args.end(), 
                          "", TheBlock);
    }

    CallInst* call_hlvm_f32_factorial(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_factorial(), args.begin(), args.end(), 
                          "", TheBlock);
    }

    CallInst* call_hlvm_f32_power(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_power(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_root(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_root(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_gcd(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_gcd(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f32_lcm(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f32_lcm(), args.begin(), args.end(), "", 
                          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.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_isninf(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_isninf(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_isnan(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_isnan(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_trunc(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_trunc(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_round(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_round(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_floor(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_floor(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_ceiling(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_ceiling(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_loge(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_loge(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_log2(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_log2(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_log10(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_log10(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_squareroot(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_squareroot(), args.begin(), args.end(), 
                          "", TheBlock);
    }

    CallInst* call_hlvm_f64_cuberoot(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_cuberoot(), args.begin(), args.end(), "",
                          TheBlock);
    }

    CallInst* call_hlvm_f64_factorial(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_factorial(), args.begin(), args.end(), 
                          "", TheBlock);
    }

    CallInst* call_hlvm_f64_power(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_power(), args.begin(), args.end(), "",
                          TheBlock);
    }

    CallInst* call_hlvm_f64_root(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_root(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_gcd(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_gcd(), args.begin(), args.end(), "", 
                          TheBlock);
    }

    CallInst* call_hlvm_f64_lcm(const hlvm::ArgList& args)
    {
      return new CallInst(get_hlvm_f64_lcm(), args.begin(), args.end(), "", 
                          TheBlock);
    }

  /// @}
};

}

namespace hlvm {

LLVMEmitter::LLVMEmitter()
  : TheModule(0), TheFunction(0), TheEntryBlock(0), TheExitBlock(0), 
    EntryInsertionPoint(0), TheBlock(0)
{
}

LLVMEmitter* 
new_LLVMEmitter()
{
  return new LLVMEmitterImpl();
}

Module*
LLVMEmitter::StartModule(const std::string& ID)
{
  hlvmAssert(TheModule == 0);
  return TheModule = new Module(ID);
}

Module*
LLVMEmitter::FinishModule()
{
  hlvmAssert(TheModule != 0);
  Module* result = TheModule;
  TheModule = 0;
  return result;
}

void
LLVMEmitter::StartFunction(Function* F)
{
  hlvmAssert(F != 0 && "Null function?");
  hlvmAssert(F->empty() && "Function already emitted!");

  // Ensure previous state is cleared
  // operands.clear();
  // enters.clear();
  // exits.clear();
  blocks.clear();
  breaks.clear();
  continues.clear();
  // lvars.clear();

  // Set up for new function
  TheFunction = F;

  // Instantiate an entry block for the alloca'd variables. This block
  // is only used for such variables. By placing the alloca'd variables in
  // the entry block, their allocation is free since the stack pointer 
  // must be adjusted anyway, all that happens is that it gets adjusted
  // by a larger amount. 
  TheBlock = TheEntryBlock = new BasicBlock("entry",F);

  // Instantiate a no-op as an insertion point for the entry point stuff such
  // as the alloca variables and argument setup. This allows us to fill and
  // terminate the entry block as usual while still retaining a point for 
  // insertion in the entry block that retains declaration order.
  EntryInsertionPoint = 
    new BitCastInst(Constant::getNullValue(Type::Int32Ty),Type::Int32Ty,
        "entry_point", TheEntryBlock);

  // Create a new block for the return node, but don't insert it yet.
  // TheExitBlock = new BasicBlock("exit");
}

void
LLVMEmitter::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.
  Function::iterator I = TheFunction->begin();
  ++I;
  new BranchInst(&*I, &TheFunction->front());
  hlvmAssert(blocks.empty());
  hlvmAssert(breaks.empty());
  hlvmAssert(continues.empty());
}

BasicBlock*
LLVMEmitter::pushBlock(const std::string& name)
{
  TheBlock = new BasicBlock(name,TheFunction);
  blocks.push_back(TheBlock);
  return TheBlock;
}

BasicBlock* 
LLVMEmitter::popBlock()
{
  BasicBlock* result = blocks.back();
  blocks.pop_back();
  if (blocks.empty())
    TheBlock = 0;
  else
    TheBlock = blocks.back();
  return result;
}

BasicBlock*
LLVMEmitter::newBlock(const std::string& name)
{
  blocks.pop_back();
  TheBlock = new BasicBlock(name,TheFunction);
  blocks.push_back(TheBlock);
  return TheBlock;
}

Value* 
LLVMEmitter::ConvertToBoolean(Value* V) const
{
  const Type* Ty = V->getType();
  if (Ty == Type::Int1Ty)
    return V;

  if (Ty->isInteger() || Ty->isFloatingPoint()) {
    Constant* CI = Constant::getNullValue(V->getType());
    return new ICmpInst(ICmpInst::ICMP_NE, V, CI, "i2b", TheBlock);
  } else if (isa<GlobalValue>(V)) {
    // GlobalValues always have non-zero constant address values, so always true
    return ConstantInt::getTrue();
  }
  hlvmAssert(!"Don't know how to convert V into bool");
  return ConstantInt::getTrue();
}

Value* 
LLVMEmitter::Pointer2Value(Value* V) const
{
  if (!isa<PointerType>(V->getType()))
    return V;

  // GetElementPtrInst* GEP = new GetElementPtrIns(V,
  //    ConstantInt::get(Type::Int32Ty,0),
  //    ConstantInt::get(Type::Int32Ty,0),
  //    "ptr2Value", TheBlock);
  return new LoadInst(V,"ptr2Value", TheBlock);
}

bool
LLVMEmitter::IsNoopCast(Value* V, const Type* Ty)
{
  // check signed to unsigned
  const Type *VTy = V->getType();
  if (VTy->canLosslesslyBitCastTo(Ty)) 
    return true;
  
  // Constant int to anything, to work around stuff like: "xor short X, int 1".
  if (isa<ConstantInt>(V)) 
    return true;
  
  return false;
}

/// CastToType - Cast the specified value to the specified type if it is
/// not already that type.
Value *
LLVMEmitter::CastToType(Value *V, bool srcIsSigned, const Type *Ty, 
                        bool destIsSigned, const std::string& newName) 
{
  // If they are the same type, no cast needed
  if (V->getType() == Ty) 
    return V;

  // Get the opcode necessary for the cast.
  Instruction::CastOps Opcode = 
    CastInst::getCastOpcode(V, srcIsSigned, Ty, destIsSigned);

  // If its a constant then we want a constant cast
  if (Constant *C = dyn_cast<Constant>(V))
    return ConstantExpr::getCast(Opcode, C, Ty);
  
  // If its a cast instruction and we're casting back to the original type, 
  // which is bool, then just get the operand of the cast instead of emitting 
  // duplicate cast instructions. This is just an optimization of a frequently
  // occurring case.
  if (CastInst *CI = dyn_cast<CastInst>(V))
    if (Ty == Type::Int1Ty && CI->getOperand(0)->getType() == Type::Int1Ty)
      return CI->getOperand(0);

  // Otherwise, just issue the cast
  return CastInst::create(Opcode, V, Ty, 
                          (newName.empty() ? V->getName() : newName), TheBlock);
}

void 
LLVMEmitter::ResolveBreaks(BasicBlock* exit)
{
  for (BranchList::iterator I = breaks.begin(), E = breaks.end(); I != E; ++I) {
    (*I)->setOperand(0,exit);
  }
  breaks.clear();
}

void 
LLVMEmitter::ResolveContinues(BasicBlock* entry)
{
  for (BranchList::iterator I = continues.begin(), E = continues.end(); 
       I != E; ++I) {
    (*I)->setOperand(0,entry);
  }
  continues.clear();
}

/// Return the number of elements in the specified type that will need to be 
/// loaded/stored if we copy this one element at a time.
unsigned 
LLVMEmitter::getNumElements(const Type *Ty) 
{
  if (Ty->isFirstClassType()) return 1;

  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
    unsigned NumElts = 0;
    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
      NumElts += getNumElements(STy->getElementType(i));
    return NumElts;
  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
    return ATy->getNumElements() * getNumElements(ATy->getElementType());
  } else if (const VectorType* VTy = dyn_cast<VectorType>(Ty)) {
    return VTy->getNumElements() * getNumElements(VTy->getElementType());
  } else
    hlvmAssert(!"Don't know how to count elements of this type");
  return 0;
}

Constant*
LLVMEmitter::getFirstElement(GlobalVariable* GV)
{
  ArgList indices;
  TwoZeroIndices(indices);
  return ConstantExpr::getGetElementPtr(GV, &indices[0], 2);
}

FunctionType*
LLVMEmitter::getFunctionType(
  const std::string& name, const Type* resultTy, 
  const TypeList& args, bool varargs)
{
  // The args might contain non-first-class typed arguments. We build a
  // new argument list the contains the argument types after conversion.
  TypeList Params;

  // We can't have results that are not first class so we use the
  // first argument to point to where the result should be stored and
  // switch the result type to VoidTy.
  if (!resultTy->isFirstClassType()) {
    Params.push_back(getFirstClassType(resultTy));
    resultTy = Type::VoidTy;
  }

  for (TypeList::const_iterator I = args.begin(), E = args.end(); I != E; ++I ) 
  {
    if ((*I)->isFirstClassType())
      Params.push_back(*I);
    else 
      Params.push_back(getFirstClassType(*I));
  }

  FunctionType* result = FunctionType::get(resultTy, Params, varargs);
  if (!name.empty())
    TheModule->addTypeName(name,result);
  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();
}

llvm::CmpInst* LLVMEmitter::emitNE(llvm::Value* V1, llvm::Value* V2){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_ONE, V1, V2, "ne",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE,  V1, V2, "ne",TheBlock);
}

llvm::CmpInst* LLVMEmitter::emitEQ(llvm::Value* V1, llvm::Value* V2){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_OEQ, V1, V2, "eq",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_EQ,  V1, V2, "eq",TheBlock);
}

llvm::CmpInst* LLVMEmitter::emitLT(llvm::Value* V1, llvm::Value* V2, bool sign){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_OLT, V1, V2,"olt",TheBlock);
  else if (sign)
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, V1, V2,"ult",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_SLT, V1, V2,"slt",TheBlock);
}

llvm::CmpInst* LLVMEmitter::emitGT(llvm::Value* V1, llvm::Value* V2, bool sign){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_OGT, V1, V2,"ogt",TheBlock);
  else if (sign)
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_SGT, V1, V2,"sgt",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, V1, V2,"ugt",TheBlock);
}

llvm::CmpInst* LLVMEmitter::emitLE(llvm::Value* V1, llvm::Value* V2, bool sign){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_OLE, V1, V2,"ole",TheBlock);
  else if (sign)
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULE, V1, V2,"ule",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_SLE, V1, V2,"sle",TheBlock);
}

llvm::CmpInst* LLVMEmitter::emitGE(llvm::Value* V1, llvm::Value* V2, bool sign){
  if (V1->getType()->isFloatingPoint())
    return new llvm::FCmpInst(llvm::FCmpInst::FCMP_OGE, V1, V2,"oge",TheBlock);
  else if (sign)
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_SGE, V1, V2,"sge",TheBlock);
  else
    return new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGE, V1, V2,"uge",TheBlock);
}

void
LLVMEmitter::emitAssign(Value* dest, Value* src)
{
  // If the destination is a load instruction then its the result of a previous
  // nested block so just get the first operand as the real destination.
  if (isa<LoadInst>(dest))
    dest = cast<LoadInst>(dest)->getOperand(0);

  // The destination must be a pointer type
  hlvmAssert(isa<PointerType>(dest->getType()));

  // Get the type of the destination and source
  const Type* destTy = cast<PointerType>(dest->getType())->getElementType();
  const Type* srcTy = src->getType();

  if (destTy->isFirstClassType()) {
    // Can't store an aggregate to a first class type
    hlvmAssert(srcTy->isFirstClassType());
    if (destTy == srcTy) {
      // simple case, the types match and they are both first class types, 
      // just emit a store instruction
      emitStore(src,dest);
    } else if (const PointerType* srcPT = dyn_cast<PointerType>(srcTy)) {
      // The source is a pointer to the value to return so just get a
      // pointer to its first element and store it since its pointing to
      // a first class type. Assert that this is true.
      hlvmAssert( srcPT->getElementType() == destTy );
      ArgList idx;
      TwoZeroIndices(idx);
      GetElementPtrInst* GEP = 
        new GetElementPtrInst(src, &idx[0], 2, "", TheBlock);
      emitStore(GEP,dest);
    } else {
      // they are both first class types and the source is not a pointer, so 
      // just cast them. FIXME: signedness
      Value* V = CastToType(src, false, destTy, false, src->getName());
      emitStore(V, dest);
    }
  } 
  else if (const PointerType* srcPT = dyn_cast<PointerType>(srcTy)) 
  {
    // We have an aggregate to copy
    emitAggregateCopy(dest,src);
  } 
  else if (Constant* srcC = dyn_cast<Constant>(src)) 
  {
    // We have a constant aggregate to move into an aggregate gvar. We must
    // create a temporary gvar based on the constant in order to copy it.
    GlobalVariable* GVar = NewGConst(srcTy, srcC, srcC->getName());
    // Now we can aggregate copy it
    emitAggregateCopy(dest, GVar);
  }
}

/// Recursively traverse the potientially aggregate src/dest ptrs, copying all 
/// of the elements from src to dest.
static void 
CopyAggregate(
  Value *DestPtr, 
  bool DestVolatile, 
  Value *SrcPtr, 
  bool SrcVolatile,
  BasicBlock *BB) 
{
  assert(DestPtr->getType() == SrcPtr->getType() &&
         "Cannot copy between two pointers of different type!");
  const Type *ElTy = cast<PointerType>(DestPtr->getType())->getElementType();
  if (ElTy->isFirstClassType()) {
    Value *V = new LoadInst(SrcPtr, "tmp", SrcVolatile, BB);
    new StoreInst(V, DestPtr, DestVolatile, BB);
  } else if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
    Constant *Zero = ConstantInt::get(Type::Int32Ty, 0);
    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
      Constant *Idx = ConstantInt::get(Type::Int32Ty, i);
      Value *DElPtr = new GetElementPtrInst(DestPtr, Zero, Idx, "tmp", BB);
      Value *SElPtr = new GetElementPtrInst(SrcPtr, Zero, Idx, "tmp", BB);
      CopyAggregate(DElPtr, DestVolatile, SElPtr, SrcVolatile, BB);
    }
  } else {
    const ArrayType *ATy = cast<ArrayType>(ElTy);
    Constant *Zero = ConstantInt::get(Type::Int32Ty, 0);
    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
      Constant *Idx = ConstantInt::get(Type::Int32Ty, i);
      Value *DElPtr = new GetElementPtrInst(DestPtr, Zero, Idx, "tmp", BB);
      Value *SElPtr = new GetElementPtrInst(SrcPtr, Zero, Idx, "tmp", BB);
      CopyAggregate(DElPtr, DestVolatile, SElPtr, SrcVolatile, BB);
    }
  }
}

/// EmitAggregateCopy - Copy the elements from SrcPtr to DestPtr, using the
/// GCC type specified by GCCType to know which elements to copy.
void 
LLVMEmitter::emitAggregateCopy(
  Value *DestPtr,
  Value *SrcPtr )
{
  // Make sure we're not mixing apples and oranges
  hlvmAssert(DestPtr->getType() == SrcPtr->getType());

  // Degenerate case, same pointer
  if (DestPtr == SrcPtr)
    return;  // noop copy.

  // If the type has just a few elements, then copy the elements directly 
  // using load/store. Otherwise use the llvm.memcpy.i64 intrinsic. This just
  // saves a function call for really small structures and arrays. 
  const Type* Ty = SrcPtr->getType();
  if (getNumElements(Ty) <= 8) 
    CopyAggregate(DestPtr, false, SrcPtr, false, TheBlock);
  else 
    emitMemCpy(DestPtr, SrcPtr, ConstantExpr::getSizeOf(Ty));
}

ReturnInst*
LLVMEmitter::emitReturn(Value* retVal)
{
  // First deal with the degenerate case, a void return
  if (retVal == 0) {
    hlvmAssert(getReturnType() == Type::VoidTy);
    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() != Type::VoidTy) {
    Value* result = 0;
    if (const PointerType* PTy = dyn_cast<PointerType>(resultTy)) {
      // must be an autovar or global var, just load the value
      hlvmAssert(PTy->getElementType() == getReturnType());
      result = emitLoad(retVal,getBlockName() + "_result");
    } else if (resultTy != getReturnType()) {
      hlvmAssert(resultTy->isFirstClassType());
      // FIXME: signedness
      result = CastToType(retVal, false, getReturnType(), false, 
                          getBlockName()+"_result");
    } else {
      hlvmAssert(resultTy->isFirstClassType());
      result = retVal;
    }
    hlvmAssert(result && "No result for function");
    return new ReturnInst(result,TheBlock);
  }

  // Now, deal with the aggregate result case. At this point the function return
  // type must be void and the first argument must be a pointer to the storage
  // area for the result.
  hlvmAssert(getReturnType() == Type::VoidTy);

  // Get the first argument.
  hlvmAssert(!TheFunction->arg_empty());
  Argument* result_arg = TheFunction->arg_begin();

  // Both the first argument and the result should have the same type which
  // both should be pointer to the aggregate
  hlvmAssert(result_arg->getType() == resultTy);

  // Copy the aggregate result
  emitAggregateCopy(result_arg, retVal);

  // Emit the void return
  return new ReturnInst(0, TheBlock);
}

CallInst* 
LLVMEmitter::emitCall(Function* F, const ArgList& args) 
{
  // Detect the aggregate result case
  if ((F->getReturnType() == Type::VoidTy) &&
      (args.size() == F->arg_size() - 1)) {
    const Type* arg1Ty = F->arg_begin()->getType();
    if (const PointerType* PTy = dyn_cast<PointerType>(arg1Ty))
    {
      // This is the case where the result is a temporary variable that
      // holds the aggregate and is passed as the first argument
      const Type* elemTy = PTy->getElementType();
      hlvmAssert(!elemTy->isFirstClassType());

      // Get a temporary for the result
      AllocaInst* result = NewAutoVar(elemTy, F->getName() + "_result");

      // Install the temporary result area into a new arg list
      ArgList newArgs;
      newArgs.push_back(result);

      // Copy the other arguments
      for (ArgList::const_iterator I = args.begin(), E = args.end(); 
           I != E; ++I)
        if (isa<Constant>(*I) && !isa<GlobalValue>(*I) && 
            !(*I)->getType()->isFirstClassType())
          newArgs.push_back(NewGConst((*I)->getType(), 
            cast<Constant>(*I), (*I)->getName()));
        else
          newArgs.push_back(*I);

      // Generate the call
      return new CallInst(F, newArgs.begin(), newArgs.end(), "", TheBlock);
    }
  }

  // The result must be a first class type at this point, ensure it
  hlvmAssert(F->getReturnType()->isFirstClassType());

  // Copy the other arguments
  ArgList newArgs;
  for (ArgList::const_iterator I = args.begin(), E = args.end(); 
       I != E; ++I)
    if (isa<Constant>(*I) && !isa<GlobalValue>(*I) && 
        !(*I)->getType()->isFirstClassType())
      newArgs.push_back(NewGConst((*I)->getType(), 
        cast<Constant>(*I), (*I)->getName()));
    else
      newArgs.push_back(*I);
  return new CallInst(F, newArgs.begin(), newArgs.end(), 
                      F->getName() + "_result", TheBlock);
}

void 
LLVMEmitter::emitMemCpy(
  Value *dest, 
  Value *src, 
  Value *size
)
{
  const Type *SBP = PointerType::get(Type::Int8Ty);
  ArgList args;
  args.push_back(CastToType(dest, false, SBP, false, ""));
  args.push_back(CastToType(src, false, SBP, false, ""));
  args.push_back(size);
  args.push_back(ConstantInt::get(Type::Int32Ty, 0u));
  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
  new CallInst(emimp->get_llvm_memcpy(), args.begin(), args.end(), "", 
               TheBlock);
}

/// Emit an llvm.memmove.i64 intrinsic
void 
LLVMEmitter::emitMemMove(
  Value *dest,
  Value *src, 
  Value *size
)
{
  const Type *SBP = PointerType::get(Type::Int8Ty);
  ArgList args;
  args.push_back(CastToType(dest, false, SBP, false, ""));
  args.push_back(CastToType(src, false, SBP, false, ""));
  args.push_back(size);
  args.push_back(ConstantInt::get(Type::Int32Ty, 0u));
  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
  new CallInst(emimp->get_llvm_memmove(), args.begin(), args.end(), "", 
               TheBlock);
}

/// Emit an llvm.memset.i64 intrinsic
void 
LLVMEmitter::emitMemSet(
  Value *dest, 
  Value *val, 
  Value *size 
)
{
  const Type *SBP = PointerType::get(Type::Int8Ty);
  ArgList args;
  args.push_back(CastToType(dest, false, SBP, false, ""));
  args.push_back(CastToType(val, false, Type::Int8Ty, false, ""));
  args.push_back(size);
  args.push_back(ConstantInt::get(Type::Int32Ty, 0u));
  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
  new CallInst(emimp->get_llvm_memset(), args.begin(), args.end(), "", 
               TheBlock);
}

CallInst* 
LLVMEmitter::emitOpen(llvm::Value* strm)
{
  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::Int8Ty) {
      args.push_back(strm);
    } else if (llvm::isa<ArrayType>(Ty) && 
             cast<ArrayType>(Ty)->getElementType() == Type::Int8Ty) {
      ArgList indices;
      this->TwoZeroIndices(indices);
      args.push_back(this->emitGEP(strm,indices));
    } else
      hlvmAssert(!"Array element type is not Int8Ty");
  } else
    hlvmAssert(!"OpenOp parameter is not a pointer");

  LLVMEmitterImpl* emimp = static_cast<LLVMEmitterImpl*>(this);
  return emimp->call_hlvm_stream_open(args,"open");
}

CallInst* 
LLVMEmitter::emitClose(llvm::Value* strm)
{
  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::Int8Ty)
      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::emitIsPInf(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_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);
}

}
