Quick compiler: support for arrays, misc.

Continuing to flesh out support in the Quick compiler.  Mostly
array-related.  Also, added runtest 028-array-write to the set of
passing tests.

Change-Id: I3c8eaf4bb14e9327e4f5fc48de73c85a5d3efb54
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 9e4b857..ba8d0d8 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -768,6 +768,10 @@
       || (PrettyMethod(method_idx, dex_file).find("math_013") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("math_014") != std::string::npos)
       || (PrettyMethod(method_idx, dex_file).find("float_017") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("array_028") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("writeArray") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("writeTest") != std::string::npos)
+      || (PrettyMethod(method_idx, dex_file).find("copyTest") != std::string::npos)
      ) {
     cUnit->genBitcode = true;
   }
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index cf990ec..690f022 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -140,12 +140,25 @@
   return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
 }
 
-llvm::Value* emitSget(CompilationUnit* cUnit,
-                      greenland::IntrinsicHelper::IntrinsicId id,
-                      llvm::ArrayRef<llvm::Value*> src, RegLocation Loc)
+void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
+                 greenland::IntrinsicHelper::IntrinsicId id,
+                 RegLocation rlDest)
 {
+  llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
   llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
-  return cUnit->irb->CreateCall(intr, src);
+  llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
+                 greenland::IntrinsicHelper::IntrinsicId id,
+                 RegLocation rlSrc)
+{
+  llvm::SmallVector<llvm::Value*, 2> args;
+  args.push_back(cUnit->irb->getInt32(fieldIndex));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  cUnit->irb->CreateCall(intr, args);
 }
 
 llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
@@ -178,8 +191,6 @@
   cUnit->irb->CreateCall(intr);
 }
 
-
-
 llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
                       RegLocation loc)
 {
@@ -220,6 +231,27 @@
   cUnit->irb->CreateUnreachable();
 }
 
+void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
+                             greenland::IntrinsicHelper::IntrinsicId id,
+                             RegLocation rlSrc)
+{
+  llvm::SmallVector<llvm::Value*, 2> args;
+  args.push_back(cUnit->irb->getInt32(optFlags));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  cUnit->irb->CreateCall(func, args);
+}
+
+void convertArrayLength(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  llvm::SmallVector<llvm::Value*, 2> args;
+  args.push_back(cUnit->irb->getInt32(optFlags));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
+      greenland::IntrinsicHelper::ArrayLength);
+  cUnit->irb->CreateCall(func, args);
+}
+
 void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
 {
   llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
@@ -450,7 +482,7 @@
       if (info->result.fp) {
         id = greenland::IntrinsicHelper::HLInvokeDouble;
       } else {
-        id = greenland::IntrinsicHelper::HLInvokeFloat;
+        id = greenland::IntrinsicHelper::HLInvokeLong;
       }
     } else if (info->result.ref) {
         id = greenland::IntrinsicHelper::HLInvokeObj;
@@ -478,8 +510,8 @@
   defineValue(cUnit, res, rlDest.origSReg);
 }
 
-void convertNewInstance(CompilationUnit* cUnit, BasicBlock* bb,
-                        uint32_t type_idx, RegLocation rlDest)
+void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
+                        RegLocation rlDest)
 {
   greenland::IntrinsicHelper::IntrinsicId id;
   id = greenland::IntrinsicHelper::NewInstance;
@@ -489,6 +521,58 @@
   defineValue(cUnit, res, rlDest.origSReg);
 }
 
+void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
+                     RegLocation rlDest, RegLocation rlSrc)
+{
+  greenland::IntrinsicHelper::IntrinsicId id;
+  id = greenland::IntrinsicHelper::NewArray;
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  llvm::SmallVector<llvm::Value*, 2> args;
+  args.push_back(cUnit->irb->getInt32(type_idx));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertAget(CompilationUnit* cUnit, int optFlags,
+                 greenland::IntrinsicHelper::IntrinsicId id,
+                 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
+{
+  llvm::SmallVector<llvm::Value*, 3> args;
+  args.push_back(cUnit->irb->getInt32(optFlags));
+  args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
+  args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
+void convertAput(CompilationUnit* cUnit, int optFlags,
+                 greenland::IntrinsicHelper::IntrinsicId id,
+                 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
+{
+  llvm::SmallVector<llvm::Value*, 4> args;
+  args.push_back(cUnit->irb->getInt32(optFlags));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
+  args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  cUnit->irb->CreateCall(intr, args);
+}
+
+void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
+                       RegLocation rlDest, RegLocation rlSrc)
+{
+  greenland::IntrinsicHelper::IntrinsicId id;
+  id = greenland::IntrinsicHelper::InstanceOf;
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  llvm::SmallVector<llvm::Value*, 2> args;
+  args.push_back(cUnit->irb->getInt32(type_idx));
+  args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
+  llvm::Value* res = cUnit->irb->CreateCall(intr, args);
+  defineValue(cUnit, res, rlDest.origSReg);
+}
+
 /*
  * Target-independent code generation.  Use only high-level
  * load/store utilities here, or target-dependent genXX() handlers
@@ -505,6 +589,7 @@
   uint32_t vA = mir->dalvikInsn.vA;
   uint32_t vB = mir->dalvikInsn.vB;
   uint32_t vC = mir->dalvikInsn.vC;
+  int optFlags = mir->optimizationFlags;
 
   bool objectDefinition = false;
 
@@ -613,11 +698,69 @@
       }
       break;
 
-    case Instruction::SGET_OBJECT: {
-        llvm::Constant* fieldIdx = cUnit->irb->GetJInt(vB);
-        llvm::Value* res = emitSget(cUnit, greenland::IntrinsicHelper::SgetObj,
-                                    fieldIdx, rlDest);
-        defineValue(cUnit, res, rlDest.origSReg);
+    case Instruction::SPUT_OBJECT:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
+                  rlSrc[0]);
+      break;
+    case Instruction::SPUT:
+      if (rlSrc[0].fp) {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
+                    rlSrc[0]);
+      } else {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
+      }
+      break;
+    case Instruction::SPUT_BOOLEAN:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
+                  rlSrc[0]);
+      break;
+    case Instruction::SPUT_BYTE:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
+      break;
+    case Instruction::SPUT_CHAR:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
+      break;
+    case Instruction::SPUT_SHORT:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
+      break;
+    case Instruction::SPUT_WIDE:
+      if (rlSrc[0].fp) {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
+                    rlSrc[0]);
+      } else {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
+                    rlSrc[0]);
+      }
+      break;
+
+    case Instruction::SGET_OBJECT:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
+      break;
+    case Instruction::SGET:
+      if (rlDest.fp) {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
+      } else {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
+      }
+      break;
+    case Instruction::SGET_BOOLEAN:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
+      break;
+    case Instruction::SGET_BYTE:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
+      break;
+    case Instruction::SGET_CHAR:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
+      break;
+    case Instruction::SGET_SHORT:
+      convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
+      break;
+    case Instruction::SGET_WIDE:
+      if (rlDest.fp) {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
+                    rlDest);
+      } else {
+        convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
       }
       break;
 
@@ -881,7 +1024,7 @@
       break;
 
     case Instruction::NEW_INSTANCE:
-      convertNewInstance(cUnit, bb, vB, rlDest);
+      convertNewInstance(cUnit, vB, rlDest);
       break;
 
    case Instruction::MOVE_EXCEPTION:
@@ -896,70 +1039,124 @@
       convertThrowVerificationError(cUnit, vA, vB);
       break;
 
-#if 0
-
-    case Instruction::MOVE_EXCEPTION: {
-      int exOffset = Thread::ExceptionOffset().Int32Value();
-      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-#if defined(TARGET_X86)
-      newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
-      newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
-#else
-      int resetReg = oatAllocTemp(cUnit);
-      loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
-      loadConstant(cUnit, resetReg, 0);
-      storeWordDisp(cUnit, rSELF, exOffset, resetReg);
-      storeValue(cUnit, rlDest, rlResult);
-      oatFreeTemp(cUnit, resetReg);
-#endif
-      break;
-    }
-
     case Instruction::MOVE_RESULT_WIDE:
-      if (mir->optimizationFlags & MIR_INLINED)
-        break;  // Nop - combined w/ previous invoke
-      storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
-      break;
-
     case Instruction::MOVE_RESULT:
     case Instruction::MOVE_RESULT_OBJECT:
-      if (mir->optimizationFlags & MIR_INLINED)
-        break;  // Nop - combined w/ previous invoke
-      storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
+      CHECK(false) << "Unexpected MOVE_RESULT";
       break;
 
     case Instruction::MONITOR_ENTER:
-      genMonitorEnter(cUnit, mir, rlSrc[0]);
+      convertMonitorEnterExit(cUnit, optFlags,
+                              greenland::IntrinsicHelper::MonitorEnter,
+                              rlSrc[0]);
       break;
 
     case Instruction::MONITOR_EXIT:
-      genMonitorExit(cUnit, mir, rlSrc[0]);
-      break;
-
-    case Instruction::CHECK_CAST:
-      genCheckCast(cUnit, mir, rlSrc[0]);
-      break;
-
-    case Instruction::INSTANCE_OF:
-      genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
-      break;
-
-    case Instruction::THROW:
-      genThrow(cUnit, mir, rlSrc[0]);
-      break;
-
-    case Instruction::THROW_VERIFICATION_ERROR:
-      genThrowVerificationError(cUnit, mir);
+      convertMonitorEnterExit(cUnit, optFlags,
+                              greenland::IntrinsicHelper::MonitorExit,
+                              rlSrc[0]);
       break;
 
     case Instruction::ARRAY_LENGTH:
-      int lenOffset;
-      lenOffset = Array::LengthOffset().Int32Value();
-      rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
-      genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
-      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-      loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
-      storeValue(cUnit, rlDest, rlResult);
+      convertArrayLength(cUnit, optFlags, rlSrc[0]);
+      break;
+
+    case Instruction::NEW_ARRAY:
+      convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
+      break;
+
+    case Instruction::INSTANCE_OF:
+      convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
+      break;
+
+    case Instruction::AGET:
+      if (rlDest.fp) {
+        convertAget(cUnit, optFlags,
+                    greenland::IntrinsicHelper::HLArrayGetFloat,
+                    rlDest, rlSrc[0], rlSrc[1]);
+      } else {
+        convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
+                    rlDest, rlSrc[0], rlSrc[1]);
+      }
+      break;
+    case Instruction::AGET_OBJECT:
+      convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
+                  rlDest, rlSrc[0], rlSrc[1]);
+      break;
+    case Instruction::AGET_BOOLEAN:
+      convertAget(cUnit, optFlags,
+                  greenland::IntrinsicHelper::HLArrayGetBoolean,
+                  rlDest, rlSrc[0], rlSrc[1]);
+      break;
+    case Instruction::AGET_BYTE:
+      convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
+                  rlDest, rlSrc[0], rlSrc[1]);
+      break;
+    case Instruction::AGET_CHAR:
+      convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
+                  rlDest, rlSrc[0], rlSrc[1]);
+      break;
+    case Instruction::AGET_SHORT:
+      convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
+                  rlDest, rlSrc[0], rlSrc[1]);
+      break;
+    case Instruction::AGET_WIDE:
+      if (rlDest.fp) {
+        convertAget(cUnit, optFlags,
+                    greenland::IntrinsicHelper::HLArrayGetDouble,
+                    rlDest, rlSrc[0], rlSrc[1]);
+      } else {
+        convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
+                    rlDest, rlSrc[0], rlSrc[1]);
+      }
+      break;
+
+    case Instruction::APUT:
+      if (rlSrc[0].fp) {
+        convertAput(cUnit, optFlags,
+                    greenland::IntrinsicHelper::HLArrayPutFloat,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      } else {
+        convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      }
+      break;
+    case Instruction::APUT_OBJECT:
+      convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      break;
+    case Instruction::APUT_BOOLEAN:
+      convertAput(cUnit, optFlags,
+                  greenland::IntrinsicHelper::HLArrayPutBoolean,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      break;
+    case Instruction::APUT_BYTE:
+      convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      break;
+    case Instruction::APUT_CHAR:
+      convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      break;
+    case Instruction::APUT_SHORT:
+      convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      break;
+    case Instruction::APUT_WIDE:
+      if (rlSrc[0].fp) {
+        convertAput(cUnit, optFlags,
+                    greenland::IntrinsicHelper::HLArrayPutDouble,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      } else {
+        convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
+                    rlSrc[0], rlSrc[1], rlSrc[2]);
+      }
+      break;
+
+#if 0
+
+    case Instruction::CHECK_CAST:
+      genCheckCast(cUnit, mir, rlSrc[0]);
       break;
 
     case Instruction::CONST_CLASS:
@@ -970,18 +1167,10 @@
       genFillArrayData(cUnit, mir, rlSrc[0]);
       break;
 
-    case Instruction::FILLED_NEW_ARRAY:
-      genFilledNewArray(cUnit, mir, false /* not range */);
-      break;
-
     case Instruction::FILLED_NEW_ARRAY_RANGE:
       genFilledNewArray(cUnit, mir, true /* range */);
       break;
 
-    case Instruction::NEW_ARRAY:
-      genNewArray(cUnit, mir, rlDest, rlSrc[0]);
-      break;
-
     case Instruction::PACKED_SWITCH:
       genPackedSwitch(cUnit, mir, rlSrc[0]);
       break;
@@ -1001,44 +1190,6 @@
       genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
-    case Instruction::AGET_WIDE:
-      genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
-      break;
-    case Instruction::AGET:
-    case Instruction::AGET_OBJECT:
-      genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
-      break;
-    case Instruction::AGET_BOOLEAN:
-      genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
-      break;
-    case Instruction::AGET_BYTE:
-      genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
-      break;
-    case Instruction::AGET_CHAR:
-      genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
-      break;
-    case Instruction::AGET_SHORT:
-      genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
-      break;
-    case Instruction::APUT_WIDE:
-      genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
-      break;
-    case Instruction::APUT:
-      genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
-      break;
-    case Instruction::APUT_OBJECT:
-      genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
-      break;
-    case Instruction::APUT_SHORT:
-    case Instruction::APUT_CHAR:
-      genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
-      break;
-    case Instruction::APUT_BYTE:
-    case Instruction::APUT_BOOLEAN:
-      genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
-            rlSrc[0], 0);
-      break;
-
     case Instruction::IGET_OBJECT:
     //case Instruction::IGET_OBJECT_VOLATILE:
       genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
@@ -1095,37 +1246,6 @@
       genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
       break;
 
-    case Instruction::SGET_OBJECT:
-      genSget(cUnit, mir, rlDest, false, true);
-      break;
-    case Instruction::SGET:
-    case Instruction::SGET_BOOLEAN:
-    case Instruction::SGET_BYTE:
-    case Instruction::SGET_CHAR:
-    case Instruction::SGET_SHORT:
-      genSget(cUnit, mir, rlDest, false, false);
-      break;
-
-    case Instruction::SGET_WIDE:
-      genSget(cUnit, mir, rlDest, true, false);
-      break;
-
-    case Instruction::SPUT_OBJECT:
-      genSput(cUnit, mir, rlSrc[0], false, true);
-      break;
-
-    case Instruction::SPUT:
-    case Instruction::SPUT_BOOLEAN:
-    case Instruction::SPUT_BYTE:
-    case Instruction::SPUT_CHAR:
-    case Instruction::SPUT_SHORT:
-      genSput(cUnit, mir, rlSrc[0], false, false);
-      break;
-
-    case Instruction::SPUT_WIDE:
-      genSput(cUnit, mir, rlSrc[0], true, false);
-      break;
-
     case Instruction::NEG_INT:
     case Instruction::NOT_INT:
       res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
@@ -1822,6 +1942,30 @@
   genNewInstance(cUnit, typeIdx, rlDest);
 }
 
+void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+  llvm::ConstantInt* typeIdxVal =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  uint32_t typeIdx = typeIdxVal->getZExtValue();
+  llvm::Value* len = callInst->getArgOperand(1);
+  RegLocation rlLen = getLoc(cUnit, len);
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  genNewArray(cUnit, typeIdx, rlDest, rlLen);
+}
+
+void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+  llvm::ConstantInt* typeIdxVal =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  uint32_t typeIdx = typeIdxVal->getZExtValue();
+  llvm::Value* src = callInst->getArgOperand(1);
+  RegLocation rlSrc = getLoc(cUnit, src);
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
+}
+
 void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
   DCHECK_EQ(callInst->getNumArgOperands(), 2U);
@@ -1840,6 +1984,37 @@
   genThrow(cUnit, rlSrc);
 }
 
+void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
+                         llvm::CallInst* callInst)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+  llvm::ConstantInt* optFlags =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  llvm::Value* src = callInst->getArgOperand(1);
+  RegLocation rlSrc = getLoc(cUnit, src);
+  if (isEnter) {
+    genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
+  } else {
+    genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
+  }
+}
+
+void cvtMonitorArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+  llvm::ConstantInt* optFlags =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  llvm::Value* src = callInst->getArgOperand(1);
+  RegLocation rlSrc = getLoc(cUnit, src);
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  int lenOffset = Array::LengthOffset().Int32Value();
+  loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
+  storeValue(cUnit, rlDest, rlResult);
+}
+
 void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
   DCHECK_EQ(callInst->getNumArgOperands(), 0U);
@@ -1870,12 +2045,50 @@
   genSget(cUnit, typeIdx, rlDest, isWide, isObject);
 }
 
+void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
+             bool isObject)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 2U);
+  llvm::ConstantInt* typeIdxVal =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  uint32_t typeIdx = typeIdxVal->getZExtValue();
+  llvm::Value* src = callInst->getArgOperand(1);
+  RegLocation rlSrc = getLoc(cUnit, src);
+  genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
+}
+
+void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
+             int scale)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 3U);
+  llvm::ConstantInt* optFlags =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
+  RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
+  RegLocation rlDest = getLoc(cUnit, callInst);
+  genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
+              rlDest, scale);
+}
+
+void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
+             int scale)
+{
+  DCHECK_EQ(callInst->getNumArgOperands(), 4U);
+  llvm::ConstantInt* optFlags =
+      llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
+  RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
+  RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
+  RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
+  genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
+              rlSrc, scale);
+}
+
 void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
-               greenland::JType jtype)
+               bool isVoid)
 {
   CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
                                          kAllocMisc);
-  if (jtype == greenland::kVoid) {
+  if (isVoid) {
     info->result.location = kLocInvalid;
   } else {
     info->result = getLoc(cUnit, callInst);
@@ -2061,14 +2274,15 @@
             case greenland::IntrinsicHelper::CheckSuspend:
               genSuspendTest(cUnit, 0 /* optFlags already applied */);
               break;
-            case greenland::IntrinsicHelper::HLInvokeInt:
-              cvtInvoke(cUnit, callInst, greenland::kInt);
-              break;
             case greenland::IntrinsicHelper::HLInvokeObj:
-              cvtInvoke(cUnit, callInst, greenland::kObject);
+            case greenland::IntrinsicHelper::HLInvokeFloat:
+            case greenland::IntrinsicHelper::HLInvokeDouble:
+            case greenland::IntrinsicHelper::HLInvokeLong:
+            case greenland::IntrinsicHelper::HLInvokeInt:
+              cvtInvoke(cUnit, callInst, false /* isVoid */);
               break;
             case greenland::IntrinsicHelper::HLInvokeVoid:
-              cvtInvoke(cUnit, callInst, greenland::kVoid);
+              cvtInvoke(cUnit, callInst, true /* isVoid */);
               break;
             case greenland::IntrinsicHelper::ConstString:
               cvtConstString(cUnit, callInst);
@@ -2076,9 +2290,21 @@
             case greenland::IntrinsicHelper::NewInstance:
               cvtNewInstance(cUnit, callInst);
               break;
-            case greenland::IntrinsicHelper::SgetObj:
+            case greenland::IntrinsicHelper::HLSgetObject:
               cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
               break;
+            case greenland::IntrinsicHelper::HLSget:
+            case greenland::IntrinsicHelper::HLSgetFloat:
+            case greenland::IntrinsicHelper::HLSgetBoolean:
+            case greenland::IntrinsicHelper::HLSgetByte:
+            case greenland::IntrinsicHelper::HLSgetChar:
+            case greenland::IntrinsicHelper::HLSgetShort:
+              cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
+              break;
+            case greenland::IntrinsicHelper::HLSgetWide:
+            case greenland::IntrinsicHelper::HLSgetDouble:
+              cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
+              break;
             case greenland::IntrinsicHelper::GetException:
               cvtMoveException(cUnit, callInst);
               break;
@@ -2086,8 +2312,68 @@
               cvtThrow(cUnit, callInst);
               break;
             case greenland::IntrinsicHelper::ThrowVerificationError:
-              cvtThrow(cUnit, callInst);
+              cvtThrowVerificationError(cUnit, callInst);
               break;
+            case greenland::IntrinsicHelper::MonitorEnter:
+              cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
+              break;
+            case greenland::IntrinsicHelper::MonitorExit:
+              cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
+              break;
+            case greenland::IntrinsicHelper::ArrayLength:
+              cvtMonitorArrayLength(cUnit, callInst);
+              break;
+            case greenland::IntrinsicHelper::NewArray:
+              cvtNewArray(cUnit, callInst);
+              break;
+            case greenland::IntrinsicHelper::InstanceOf:
+              cvtInstanceOf(cUnit, callInst);
+              break;
+
+            case greenland::IntrinsicHelper::HLArrayGet:
+            case greenland::IntrinsicHelper::HLArrayGetObject:
+            case greenland::IntrinsicHelper::HLArrayGetFloat:
+              cvtAget(cUnit, callInst, kWord, 2);
+              break;
+            case greenland::IntrinsicHelper::HLArrayGetWide:
+            case greenland::IntrinsicHelper::HLArrayGetDouble:
+              cvtAget(cUnit, callInst, kLong, 3);
+              break;
+            case greenland::IntrinsicHelper::HLArrayGetBoolean:
+              cvtAget(cUnit, callInst, kUnsignedByte, 0);
+              break;
+            case greenland::IntrinsicHelper::HLArrayGetByte:
+              cvtAget(cUnit, callInst, kSignedByte, 0);
+              break;
+            case greenland::IntrinsicHelper::HLArrayGetChar:
+              cvtAget(cUnit, callInst, kUnsignedHalf, 1);
+              break;
+            case greenland::IntrinsicHelper::HLArrayGetShort:
+              cvtAget(cUnit, callInst, kSignedHalf, 1);
+              break;
+
+            case greenland::IntrinsicHelper::HLArrayPut:
+            case greenland::IntrinsicHelper::HLArrayPutObject:
+            case greenland::IntrinsicHelper::HLArrayPutFloat:
+              cvtAput(cUnit, callInst, kWord, 2);
+              break;
+            case greenland::IntrinsicHelper::HLArrayPutWide:
+            case greenland::IntrinsicHelper::HLArrayPutDouble:
+              cvtAput(cUnit, callInst, kLong, 3);
+              break;
+            case greenland::IntrinsicHelper::HLArrayPutBoolean:
+              cvtAput(cUnit, callInst, kUnsignedByte, 0);
+              break;
+            case greenland::IntrinsicHelper::HLArrayPutByte:
+              cvtAput(cUnit, callInst, kSignedByte, 0);
+              break;
+            case greenland::IntrinsicHelper::HLArrayPutChar:
+              cvtAput(cUnit, callInst, kUnsignedHalf, 1);
+              break;
+            case greenland::IntrinsicHelper::HLArrayPutShort:
+              cvtAput(cUnit, callInst, kSignedHalf, 1);
+              break;
+
             case greenland::IntrinsicHelper::UnknownId:
               cvtCall(cUnit, callInst, callee);
               break;
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index e2a5557..5c8da89 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -141,7 +141,7 @@
                           _EXPAND_ARG1(kInt32ConstantTy))
 
 //----------------------------------------------------------------------------
-// New Instance
+// Instance
 //----------------------------------------------------------------------------
 
 // JavaObject* dex_lang_new_instance(uint32_t type_idx)
@@ -151,16 +151,23 @@
                           kJavaObjectTy,
                           _EXPAND_ARG1(kInt32Ty))
 
+// bool dex_lang_instance_of(uint32_t type_idx, JavaObject* ref)
+_EVAL_DEF_INTRINSICS_FUNC(InstanceOf,
+                          dex_lang_instance_of,
+                          kAttrNone,
+                          kInt1Ty,
+                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
+
 //----------------------------------------------------------------------------
 // Array
 //----------------------------------------------------------------------------
 
-// uint32_t dex_lang_array_length(JavaObject* array)
+// uint32_t dex_lang_array_length(int32_t opt_flags, JavaObject* array)
 _EVAL_DEF_INTRINSICS_FUNC(ArrayLength,
                           dex_lang_array_length,
                           kAttrReadOnly | kAttrNoThrow,
                           kInt32Ty,
-                          _EXPAND_ARG1(kJavaObjectTy))
+                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
 
 // JavaObject* dex_lang_new_array(uint32_t type_idx, uint32_t array_size)
 _EVAL_DEF_INTRINSICS_FUNC(NewArray,
@@ -474,6 +481,123 @@
                           _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
 
 //----------------------------------------------------------------------------
+// High-level Array get/put
+//
+// Similar to dex_lang_aget/aput_xxx, but checks not yet performed.
+// OptFlags contain info describing whether frontend has determined that
+// null check and/or array bounds check may be skipped.
+//
+// [type] void dex_lang_hl_aget_[type](int optFlags, JavaObject* array, uint32_t index)
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGet,
+                          dex_lang_hl_aget,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt32Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetFloat,
+                          dex_lang_hl_aget_float,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kFloatTy,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetWide,
+                          dex_lang_hl_aget_wide,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt64Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetDouble,
+                          dex_lang_hl_aget_double,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kDoubleTy,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetObject,
+                          dex_lang_hl_aget_object,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kJavaObjectTy,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetBoolean,
+                          dex_lang_hl_aget_boolean,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt1Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetByte,
+                          dex_lang_hl_aget_byte,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt8Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetChar,
+                          dex_lang_hl_aget_char,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt16Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetShort,
+                          dex_lang_hl_aget_short,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt16Ty,
+                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+// void dex_lang_aput_[type](int optFlags, [type] value, JavaObject* array, uint32_t index)
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPut,
+                          dex_lang_hl_aput,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutFloat,
+                          dex_lang_hl_aput_float,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kFloatTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutWide,
+                          dex_lang_hl_aput_wide,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt64Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutDouble,
+                          dex_lang_hl_aput_double,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kDoubleTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutObject,
+                          dex_lang_hl_aput_object,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kJavaObjectTy, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutBoolean,
+                          dex_lang_hl_aput_boolean,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt1Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutByte,
+                          dex_lang_hl_aput_byte,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt8Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutChar,
+                          dex_lang_hl_aput_char,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+
+_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutShort,
+                          dex_lang_hl_aput_short,
+                          kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG4(kInt32Ty, kInt16Ty, kJavaObjectTy, kInt32Ty))
+
+//----------------------------------------------------------------------------
 // High-level Invokes (fast-path determination not yet performed)
 //
 // NOTE: We expect these intrinsics to be temporary.  Once calling conventions are
@@ -644,18 +768,160 @@
                           kAttrNoThrow,
                           kVoidTy,
                           _EXPAND_ARG0())
+//----------------------------------------------------------------------------
+// sput intrinsics to assist MIR to Greenland_ir conversion.
+// "HL" versions - will be deprecated when fast/slow path handling done
+// in the common frontend.
+//----------------------------------------------------------------------------
+
+// void sput_hl(int field_idx, int val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSput,
+                          dex_lang_hl_sput,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
+
+// void sput_hl_object(int field_idx, object* val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputObject,
+                          dex_lang_hl_sput_object,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
+
+// void sput_hl_boolean(int field_idx, kInt1Ty)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputBoolean,
+                          dex_lang_hl_sput_boolean,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt1Ty))
+
+// void sput_hl_byte(int field_idx, int val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputByte,
+                          dex_lang_hl_sput_byte,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt8Ty))
+
+// void sput_hl_char(int field_idx, kInt16Ty val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputChar,
+                          dex_lang_hl_sput_char,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt16Ty))
+
+// void sput_hl_short(int field_idx, int val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputShort,
+                          dex_lang_hl_sput_short,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt16Ty))
+
+// void sput_hl_wide(int field_idx, long val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputWide,
+                          dex_lang_hl_sput_wide,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kInt64Ty))
+
+// void sput_hl_double(int field_idx, double val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputDouble,
+                          dex_lang_hl_sput_double,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kDoubleTy))
+
+// void sput_hl_float(int field_idx, float val)
+_EVAL_DEF_INTRINSICS_FUNC(HLSputFloat,
+                          dex_lang_hl_sput_float,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG2(kInt32Ty, kFloatTy))
 
 //----------------------------------------------------------------------------
 // sget intrinsics to assist MIR to Greenland_ir conversion.
+// "HL" versions - will be deprecated when fast/slow path handling done
+// in the common frontend.
 //----------------------------------------------------------------------------
 
-// object* sget_obj(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(SgetObj,
-                          dex_lang_sget_obj,
+// int sget_hl(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSget,
+                          dex_lang_hl_sget,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt32Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// object* sget_hl_object(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetObject,
+                          dex_lang_hl_sget_object,
                           kAttrReadOnly | kAttrNoThrow,
                           kJavaObjectTy,
                           _EXPAND_ARG1(kInt32Ty))
 
+// boolean sget_hl_boolean(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetBoolean,
+                          dex_lang_hl_sget_boolean,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt1Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// byte sget_hl_byte(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetByte,
+                          dex_lang_hl_sget_byte,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt8Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_char(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetChar,
+                          dex_lang_hl_sget_char,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt16Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_short(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetShort,
+                          dex_lang_hl_sget_short,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt16Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_wide(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetWide,
+                          dex_lang_hl_sget_wide,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kInt64Ty,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_double(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetDouble,
+                          dex_lang_hl_sget_double,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kDoubleTy,
+                          _EXPAND_ARG1(kInt32Ty))
+
+// char sget_hl_float(int field_idx)
+_EVAL_DEF_INTRINSICS_FUNC(HLSgetFloat,
+                          dex_lang_hl_sget_float,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kFloatTy,
+                          _EXPAND_ARG1(kInt32Ty))
+//----------------------------------------------------------------------------
+// Monitor enter/exit
+//----------------------------------------------------------------------------
+// uint32_t dex_lang_monitor_enter(JavaObject* obj)
+_EVAL_DEF_INTRINSICS_FUNC(MonitorEnter,
+                          dex_lang_monitor_enter,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG1(kJavaObjectTy))
+
+// uint32_t dex_lang_monitor_exit(JavaObject* obj)
+_EVAL_DEF_INTRINSICS_FUNC(MonitorExit,
+                          dex_lang_monitor_exit,
+                          kAttrReadOnly | kAttrNoThrow,
+                          kVoidTy,
+                          _EXPAND_ARG1(kJavaObjectTy))
+
 //----------------------------------------------------------------------------
 // Shadow Frame
 //----------------------------------------------------------------------------
diff --git a/test/028-array-write/src/Main.java b/test/028-array-write/src/Main.java
index 9e2826e..2618ff8 100644
--- a/test/028-array-write/src/Main.java
+++ b/test/028-array-write/src/Main.java
@@ -70,13 +70,16 @@
         report(start, end);
     }
 
+    public static void array_028() {
+        writeTest();
+        copyTest();
+        System.out.println("Done!");
+    }
+
     public static void main(String[] args) {
         if ((args.length >= 1) && args[0].equals("--timing")) {
             timing = true;
         }
-
-        writeTest();
-        copyTest();
-        System.out.println("Done!");
+        array_028();
     }
 }