Support for access check in checkcast and instanceof.

Change-Id: Ie15216618b35cace7d351be2b0a1c466ed6db489
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 4e3888d..e58a982 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -729,8 +729,14 @@
     loadValueDirectFixed(cUnit, rlSrc, r0);  // r0 <= ref
     int classReg = r2;  // r2 will hold the Class*
     if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
-        // Check we have access to type_idx and if not throw IllegalAccessError
-        UNIMPLEMENTED(FATAL);
+        // Check we have access to type_idx and if not throw IllegalAccessError,
+        // returns Class* in r0
+        loadWordDisp(cUnit, rSELF,
+                     OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
+                     rLR);
+        loadConstant(cUnit, r0, type_idx);
+        callRuntimeHelper(cUnit, rLR);  // InitializeTypeAndVerifyAccess(idx, method)
+        genRegCopy(cUnit, classReg, r0);  // Align usage with fast path
     } else {
         // Load dex cache entry into classReg (r2)
         loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
@@ -743,7 +749,7 @@
             // Call out to helper, which will return resolved type in r0
             loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
             loadConstant(cUnit, r0, type_idx);
-            callRuntimeHelper(cUnit, rLR);  // resolveTypeFromCode(idx, method)
+            callRuntimeHelper(cUnit, rLR);  // InitializeTypeFromCode(idx, method)
             genRegCopy(cUnit, r2, r0); // Align usage with fast path
             loadValueDirectFixed(cUnit, rlSrc, r0);  /* reload Ref */
             // Rejoin code paths
@@ -784,8 +790,14 @@
     loadCurrMethodDirect(cUnit, r1);  // r1 <= current Method*
     int classReg = r2;  // r2 will hold the Class*
     if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
-        // Check we have access to type_idx and if not throw IllegalAccessError
-        UNIMPLEMENTED(FATAL);
+        // Check we have access to type_idx and if not throw IllegalAccessError,
+        // returns Class* in r0
+        loadWordDisp(cUnit, rSELF,
+                     OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
+                     rLR);
+        loadConstant(cUnit, r0, type_idx);
+        callRuntimeHelper(cUnit, rLR);  // InitializeTypeAndVerifyAccess(idx, method)
+        genRegCopy(cUnit, classReg, r0);  // Align usage with fast path
     } else {
         // Load dex cache entry into classReg (r2)
         loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
@@ -798,8 +810,8 @@
             // Call out to helper, which will return resolved type in r0
             loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
             loadConstant(cUnit, r0, type_idx);
-            callRuntimeHelper(cUnit, rLR);  // resolveTypeFromCode(idx, method)
-            genRegCopy(cUnit, r2, r0); // Align usage with fast path
+            callRuntimeHelper(cUnit, rLR);  // InitializeTypeFromCode(idx, method)
+            genRegCopy(cUnit, classReg, r0); // Align usage with fast path
             // Rejoin code paths
             ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
             hopTarget->defMask = ENCODE_ALL;
@@ -815,7 +827,7 @@
     loadWordDisp(cUnit, r0,  Object::ClassOffset().Int32Value(), r1);
     /* r1 now contains object->clazz */
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pCheckCastFromCode), rLR);
-    opRegReg(cUnit, kOpCmp, r1, r2);
+    opRegReg(cUnit, kOpCmp, r1, classReg);
     ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); /* If equal, trivial yes */
     genRegCopy(cUnit, r0, r1);
     genRegCopy(cUnit, r1, r2);