Rename the file name (looks more similar to LLVM).
diff --git a/lib/bcc/CodeEmitter.cpp b/lib/bcc/CodeEmitter.cpp
new file mode 100644
index 0000000..38fc281
--- /dev/null
+++ b/lib/bcc/CodeEmitter.cpp
@@ -0,0 +1,1574 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CodeEmitter.h"
+
+#include "CodeMemoryManager.h"
+#include "EmittedFuncEntry.h"
+#include "Runtime.h"
+
+#include <bcc/bcc.h>
+#include <bcc/bcc_cache.h>
+
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRelocation.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/JITCodeEmitter.h"
+
+#include "llvm/ExecutionEngine/GenericValue.h"
+
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+
+#if defined(USE_DISASSEMBLER)
+#include "llvm/Support/MemoryObject.h"
+#endif
+
+#include "llvm/System/Host.h"
+
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetJITInfo.h"
+
+#include "llvm/Constant.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalAlias.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Instruction.h"
+#include "llvm/Type.h"
+
+#include <algorithm>
+#include <vector>
+#include <set>
+#include <string>
+
+#include <stddef.h>
+
+
+namespace {
+
+#if defined(USE_DISASSEMBLER)
+class BufferMemoryObject : public llvm::MemoryObject {
+private:
+  const uint8_t *mBytes;
+  uint64_t mLength;
+
+public:
+  BufferMemoryObject(const uint8_t *Bytes, uint64_t Length)
+    : mBytes(Bytes), mLength(Length) {
+  }
+
+  virtual uint64_t getBase() const { return 0; }
+  virtual uint64_t getExtent() const { return mLength; }
+
+  virtual int readByte(uint64_t Addr, uint8_t *Byte) const {
+    if (Addr > getExtent())
+      return -1;
+    *Byte = mBytes[Addr];
+    return 0;
+  }
+};
+#endif
+
+}; // namespace anonymous
+
+
+namespace bcc {
+
+// Will take the ownership of @MemMgr
+CodeEmitter::CodeEmitter(CodeMemoryManager *pMemMgr)
+    : mpMemMgr(pMemMgr),
+      mpTarget(NULL),
+      mpTJI(NULL),
+      mpTD(NULL),
+      mpCurEmitFunction(NULL),
+      mpConstantPool(NULL),
+      mpJumpTable(NULL),
+      mpMMI(NULL),
+#if defined(USE_DISASSEMBLER)
+      mpAsmInfo(NULL),
+      mpDisassmbler(NULL),
+      mpIP(NULL),
+#endif
+      mpSymbolLookupFn(NULL),
+      mpSymbolLookupContext(NULL) {
+}
+
+
+CodeEmitter::~CodeEmitter() {
+  delete mpMemMgr;
+#if defined(USE_DISASSEMBLER)
+  delete mpAsmInfo;
+  delete mpDisassmbler;
+  delete mpIP;
+#endif
+}
+
+
+// Once you finish the compilation on a translation unit, you can call this
+// function to recycle the memory (which is used at compilation time and not
+// needed for runtime).
+//
+//  NOTE: You should not call this funtion until the code-gen passes for a
+//        given module is done. Otherwise, the results is undefined and may
+//        cause the system crash!
+void CodeEmitter::releaseUnnecessary() {
+  mMBBLocations.clear();
+  mLabelLocations.clear();
+  mGlobalAddressMap.clear();
+  mFunctionToLazyStubMap.clear();
+  GlobalToIndirectSymMap.clear();
+  ExternalFnToStubMap.clear();
+  PendingFunctions.clear();
+}
+
+
+void CodeEmitter::reset() {
+  releaseUnnecessary();
+
+  mpSymbolLookupFn = NULL;
+  mpSymbolLookupContext = NULL;
+
+  mpTJI = NULL;
+  mpTD = NULL;
+
+  for (EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin(),
+          E = mEmittedFunctions.end();
+       I != E;
+       I++)
+    if (I->second != NULL)
+      delete I->second;
+  mEmittedFunctions.clear();
+
+  mpMemMgr->reset();
+}
+
+
+void *CodeEmitter::UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
+  if (Addr == NULL) {
+    // Removing mapping
+    GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
+    void *OldVal;
+
+    if (I == mGlobalAddressMap.end()) {
+      OldVal = NULL;
+    } else {
+      OldVal = I->second;
+      mGlobalAddressMap.erase(I);
+    }
+
+    return OldVal;
+  }
+
+  void *&CurVal = mGlobalAddressMap[GV];
+  void *OldVal = CurVal;
+
+  CurVal = Addr;
+
+  return OldVal;
+}
+
+
+unsigned int CodeEmitter::GetConstantPoolSizeInBytes(
+                                    llvm::MachineConstantPool *MCP) {
+  const std::vector<llvm::MachineConstantPoolEntry> &Constants =
+      MCP->getConstants();
+
+  if (Constants.empty())
+    return 0;
+
+  unsigned int Size = 0;
+  for (int i = 0, e = Constants.size(); i != e; i++) {
+    llvm::MachineConstantPoolEntry CPE = Constants[i];
+    unsigned int AlignMask = CPE.getAlignment() - 1;
+    Size = (Size + AlignMask) & ~AlignMask;
+    const llvm::Type *Ty = CPE.getType();
+    Size += mpTD->getTypeAllocSize(Ty);
+  }
+
+  return Size;
+}
+
+// This function converts a Constant* into a GenericValue. The interesting
+// part is if C is a ConstantExpr.
+void CodeEmitter::GetConstantValue(const llvm::Constant *C,
+                                   llvm::GenericValue &Result) {
+  if (C->getValueID() == llvm::Value::UndefValueVal)
+    return;
+  else if (C->getValueID() == llvm::Value::ConstantExprVal) {
+    const llvm::ConstantExpr *CE = (llvm::ConstantExpr*) C;
+    const llvm::Constant *Op0 = CE->getOperand(0);
+
+    switch (CE->getOpcode()) {
+      case llvm::Instruction::GetElementPtr: {
+        // Compute the index
+        llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
+                                                   CE->op_end());
+        uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
+                                                 &Indices[0],
+                                                 Indices.size());
+
+        GetConstantValue(Op0, Result);
+        Result.PointerVal =
+            static_cast<uint8_t*>(Result.PointerVal) + Offset;
+
+        return;
+      }
+      case llvm::Instruction::Trunc: {
+        uint32_t BitWidth =
+            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
+
+        GetConstantValue(Op0, Result);
+        Result.IntVal = Result.IntVal.trunc(BitWidth);
+
+        return;
+      }
+      case llvm::Instruction::ZExt: {
+        uint32_t BitWidth =
+            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
+
+        GetConstantValue(Op0, Result);
+        Result.IntVal = Result.IntVal.zext(BitWidth);
+
+        return;
+      }
+      case llvm::Instruction::SExt: {
+        uint32_t BitWidth =
+            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
+
+        GetConstantValue(Op0, Result);
+        Result.IntVal = Result.IntVal.sext(BitWidth);
+
+        return;
+      }
+      case llvm::Instruction::FPTrunc: {
+        // TODO(all): fixme: long double
+        GetConstantValue(Op0, Result);
+        Result.FloatVal = static_cast<float>(Result.DoubleVal);
+        return;
+      }
+      case llvm::Instruction::FPExt: {
+        // TODO(all): fixme: long double
+        GetConstantValue(Op0, Result);
+        Result.DoubleVal = static_cast<double>(Result.FloatVal);
+        return;
+      }
+      case llvm::Instruction::UIToFP: {
+        GetConstantValue(Op0, Result);
+        if (CE->getType()->isFloatTy())
+          Result.FloatVal =
+              static_cast<float>(Result.IntVal.roundToDouble());
+        else if (CE->getType()->isDoubleTy())
+          Result.DoubleVal = Result.IntVal.roundToDouble();
+        else if (CE->getType()->isX86_FP80Ty()) {
+          const uint64_t zero[] = { 0, 0 };
+          llvm::APFloat apf(llvm::APInt(80, 2, zero));
+          apf.convertFromAPInt(Result.IntVal,
+                               false,
+                               llvm::APFloat::rmNearestTiesToEven);
+          Result.IntVal = apf.bitcastToAPInt();
+        }
+        return;
+      }
+      case llvm::Instruction::SIToFP: {
+        GetConstantValue(Op0, Result);
+        if (CE->getType()->isFloatTy())
+          Result.FloatVal =
+              static_cast<float>(Result.IntVal.signedRoundToDouble());
+        else if (CE->getType()->isDoubleTy())
+          Result.DoubleVal = Result.IntVal.signedRoundToDouble();
+        else if (CE->getType()->isX86_FP80Ty()) {
+          const uint64_t zero[] = { 0, 0 };
+          llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
+          apf.convertFromAPInt(Result.IntVal,
+                               true,
+                               llvm::APFloat::rmNearestTiesToEven);
+          Result.IntVal = apf.bitcastToAPInt();
+        }
+        return;
+      }
+      // double->APInt conversion handles sign
+      case llvm::Instruction::FPToUI:
+      case llvm::Instruction::FPToSI: {
+        uint32_t BitWidth =
+            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
+
+        GetConstantValue(Op0, Result);
+        if (Op0->getType()->isFloatTy())
+          Result.IntVal =
+           llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
+        else if (Op0->getType()->isDoubleTy())
+          Result.IntVal =
+              llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal,
+                                                 BitWidth);
+        else if (Op0->getType()->isX86_FP80Ty()) {
+          llvm::APFloat apf = llvm::APFloat(Result.IntVal);
+          uint64_t V;
+          bool Ignored;
+          apf.convertToInteger(&V,
+                               BitWidth,
+                               CE->getOpcode() == llvm::Instruction::FPToSI,
+                               llvm::APFloat::rmTowardZero,
+                               &Ignored);
+          Result.IntVal = V;  // endian?
+        }
+        return;
+      }
+      case llvm::Instruction::PtrToInt: {
+        uint32_t PtrWidth = mpTD->getPointerSizeInBits();
+
+        GetConstantValue(Op0, Result);
+        Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
+                                    (Result.PointerVal));
+
+        return;
+      }
+      case llvm::Instruction::IntToPtr: {
+        uint32_t PtrWidth = mpTD->getPointerSizeInBits();
+
+        GetConstantValue(Op0, Result);
+        if (PtrWidth != Result.IntVal.getBitWidth())
+          Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
+        assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
+
+        Result.PointerVal =
+            llvm::PointerTy(
+                static_cast<uintptr_t>(Result.IntVal.getZExtValue()));
+
+        return;
+      }
+      case llvm::Instruction::BitCast: {
+        GetConstantValue(Op0, Result);
+        const llvm::Type *DestTy = CE->getType();
+
+        switch (Op0->getType()->getTypeID()) {
+          case llvm::Type::IntegerTyID: {
+            assert(DestTy->isFloatingPointTy() && "invalid bitcast");
+            if (DestTy->isFloatTy())
+              Result.FloatVal = Result.IntVal.bitsToFloat();
+            else if (DestTy->isDoubleTy())
+              Result.DoubleVal = Result.IntVal.bitsToDouble();
+            break;
+          }
+          case llvm::Type::FloatTyID: {
+            assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
+            Result.IntVal.floatToBits(Result.FloatVal);
+            break;
+          }
+          case llvm::Type::DoubleTyID: {
+            assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
+            Result.IntVal.doubleToBits(Result.DoubleVal);
+            break;
+          }
+          case llvm::Type::PointerTyID: {
+            assert(DestTy->isPointerTy() && "Invalid bitcast");
+            break;  // getConstantValue(Op0) above already converted it
+          }
+          default: {
+            llvm_unreachable("Invalid bitcast operand");
+          }
+        }
+        return;
+      }
+      case llvm::Instruction::Add:
+      case llvm::Instruction::FAdd:
+      case llvm::Instruction::Sub:
+      case llvm::Instruction::FSub:
+      case llvm::Instruction::Mul:
+      case llvm::Instruction::FMul:
+      case llvm::Instruction::UDiv:
+      case llvm::Instruction::SDiv:
+      case llvm::Instruction::URem:
+      case llvm::Instruction::SRem:
+      case llvm::Instruction::And:
+      case llvm::Instruction::Or:
+      case llvm::Instruction::Xor: {
+        llvm::GenericValue LHS, RHS;
+        GetConstantValue(Op0, LHS);
+        GetConstantValue(CE->getOperand(1), RHS);
+
+        switch (Op0->getType()->getTypeID()) {
+          case llvm::Type::IntegerTyID: {
+            switch (CE->getOpcode()) {
+              case llvm::Instruction::Add: {
+                Result.IntVal = LHS.IntVal + RHS.IntVal;
+                break;
+              }
+              case llvm::Instruction::Sub: {
+                Result.IntVal = LHS.IntVal - RHS.IntVal;
+                break;
+              }
+              case llvm::Instruction::Mul: {
+                Result.IntVal = LHS.IntVal * RHS.IntVal;
+                break;
+              }
+              case llvm::Instruction::UDiv: {
+                Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
+                break;
+              }
+              case llvm::Instruction::SDiv: {
+                Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
+                break;
+              }
+              case llvm::Instruction::URem: {
+                Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
+                break;
+              }
+              case llvm::Instruction::SRem: {
+                Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
+                break;
+              }
+              case llvm::Instruction::And: {
+                Result.IntVal = LHS.IntVal & RHS.IntVal;
+                break;
+              }
+              case llvm::Instruction::Or: {
+                Result.IntVal = LHS.IntVal | RHS.IntVal;
+                break;
+              }
+              case llvm::Instruction::Xor: {
+                Result.IntVal = LHS.IntVal ^ RHS.IntVal;
+                break;
+              }
+              default: {
+                llvm_unreachable("Invalid integer opcode");
+              }
+            }
+            break;
+          }
+          case llvm::Type::FloatTyID: {
+            switch (CE->getOpcode()) {
+              case llvm::Instruction::FAdd: {
+                Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
+                break;
+              }
+              case llvm::Instruction::FSub: {
+                Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
+                break;
+              }
+              case llvm::Instruction::FMul: {
+                Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
+                break;
+              }
+              case llvm::Instruction::FDiv: {
+                Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
+                break;
+              }
+              case llvm::Instruction::FRem: {
+                Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
+                break;
+              }
+              default: {
+                llvm_unreachable("Invalid float opcode");
+              }
+            }
+            break;
+          }
+          case llvm::Type::DoubleTyID: {
+            switch (CE->getOpcode()) {
+              case llvm::Instruction::FAdd: {
+                Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
+                break;
+              }
+              case llvm::Instruction::FSub: {
+                Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
+                break;
+              }
+              case llvm::Instruction::FMul: {
+                Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
+                break;
+              }
+              case llvm::Instruction::FDiv: {
+                Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
+                break;
+              }
+              case llvm::Instruction::FRem: {
+                Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
+                break;
+              }
+              default: {
+                llvm_unreachable("Invalid double opcode");
+              }
+            }
+            break;
+          }
+          case llvm::Type::X86_FP80TyID:
+          case llvm::Type::PPC_FP128TyID:
+          case llvm::Type::FP128TyID: {
+            llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
+            switch (CE->getOpcode()) {
+              case llvm::Instruction::FAdd: {
+                apfLHS.add(llvm::APFloat(RHS.IntVal),
+                           llvm::APFloat::rmNearestTiesToEven);
+                break;
+              }
+              case llvm::Instruction::FSub: {
+                apfLHS.subtract(llvm::APFloat(RHS.IntVal),
+                                llvm::APFloat::rmNearestTiesToEven);
+                break;
+              }
+              case llvm::Instruction::FMul: {
+                apfLHS.multiply(llvm::APFloat(RHS.IntVal),
+                                llvm::APFloat::rmNearestTiesToEven);
+                break;
+              }
+              case llvm::Instruction::FDiv: {
+                apfLHS.divide(llvm::APFloat(RHS.IntVal),
+                              llvm::APFloat::rmNearestTiesToEven);
+                break;
+              }
+              case llvm::Instruction::FRem: {
+                apfLHS.mod(llvm::APFloat(RHS.IntVal),
+                           llvm::APFloat::rmNearestTiesToEven);
+                break;
+              }
+              default: {
+                llvm_unreachable("Invalid long double opcode");
+              }
+            }
+            Result.IntVal = apfLHS.bitcastToAPInt();
+            break;
+          }
+          default: {
+            llvm_unreachable("Bad add type!");
+          }
+        }  // End switch (Op0->getType()->getTypeID())
+        return;
+      }
+      default: {
+        break;
+      }
+    }   // End switch (CE->getOpcode())
+
+    std::string msg;
+    llvm::raw_string_ostream Msg(msg);
+    Msg << "ConstantExpr not handled: " << *CE;
+    llvm::report_fatal_error(Msg.str());
+  }  // C->getValueID() == llvm::Value::ConstantExprVal
+
+  switch (C->getType()->getTypeID()) {
+    case llvm::Type::FloatTyID: {
+      Result.FloatVal =
+          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToFloat();
+      break;
+    }
+    case llvm::Type::DoubleTyID: {
+      Result.DoubleVal =
+          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToDouble();
+      break;
+    }
+    case llvm::Type::X86_FP80TyID:
+    case llvm::Type::FP128TyID:
+    case llvm::Type::PPC_FP128TyID: {
+      Result.IntVal =
+          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().bitcastToAPInt();
+      break;
+    }
+    case llvm::Type::IntegerTyID: {
+      Result.IntVal =
+          llvm::cast<llvm::ConstantInt>(C)->getValue();
+      break;
+    }
+    case llvm::Type::PointerTyID: {
+      switch (C->getValueID()) {
+        case llvm::Value::ConstantPointerNullVal: {
+          Result.PointerVal = NULL;
+          break;
+        }
+        case llvm::Value::FunctionVal: {
+          const llvm::Function *F = static_cast<const llvm::Function*>(C);
+          Result.PointerVal =
+              GetPointerToFunctionOrStub(const_cast<llvm::Function*>(F));
+          break;
+        }
+        case llvm::Value::GlobalVariableVal: {
+          const llvm::GlobalVariable *GV =
+              static_cast<const llvm::GlobalVariable*>(C);
+          Result.PointerVal =
+            GetOrEmitGlobalVariable(const_cast<llvm::GlobalVariable*>(GV));
+          break;
+        }
+        case llvm::Value::BlockAddressVal: {
+          assert(false && "JIT does not support address-of-label yet!");
+        }
+        default: {
+          llvm_unreachable("Unknown constant pointer type!");
+        }
+      }
+      break;
+    }
+    default: {
+      std::string msg;
+      llvm::raw_string_ostream Msg(msg);
+      Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
+      llvm::report_fatal_error(Msg.str());
+      break;
+    }
+  }
+  return;
+}
+
+
+// Stores the data in @Val of type @Ty at address @Addr.
+void CodeEmitter::StoreValueToMemory(const llvm::GenericValue &Val,
+                                     void *Addr,
+                                     const llvm::Type *Ty) {
+  const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
+
+  switch (Ty->getTypeID()) {
+    case llvm::Type::IntegerTyID: {
+      const llvm::APInt &IntVal = Val.IntVal;
+      assert(((IntVal.getBitWidth() + 7) / 8 >= StoreBytes) &&
+          "Integer too small!");
+
+      const uint8_t *Src =
+        reinterpret_cast<const uint8_t*>(IntVal.getRawData());
+
+      if (llvm::sys::isLittleEndianHost()) {
+        // Little-endian host - the source is ordered from LSB to MSB.
+        // Order the destination from LSB to MSB: Do a straight copy.
+        memcpy(Addr, Src, StoreBytes);
+      } else {
+        // Big-endian host - the source is an array of 64 bit words
+        // ordered from LSW to MSW.
+        //
+        // Each word is ordered from MSB to LSB.
+        //
+        // Order the destination from MSB to LSB:
+        //  Reverse the word order, but not the bytes in a word.
+        unsigned int i = StoreBytes;
+        while (i > sizeof(uint64_t)) {
+          i -= sizeof(uint64_t);
+          ::memcpy(reinterpret_cast<uint8_t*>(Addr) + i,
+              Src,
+              sizeof(uint64_t));
+          Src += sizeof(uint64_t);
+        }
+        ::memcpy(Addr, Src + sizeof(uint64_t) - i, i);
+      }
+      break;
+    }
+    case llvm::Type::FloatTyID: {
+      *reinterpret_cast<float*>(Addr) = Val.FloatVal;
+      break;
+    }
+    case llvm::Type::DoubleTyID: {
+      *reinterpret_cast<double*>(Addr) = Val.DoubleVal;
+      break;
+    }
+    case llvm::Type::X86_FP80TyID: {
+      memcpy(Addr, Val.IntVal.getRawData(), 10);
+      break;
+    }
+    case llvm::Type::PointerTyID: {
+      // Ensure 64 bit target pointers are fully initialized on 32 bit
+      // hosts.
+      if (StoreBytes != sizeof(llvm::PointerTy))
+        memset(Addr, 0, StoreBytes);
+      *((llvm::PointerTy*) Addr) = Val.PointerVal;
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+
+  if (llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
+    std::reverse(reinterpret_cast<uint8_t*>(Addr),
+        reinterpret_cast<uint8_t*>(Addr) + StoreBytes);
+
+  return;
+}
+
+
+// Recursive function to apply a @Constant value into the specified memory
+// location @Addr.
+void CodeEmitter::InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
+  switch (C->getValueID()) {
+    case llvm::Value::UndefValueVal: {
+      // Nothing to do
+      break;
+    }
+    case llvm::Value::ConstantVectorVal: {
+      // dynamic cast may hurt performance
+      const llvm::ConstantVector *CP = (llvm::ConstantVector*) C;
+
+      unsigned int ElementSize = mpTD->getTypeAllocSize
+        (CP->getType()->getElementType());
+
+      for (int i = 0, e = CP->getNumOperands(); i != e;i++)
+        InitializeConstantToMemory(
+            CP->getOperand(i),
+            reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
+      break;
+    }
+    case llvm::Value::ConstantAggregateZeroVal: {
+      memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
+      break;
+    }
+    case llvm::Value::ConstantArrayVal: {
+      const llvm::ConstantArray *CPA = (llvm::ConstantArray*) C;
+      unsigned int ElementSize = mpTD->getTypeAllocSize
+        (CPA->getType()->getElementType());
+
+      for (int i = 0, e = CPA->getNumOperands(); i != e; i++)
+        InitializeConstantToMemory(
+            CPA->getOperand(i),
+            reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
+      break;
+    }
+    case llvm::Value::ConstantStructVal: {
+      const llvm::ConstantStruct *CPS =
+          static_cast<const llvm::ConstantStruct*>(C);
+      const llvm::StructLayout *SL = mpTD->getStructLayout
+        (llvm::cast<llvm::StructType>(CPS->getType()));
+
+      for (int i = 0, e = CPS->getNumOperands(); i != e; i++)
+        InitializeConstantToMemory(
+            CPS->getOperand(i),
+            reinterpret_cast<uint8_t*>(Addr) + SL->getElementOffset(i));
+      break;
+    }
+    default: {
+      if (C->getType()->isFirstClassType()) {
+        llvm::GenericValue Val;
+        GetConstantValue(C, Val);
+        StoreValueToMemory(Val, Addr, C->getType());
+      } else {
+        llvm_unreachable("Unknown constant type to initialize memory "
+                         "with!");
+      }
+      break;
+    }
+  }
+  return;
+}
+
+
+void CodeEmitter::emitConstantPool(llvm::MachineConstantPool *MCP) {
+  if (mpTJI->hasCustomConstantPool())
+    return;
+
+  // Constant pool address resolution is handled by the target itself in ARM
+  // (TargetJITInfo::hasCustomConstantPool() returns true).
+#if !defined(PROVIDE_ARM_CODEGEN)
+  const std::vector<llvm::MachineConstantPoolEntry> &Constants =
+    MCP->getConstants();
+
+  if (Constants.empty())
+    return;
+
+  unsigned Size = GetConstantPoolSizeInBytes(MCP);
+  unsigned Align = MCP->getConstantPoolAlignment();
+
+  mpConstantPoolBase = allocateSpace(Size, Align);
+  mpConstantPool = MCP;
+
+  if (mpConstantPoolBase == NULL)
+    return;  // out of memory
+
+  unsigned Offset = 0;
+  for (int i = 0, e = Constants.size(); i != e; i++) {
+    llvm::MachineConstantPoolEntry CPE = Constants[i];
+    unsigned AlignMask = CPE.getAlignment() - 1;
+    Offset = (Offset + AlignMask) & ~AlignMask;
+
+    uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
+    mConstPoolAddresses.push_back(CAddr);
+
+    if (CPE.isMachineConstantPoolEntry())
+      llvm::report_fatal_error
+        ("Initialize memory with machine specific constant pool"
+         " entry has not been implemented!");
+
+    InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
+
+    const llvm::Type *Ty = CPE.Val.ConstVal->getType();
+    Offset += mpTD->getTypeAllocSize(Ty);
+  }
+#endif
+  return;
+}
+
+
+void CodeEmitter::initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
+  if (mpTJI->hasCustomJumpTables())
+    return;
+
+  const std::vector<llvm::MachineJumpTableEntry> &JT =
+    MJTI->getJumpTables();
+  if (JT.empty())
+    return;
+
+  unsigned NumEntries = 0;
+  for (int i = 0, e = JT.size(); i != e; i++)
+    NumEntries += JT[i].MBBs.size();
+
+  unsigned EntrySize = MJTI->getEntrySize(*mpTD);
+
+  mpJumpTable = MJTI;
+  mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
+      MJTI->getEntryAlignment(*mpTD));
+
+  return;
+}
+
+
+void CodeEmitter::emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
+  if (mpTJI->hasCustomJumpTables())
+    return;
+
+  const std::vector<llvm::MachineJumpTableEntry> &JT =
+    MJTI->getJumpTables();
+  if (JT.empty() || mpJumpTableBase == 0)
+    return;
+
+  assert(llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static &&
+         (MJTI->getEntrySize(*mpTD) == sizeof(mpTD /* a pointer type */)) &&
+         "Cross JIT'ing?");
+
+  // For each jump table, map each target in the jump table to the
+  // address of an emitted MachineBasicBlock.
+  intptr_t *SlotPtr = reinterpret_cast<intptr_t*>(mpJumpTableBase);
+  for (int i = 0, ie = JT.size(); i != ie; i++) {
+    const std::vector<llvm::MachineBasicBlock*> &MBBs = JT[i].MBBs;
+    // Store the address of the basic block for this jump table slot in the
+    // memory we allocated for the jump table in 'initJumpTableInfo'
+    for (int j = 0, je = MBBs.size(); j != je; j++)
+      *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
+  }
+}
+
+
+void *CodeEmitter::GetPointerToGlobal(llvm::GlobalValue *V,
+                                      void *Reference,
+                                      bool MayNeedFarStub) {
+  switch (V->getValueID()) {
+    case llvm::Value::FunctionVal: {
+      llvm::Function *F = (llvm::Function*) V;
+
+      // If we have code, go ahead and return that.
+      if (void *ResultPtr = GetPointerToGlobalIfAvailable(F))
+        return ResultPtr;
+
+      if (void *FnStub = GetLazyFunctionStubIfAvailable(F))
+        // Return the function stub if it's already created.
+        // We do this first so that:
+        //   we're returning the same address for the function as any
+        //   previous call.
+        //
+        // TODO(llvm.org): Yes, this is wrong. The lazy stub isn't
+        //                 guaranteed to be close enough to call.
+        return FnStub;
+
+      // If we know the target can handle arbitrary-distance calls, try to
+      //  return a direct pointer.
+      if (!MayNeedFarStub) {
+        //
+        // x86_64 architecture may encounter the bug:
+        //   http://llvm.org/bugs/show_bug.cgi?id=5201
+        // which generate instruction "call" instead of "callq".
+        //
+        // And once the real address of stub is greater than 64-bit
+        // long, the replacement will truncate to 32-bit resulting a
+        // serious problem.
+#if !defined(__x86_64__)
+        // If this is an external function pointer, we can force the JIT
+        // to 'compile' it, which really just adds it to the map.
+        if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
+          return GetPointerToFunction(F, /* AbortOnFailure = */false);
+          // Changing to false because wanting to allow later calls to
+          // mpTJI->relocate() without aborting. For caching purpose
+        }
+#endif
+      }
+
+      // Otherwise, we may need a to emit a stub, and, conservatively, we
+      // always do so.
+      return GetLazyFunctionStub(F);
+      break;
+    }
+    case llvm::Value::GlobalVariableVal: {
+      return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
+      break;
+    }
+    case llvm::Value::GlobalAliasVal: {
+      llvm::GlobalAlias *GA = (llvm::GlobalAlias*) V;
+      const llvm::GlobalValue *GV = GA->resolveAliasedGlobal(false);
+
+      switch (GV->getValueID()) {
+        case llvm::Value::FunctionVal: {
+          // TODO(all): is there's any possibility that the function is not
+          // code-gen'd?
+          return GetPointerToFunction(
+              static_cast<const llvm::Function*>(GV),
+              /* AbortOnFailure = */false);
+          // Changing to false because wanting to allow later calls to
+          // mpTJI->relocate() without aborting. For caching purpose
+          break;
+        }
+        case llvm::Value::GlobalVariableVal: {
+          if (void *P = mGlobalAddressMap[GV])
+            return P;
+
+          llvm::GlobalVariable *GVar = (llvm::GlobalVariable*) GV;
+          EmitGlobalVariable(GVar);
+
+          return mGlobalAddressMap[GV];
+          break;
+        }
+        case llvm::Value::GlobalAliasVal: {
+          assert(false && "Alias should be resolved ultimately!");
+        }
+      }
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+  llvm_unreachable("Unknown type of global value!");
+}
+
+
+// If the specified function has been code-gen'd, return a pointer to the
+// function. If not, compile it, or use a stub to implement lazy compilation
+// if available.
+void *CodeEmitter::GetPointerToFunctionOrStub(llvm::Function *F) {
+  // If we have already code generated the function, just return the
+  // address.
+  if (void *Addr = GetPointerToGlobalIfAvailable(F))
+    return Addr;
+
+  // Get a stub if the target supports it.
+  return GetLazyFunctionStub(F);
+}
+
+
+void *CodeEmitter::GetLazyFunctionStub(llvm::Function *F) {
+  // If we already have a lazy stub for this function, recycle it.
+  void *&Stub = mFunctionToLazyStubMap[F];
+  if (Stub)
+    return Stub;
+
+  // In any cases, we should NOT resolve function at runtime (though we are
+  // able to). We resolve this right now.
+  void *Actual = NULL;
+  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
+    Actual = GetPointerToFunction(F, /* AbortOnFailure = */false);
+    // Changing to false because wanting to allow later calls to
+    // mpTJI->relocate() without aborting. For caching purpose
+  }
+
+  // Codegen a new stub, calling the actual address of the external
+  // function, if it was resolved.
+  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
+  startGVStub(F, SL.Size, SL.Alignment);
+  Stub = mpTJI->emitFunctionStub(F, Actual, *this);
+  finishGVStub();
+
+  // We really want the address of the stub in the GlobalAddressMap for the
+  // JIT, not the address of the external function.
+  UpdateGlobalMapping(F, Stub);
+
+  if (!Actual)
+    PendingFunctions.insert(F);
+  else
+    Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
+                SL.Size, true);
+
+  return Stub;
+}
+
+
+void *CodeEmitter::GetPointerToFunction(const llvm::Function *F,
+                                        bool AbortOnFailure) {
+  void *Addr = GetPointerToGlobalIfAvailable(F);
+  if (Addr)
+    return Addr;
+
+  assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
+         "Internal error: only external defined function routes here!");
+
+  // Handle the failure resolution by ourselves.
+  Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
+                                 /* AbortOnFailure = */ false);
+
+  // If we resolved the symbol to a null address (eg. a weak external)
+  // return a null pointer let the application handle it.
+  if (Addr == NULL) {
+    if (AbortOnFailure)
+      llvm::report_fatal_error("Could not resolve external function "
+                               "address: " + F->getName());
+    else
+      return NULL;
+  }
+
+  AddGlobalMapping(F, Addr);
+
+  return Addr;
+}
+
+
+void *CodeEmitter::GetPointerToNamedSymbol(const std::string &Name,
+                                           bool AbortOnFailure) {
+  if (void *Addr = FindRuntimeFunction(Name.c_str()))
+    return Addr;
+
+  if (mpSymbolLookupFn)
+    if (void *Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
+      return Addr;
+
+  if (AbortOnFailure)
+    llvm::report_fatal_error("Program used external symbol '" + Name +
+                            "' which could not be resolved!");
+
+  return NULL;
+}
+
+
+// Return the address of the specified global variable, possibly emitting it
+// to memory if needed. This is used by the Emitter.
+void *CodeEmitter::GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
+  void *Ptr = GetPointerToGlobalIfAvailable(GV);
+  if (Ptr)
+    return Ptr;
+
+  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
+    // If the global is external, just remember the address.
+    Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
+    AddGlobalMapping(GV, Ptr);
+  } else {
+    // If the global hasn't been emitted to memory yet, allocate space and
+    // emit it into memory.
+    Ptr = GetMemoryForGV(GV);
+    AddGlobalMapping(GV, Ptr);
+    EmitGlobalVariable(GV);
+  }
+
+  return Ptr;
+}
+
+
+// This method abstracts memory allocation of global variable so that the
+// JIT can allocate thread local variables depending on the target.
+void *CodeEmitter::GetMemoryForGV(const llvm::GlobalVariable *GV) {
+  void *Ptr;
+
+  const llvm::Type *GlobalType = GV->getType()->getElementType();
+  size_t S = mpTD->getTypeAllocSize(GlobalType);
+  size_t A = mpTD->getPreferredAlignment(GV);
+
+  if (GV->isThreadLocal()) {
+    // We can support TLS by
+    //
+    //  Ptr = TJI.allocateThreadLocalMemory(S);
+    //
+    // But I tend not to.
+    // (should we disable this in the front-end (i.e., slang)?).
+    llvm::report_fatal_error
+        ("Compilation of Thread Local Storage (TLS) is disabled!");
+
+  } else if (mpTJI->allocateSeparateGVMemory()) {
+    if (A <= 8) {
+      Ptr = malloc(S);
+    } else {
+      // Allocate (S + A) bytes of memory, then use an aligned pointer
+      // within that space.
+      Ptr = malloc(S + A);
+      unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
+      Ptr = reinterpret_cast<uint8_t*>(Ptr) +
+                (MisAligned ? (A - MisAligned) : 0);
+    }
+  } else {
+    Ptr = allocateGlobal(S, A);
+  }
+
+  return Ptr;
+}
+
+
+void CodeEmitter::EmitGlobalVariable(const llvm::GlobalVariable *GV) {
+  void *GA = GetPointerToGlobalIfAvailable(GV);
+
+  if (GV->isThreadLocal())
+    llvm::report_fatal_error
+        ("We don't support Thread Local Storage (TLS)!");
+
+  if (GA == NULL) {
+    // If it's not already specified, allocate memory for the global.
+    GA = GetMemoryForGV(GV);
+    AddGlobalMapping(GV, GA);
+  }
+
+  InitializeConstantToMemory(GV->getInitializer(), GA);
+
+  // You can do some statistics on global variable here.
+  return;
+}
+
+
+void *CodeEmitter::GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
+  // Make sure GV is emitted first, and create a stub containing the fully
+  // resolved address.
+  void *GVAddress = GetPointerToGlobal(V, Reference, false);
+
+  // If we already have a stub for this global variable, recycle it.
+  void *&IndirectSym = GlobalToIndirectSymMap[V];
+  // Otherwise, codegen a new indirect symbol.
+  if (!IndirectSym)
+    IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
+
+  return IndirectSym;
+}
+
+
+// Return a stub for the function at the specified address.
+void *CodeEmitter::GetExternalFunctionStub(void *FnAddr) {
+  void *&Stub = ExternalFnToStubMap[FnAddr];
+  if (Stub)
+    return Stub;
+
+  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
+  startGVStub(0, SL.Size, SL.Alignment);
+  Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
+  finishGVStub();
+
+  return Stub;
+}
+
+
+void CodeEmitter::Disassemble(const llvm::StringRef &Name,
+                              uint8_t *Start, size_t Length, bool IsStub) {
+
+#if defined(USE_DISASSEMBLER)
+  llvm::raw_ostream *OS;
+
+#if defined(USE_DISASSEMBLER_FILE)
+  std::string ErrorInfo;
+  OS = new llvm::raw_fd_ostream("/data/local/tmp/out.S",
+                                ErrorInfo,
+                                llvm::raw_fd_ostream::F_Append);
+
+  if (!ErrorInfo.empty()) {    // some errors occurred
+    // LOGE("Error in creating disassembly file");
+    delete OS;
+    return;
+  }
+#else
+  OS = &llvm::outs();
+#endif
+
+  *OS << "JIT: Disassembled code: " << Name << ((IsStub) ? " (stub)" : "")
+      << "\n";
+
+  if (mpAsmInfo == NULL)
+    mpAsmInfo = mpTarget->createAsmInfo(Compiler::Triple);
+  if (mpDisassmbler == NULL)
+    mpDisassmbler = mpTarget->createMCDisassembler();
+  if (mpIP == NULL)
+    mpIP = mpTarget->createMCInstPrinter(mpAsmInfo->getAssemblerDialect(),
+                                         *mpAsmInfo);
+
+  const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Start,
+                                                                Length);
+  uint64_t Size;
+  uint64_t Index;
+
+  for (Index = 0; Index < Length; Index += Size) {
+    llvm::MCInst Inst;
+
+    if (mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
+          /* REMOVED */ llvm::nulls())) {
+      (*OS).indent(4)
+           .write("0x", 2)
+           .write_hex((uint32_t) Start + Index)
+           .write(':');
+      mpIP->printInst(&Inst, *OS);
+      *OS << "\n";
+    } else {
+      if (Size == 0)
+        Size = 1;  // skip illegible bytes
+    }
+  }
+
+  *OS << "\n";
+  delete BufferMObj;
+
+#if defined(USE_DISASSEMBLER_FILE)
+  // If you want the disassemble results write to file, uncomment this.
+  OS->close();
+  delete OS;
+#endif
+
+#endif // defined(USE_DISASSEMBLER)
+}
+
+
+void CodeEmitter::setTargetMachine(llvm::TargetMachine &TM) {
+  // Set Target
+  mpTarget = &TM.getTarget();
+  // Set TargetJITInfo
+  mpTJI = TM.getJITInfo();
+  // set TargetData
+  mpTD = TM.getTargetData();
+
+  assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
+
+  return;
+}
+
+
+// This callback is invoked when the specified function is about to be code
+// generated.  This initializes the BufferBegin/End/Ptr fields.
+void CodeEmitter::startFunction(llvm::MachineFunction &F) {
+  uintptr_t ActualSize = 0;
+
+  mpMemMgr->setMemoryWritable();
+
+  // BufferBegin, BufferEnd and CurBufferPtr are all inherited from class
+  // MachineCodeEmitter, which is the super class of the class
+  // JITCodeEmitter.
+  //
+  // BufferBegin/BufferEnd - Pointers to the start and end of the memory
+  //                         allocated for this code buffer.
+  //
+  // CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+  //                code. This is guranteed to be in the range
+  //                [BufferBegin, BufferEnd].  If this pointer is at
+  //                BufferEnd, it will never move due to code emission, and
+  //                all code emission requests will be ignored (this is the
+  //                buffer overflow condition).
+  BufferBegin = CurBufferPtr =
+      mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
+  BufferEnd = BufferBegin + ActualSize;
+
+  if (mpCurEmitFunction == NULL)
+    mpCurEmitFunction = new EmittedFuncEntry();
+  mpCurEmitFunction->FunctionBody = BufferBegin;
+
+  // Ensure the constant pool/jump table info is at least 4-byte aligned.
+  emitAlignment(16);
+
+  emitConstantPool(F.getConstantPool());
+  if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
+    initJumpTableInfo(MJTI);
+
+  // About to start emitting the machine code for the function.
+  emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
+
+  UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
+
+  mpCurEmitFunction->Code = CurBufferPtr;
+
+  mMBBLocations.clear();
+}
+
+
+// This callback is invoked when the specified function has finished code
+// generation. If a buffer overflow has occurred, this method returns true
+// (the callee is required to try again).
+bool CodeEmitter::finishFunction(llvm::MachineFunction &F) {
+  if (CurBufferPtr == BufferEnd) {
+    // No enough memory
+    mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
+    return false;
+  }
+
+  if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
+    emitJumpTableInfo(MJTI);
+
+  // FnStart is the start of the text, not the start of the constant pool
+  // and other per-function data.
+  uint8_t *FnStart =
+      reinterpret_cast<uint8_t*>(
+          GetPointerToGlobalIfAvailable(F.getFunction()));
+
+  // FnEnd is the end of the function's machine code.
+  uint8_t *FnEnd = CurBufferPtr;
+
+  if (!mRelocations.empty()) {
+    ptrdiff_t BufferOffset = BufferBegin - mpMemMgr->getCodeMemBase();
+
+    // Resolve the relocations to concrete pointers.
+    for (int i = 0, e = mRelocations.size(); i != e; i++) {
+      llvm::MachineRelocation &MR = mRelocations[i];
+      void *ResultPtr = NULL;
+
+      if (!MR.letTargetResolve()) {
+        if (MR.isExternalSymbol()) {
+          ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
+
+          if (MR.mayNeedFarStub()) {
+            ResultPtr = GetExternalFunctionStub(ResultPtr);
+          }
+
+        } else if (MR.isGlobalValue()) {
+          ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
+                                         BufferBegin
+                                           + MR.getMachineCodeOffset(),
+                                         MR.mayNeedFarStub());
+        } else if (MR.isIndirectSymbol()) {
+          ResultPtr =
+              GetPointerToGVIndirectSym(
+                  MR.getGlobalValue(),
+                  BufferBegin + MR.getMachineCodeOffset());
+        } else if (MR.isBasicBlock()) {
+          ResultPtr =
+              (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
+        } else if (MR.isConstantPoolIndex()) {
+          ResultPtr =
+             (void*) getConstantPoolEntryAddress(MR.getConstantPoolIndex());
+        } else {
+          assert(MR.isJumpTableIndex() && "Unknown type of relocation");
+          ResultPtr =
+              (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
+        }
+
+        if (!MR.isExternalSymbol() || MR.mayNeedFarStub()) {
+          // TODO(logan): Cache external symbol relocation entry.
+          // Currently, we are not caching them.  But since Android
+          // system is using prelink, it is not a problem.
+
+          // Cache the relocation result address
+          mCachingRelocations.push_back(
+            oBCCRelocEntry(MR.getRelocationType(),
+                           MR.getMachineCodeOffset() + BufferOffset,
+                           ResultPtr));
+        }
+
+        MR.setResultPointer(ResultPtr);
+      }
+    }
+
+    mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
+                    mpMemMgr->getGOTBase());
+  }
+
+  mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
+  // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
+  // global variables that were referenced in the relocations.
+  if (CurBufferPtr == BufferEnd)
+    return false;
+
+  // Now that we've succeeded in emitting the function.
+  mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
+  BufferBegin = CurBufferPtr = 0;
+
+  if (F.getFunction()->hasName())
+    mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
+  mpCurEmitFunction = NULL;
+
+  mRelocations.clear();
+  mConstPoolAddresses.clear();
+
+  if (mpMMI)
+    mpMMI->EndFunction();
+
+  updateFunctionStub(F.getFunction());
+
+  // Mark code region readable and executable if it's not so already.
+  mpMemMgr->setMemoryExecutable();
+
+  Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
+
+  return false;
+}
+
+
+void CodeEmitter::startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
+                 unsigned Alignment) {
+  mpSavedBufferBegin = BufferBegin;
+  mpSavedBufferEnd = BufferEnd;
+  mpSavedCurBufferPtr = CurBufferPtr;
+
+  BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
+                                                      Alignment);
+  BufferEnd = BufferBegin + StubSize + 1;
+
+  return;
+}
+
+
+void CodeEmitter::startGVStub(void *Buffer, unsigned StubSize) {
+  mpSavedBufferBegin = BufferBegin;
+  mpSavedBufferEnd = BufferEnd;
+  mpSavedCurBufferPtr = CurBufferPtr;
+
+  BufferBegin = CurBufferPtr = reinterpret_cast<uint8_t *>(Buffer);
+  BufferEnd = BufferBegin + StubSize + 1;
+
+  return;
+}
+
+
+void CodeEmitter::finishGVStub() {
+  assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
+
+  // restore
+  BufferBegin = mpSavedBufferBegin;
+  BufferEnd = mpSavedBufferEnd;
+  CurBufferPtr = mpSavedCurBufferPtr;
+}
+
+
+// Allocates and fills storage for an indirect GlobalValue, and returns the
+// address.
+void *CodeEmitter::allocIndirectGV(const llvm::GlobalValue *GV,
+                      const uint8_t *Buffer, size_t Size,
+                      unsigned Alignment) {
+  uint8_t *IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
+  memcpy(IndGV, Buffer, Size);
+  return IndGV;
+}
+
+
+// Allocate memory for a global. Unlike allocateSpace, this method does not
+// allocate memory in the current output buffer, because a global may live
+// longer than the current function.
+void *CodeEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) {
+  // Delegate this call through the memory manager.
+  return mpMemMgr->allocateGlobal(Size, Alignment);
+}
+
+
+// This should be called by the target when a new basic block is about to be
+// emitted. This way the MCE knows where the start of the block is, and can
+// implement getMachineBasicBlockAddress.
+void CodeEmitter::StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
+  if (mMBBLocations.size() <= (unsigned) MBB->getNumber())
+    mMBBLocations.resize((MBB->getNumber() + 1) * 2);
+  mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
+  return;
+}
+
+
+// Return the address of the jump table with index @Index in the function
+// that last called initJumpTableInfo.
+uintptr_t CodeEmitter::getJumpTableEntryAddress(unsigned Index) const {
+  const std::vector<llvm::MachineJumpTableEntry> &JT =
+      mpJumpTable->getJumpTables();
+
+  assert((Index < JT.size()) && "Invalid jump table index!");
+
+  unsigned int Offset = 0;
+  unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
+
+  for (unsigned i = 0; i < Index; i++)
+    Offset += JT[i].MBBs.size();
+  Offset *= EntrySize;
+
+  return (uintptr_t)(reinterpret_cast<uint8_t*>(mpJumpTableBase) + Offset);
+}
+
+
+// Return the address of the specified MachineBasicBlock, only usable after
+// the label for the MBB has been emitted.
+uintptr_t CodeEmitter::getMachineBasicBlockAddress(
+                                        llvm::MachineBasicBlock *MBB) const {
+  assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
+         mMBBLocations[MBB->getNumber()] &&
+         "MBB not emitted!");
+  return mMBBLocations[MBB->getNumber()];
+}
+
+
+void CodeEmitter::updateFunctionStub(const llvm::Function *F) {
+  // Get the empty stub we generated earlier.
+  void *Stub;
+  std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
+  if (I != PendingFunctions.end())
+    Stub = mFunctionToLazyStubMap[F];
+  else
+    return;
+
+  void *Addr = GetPointerToGlobalIfAvailable(F);
+
+  assert(Addr != Stub &&
+         "Function must have non-stub address to be updated.");
+
+  // Tell the target jit info to rewrite the stub at the specified address,
+  // rather than creating a new one.
+  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
+  startGVStub(Stub, SL.Size);
+  mpTJI->emitFunctionStub(F, Addr, *this);
+  finishGVStub();
+
+  Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
+              SL.Size, true);
+
+  PendingFunctions.erase(I);
+}
+
+
+void *CodeEmitter::lookup(const llvm::StringRef &Name) {
+  EmittedFunctionsMapTy::const_iterator
+    I = mEmittedFunctions.find(Name.str());
+
+  return (I == mEmittedFunctions.end()) ? NULL : I->second->Code;
+}
+
+
+void CodeEmitter::getFunctionNames(BCCsizei *actualFunctionCount,
+                                   BCCsizei maxFunctionCount,
+                                   BCCchar **functions) {
+  int functionCount = mEmittedFunctions.size();
+
+  if (actualFunctionCount)
+    *actualFunctionCount = functionCount;
+  if (functionCount > maxFunctionCount)
+    functionCount = maxFunctionCount;
+  if (functions)
+    for (EmittedFunctionsMapTy::const_iterator
+         I = mEmittedFunctions.begin(), E = mEmittedFunctions.end();
+         I != E && (functionCount > 0); I++, functionCount--) {
+      *functions++ = const_cast<BCCchar*>(I->first.c_str());
+    }
+}
+
+
+void CodeEmitter::getFunctionBinary(BCCchar *label,
+                                    BCCvoid **base,
+                                    BCCsizei *length) {
+  EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
+  if (I == mEmittedFunctions.end()) {
+    *base = NULL;
+    *length = 0;
+  } else {
+    *base = I->second->Code;
+    *length = I->second->Size;
+  }
+}
+
+} // namespace bcc