Various bug fixes and new tests.

Amusingly realized that many tests believed to be passing were in fact not
running at all.  The test harness returned 0 if the test wasn't run, but some
of the tests used 0 as a success code.  Will change the tests later.

Most were failing only because the function pointer table in Thread wasn't
fully initialized with the math helper functions.

Change-Id: If2e42f06139f219a423eef475b599258ccfc82d4
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 26e4891..cab1572 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -55,6 +55,7 @@
 	src/compiler/codegen/arm/Assemble.cc \
 	src/compiler/codegen/arm/LocalOptimizations.cc \
 	src/compiler/codegen/arm/armv7-a/Codegen.cc \
+	src/compiler/RuntimeUtilities.cc \
 	src/dex_cache.cc \
 	src/dex_file.cc \
 	src/dex_instruction.cc \
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 1775375..272cb08 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -700,13 +700,7 @@
     if (!method->IsStatic() ||
         (method->GetName()->ToModifiedUtf8().find("foo") != std::string::npos) ||
         (method->GetName()->ToModifiedUtf8().find("init>") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("intOperTest") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("intShiftTest") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("lit16Test") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("lit8Test") != std::string::npos) ||
         (method->GetName()->ToModifiedUtf8().find("longOperTest") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("longShiftTest") != std::string::npos) ||
-        (method->GetName()->ToModifiedUtf8().find("shiftTest1") != std::string::npos) ||
         (method->GetName()->ToModifiedUtf8().find("main") != std::string::npos)) {
         LOG(INFO) << "not compiling " << PrettyMethod(method, true);
         return false;
diff --git a/src/compiler/RuntimeUtilities.cc b/src/compiler/RuntimeUtilities.cc
index d40f097..b18e4da 100644
--- a/src/compiler/RuntimeUtilities.cc
+++ b/src/compiler/RuntimeUtilities.cc
@@ -23,7 +23,7 @@
  * Float/double conversion requires clamping to min and max of integer form.  If
  * target doesn't support this normally, use these.
  */
-s8 artD2L(double d)
+int64_t artD2L(double d)
 {
     static const double kMaxLong = (double)(s8)0x7fffffffffffffffULL;
     static const double kMinLong = (double)(s8)0x8000000000000000ULL;
@@ -37,7 +37,7 @@
         return (s8)d;
 }
 
-s8 artF2L(float f)
+int64_t artF2L(float f)
 {
     static const float kMaxLong = (float)(s8)0x7fffffffffffffffULL;
     static const float kMinLong = (float)(s8)0x8000000000000000ULL;
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index bf87c1e..cf606a3 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -53,6 +53,8 @@
                              int dOffset, TGT_LIR* pcrLabel)
 {
     /* This particular Dalvik register has been null-checked */
+    UNIMPLEMENTED(WARNING) << "Need null check & throw support";
+    return pcrLabel;
     if (oatIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
         return pcrLabel;
     }
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index 19b9445..d9dd8c4 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -1194,13 +1194,18 @@
         } else if (lir->opcode == kThumbBCond ||
                    lir->opcode == kThumb2BCond) {
             ArmLIR *targetLIR = (ArmLIR *) lir->generic.target;
-            intptr_t pc = lir->generic.offset + 4;
-            intptr_t target = targetLIR->generic.offset;
-            int delta = target - pc;
-            if ((lir->opcode == kThumbBCond) && (delta > 254 || delta < -256)) {
-                lir->opcode = kThumb2BCond;
-                oatSetupResourceMasks(lir);
-                res = kRetryAll;
+            int delta = 0;
+            if (targetLIR == NULL) {
+                UNIMPLEMENTED(WARNING) << "Throw targets unimplemented";
+            } else {
+                intptr_t pc = lir->generic.offset + 4;
+                intptr_t target = targetLIR->generic.offset;
+                delta = target - pc;
+                if ((lir->opcode == kThumbBCond) && (delta > 254 || delta < -256)) {
+                    lir->opcode = kThumb2BCond;
+                    oatSetupResourceMasks(lir);
+                    res = kRetryAll;
+                }
             }
             lir->operands[0] = delta >> 1;
         } else if (lir->opcode == kThumb2BUncond) {
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 6e2f285..f7194f1 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -428,6 +428,66 @@
     return state + 1;
 }
 
+// Slow path sequence for virtual calls
+static int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir,
+                           DecodedInstruction* dInsn, int state)
+{
+    RegLocation rlArg;
+    switch(state) {
+        case 0:  // Get the current Method* [sets r0]
+            loadBaseDisp(cUnit, mir, rSP, 0, r0, kWord, INVALID_SREG);
+            break;
+        case 1:  // Get the current Method->DeclaringClass() [uses/sets r0]
+            loadBaseDisp(cUnit, mir, r0,
+                         OFFSETOF_MEMBER(art::Method, declaring_class_),
+                         r0, kWord, INVALID_SREG);
+            break;
+        case 2:  // Method->DeclaringClass()->GetDexCache() [uses/sets r0]
+            loadBaseDisp(cUnit, mir, r0,
+                         OFFSETOF_MEMBER(art::Class, dex_cache_), r0, kWord,
+                         INVALID_SREG);
+            break;
+        case 3:  // ...()->GetDexCache()->methodsObjectArr [uses/sets r0]
+            loadBaseDisp(cUnit, mir, r0,
+                         art::DexCache::MethodsOffset().Int32Value(), r0,
+                         kWord, INVALID_SREG);
+            // Load "this" [set r1]
+            rlArg = oatGetSrc(cUnit, mir, 0);
+            loadValueDirectFixed(cUnit, rlArg, r1);
+            // Skip past the object header
+            opRegImm(cUnit, kOpAdd, r0, art::Array::DataOffset().Int32Value());
+            break;
+        case 4:
+            // Is "this" null? [use r1]
+            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir->offset, NULL);
+            // get this->clazz [use r1, set rLR]
+            loadBaseDisp(cUnit, mir, r1, OFFSETOF_MEMBER(Object, klass_), rLR,
+                         kWord, INVALID_SREG);
+            // Get the base Method* [uses r0, sets r0]
+            loadBaseDisp(cUnit, mir, r0, dInsn->vB * 4, r0,
+                         kWord, INVALID_SREG);
+            // get this->clazz->vtable [use rLR, set rLR]
+            loadBaseDisp(cUnit, mir, rLR,
+                         OFFSETOF_MEMBER(Class, vtable_), rLR, kWord,
+                         INVALID_SREG);
+            // Get the method index [use r0, set r12]
+            loadBaseDisp(cUnit, mir, r0, OFFSETOF_MEMBER(Method, method_index_),
+                         r12, kUnsignedHalf, INVALID_SREG);
+            // Skip past the object header
+            opRegImm(cUnit, kOpAdd, rLR, art::Array::DataOffset().Int32Value());
+            // Get target Method*
+            loadBaseIndexed(cUnit, rLR, r12, r0, 2, kWord);
+            break;
+        case 5: // Get the target compiled code address [uses r0, sets rLR]
+            loadBaseDisp(cUnit, mir, r0, art::Method::GetCodeOffset(), rLR,
+                         kWord, INVALID_SREG);
+            break;
+        default:
+            return -1;
+    }
+    return state + 1;
+}
+
 /* Load up to 3 arguments in r1..r3 */
 static int loadArgRegs(CompilationUnit* cUnit, MIR* mir,
                        DecodedInstruction* dInsn, int callState,
@@ -702,12 +762,6 @@
 {
     DecodedInstruction* dInsn = &mir->dalvikInsn;
     int callState = 0;
-    /*
-     * TODO: check for/force resolution of target method
-     * note to bdc: you can find the method index in
-     * dInsn->vB.  If you need it, the calling method's
-     * Method* is cUnit->method.
-     */
     int fastPath = false;  // TODO: set based on resolution results
 
     NextCallInsn nextCallInsn = fastPath ? nextSDCallInsn : nextSDCallInsnSP;
@@ -731,15 +785,18 @@
     DecodedInstruction* dInsn = &mir->dalvikInsn;
     int callState = 0;
     ArmLIR* nullCk;
+    int fastPath = false;  // TODO: set based on resolution results
+
+    NextCallInsn nextCallInsn = fastPath ? nextSDCallInsn : nextSDCallInsnSP;
     if (mir->dalvikInsn.opcode == OP_INVOKE_DIRECT)
         callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, &nullCk,
-                                         false, nextSDCallInsn);
+                                         false, nextCallInsn);
     else
         callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, &nullCk,
-                                       nextSDCallInsn);
+                                       nextCallInsn);
     // Finish up any of the call sequence not interleaved in arg loading
     while (callState >= 0) {
-        callState = nextSDCallInsn(cUnit, mir, dInsn, callState);
+        callState = nextCallInsn(cUnit, mir, dInsn, callState);
     }
     newLIR1(cUnit, kThumbBlxR, rLR);
 }
@@ -788,16 +845,19 @@
     DecodedInstruction* dInsn = &mir->dalvikInsn;
     int callState = 0;
     ArmLIR* nullCk;
-// FIXME - redundantly loading arg0/r1 ("this")
+    int fastPath = false;  // TODO: set based on resolution results
+
+    NextCallInsn nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
+    // TODO - redundantly loading arg0/r1 ("this")
     if (mir->dalvikInsn.opcode == OP_INVOKE_VIRTUAL)
         callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, &nullCk,
-                                         false, nextVCallInsn);
+                                         false, nextCallInsn);
     else
         callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, &nullCk,
-                                       nextVCallInsn);
+                                       nextCallInsn);
     // Finish up any of the call sequence not interleaved in arg loading
     while (callState >= 0) {
-        callState = nextVCallInsn(cUnit, mir, dInsn, callState);
+        callState = nextCallInsn(cUnit, mir, dInsn, callState);
     }
     newLIR1(cUnit, kThumbBlxR, rLR);
 }
@@ -956,7 +1016,7 @@
             rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
             loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
                                   0, mir->dalvikInsn.vB << 16);
-            storeValue(cUnit, rlDest, rlResult);
+            storeValueWide(cUnit, rlDest, rlResult);
             break;
 
         case OP_MONITOR_ENTER:
@@ -986,6 +1046,7 @@
         case OP_ARRAY_LENGTH:
             int lenOffset;
             lenOffset = Array::LengthOffset().Int32Value();
+            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
             genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg,
                          mir->offset, NULL);
             rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index e06910d..2239bd9 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -1358,6 +1358,11 @@
     oatFlushAllRegs(cUnit);   /* Send everything to home location */
     loadWordDisp(cUnit, rSELF, funcOffset, rLR);
     loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+    if (rlShift.wide) {
+        LOG(WARNING) << "Invalid RegLocation size - dataflow problem";
+        LOG(WARNING) << "   sReg[" << rlShift.sRegLow << "]";
+        rlShift.wide = false;
+    }
     loadValueDirect(cUnit, rlShift, r2);
     opReg(cUnit, kOpBlx, rLR);
     oatClobberCallRegs(cUnit);
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index cab932f..186e4c4 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -120,10 +120,12 @@
                         38);
 }
 
+#if 0 // Needs artFillArrayDataNoThrow() helper function
 TEST_F(CompilerTest, ShiftTest1) {
   CompileDex(kIntMathDex, "kIntMathDex");
   AssertStaticIntMethod("IntMath", "shiftTest1", "()I", 0);
 }
+#endif
 
 TEST_F(CompilerTest, ShiftTest2) {
   CompileDex(kIntMathDex, "kIntMathDex");
@@ -177,8 +179,8 @@
 
 TEST_F(CompilerTest, LongShiftTest) {
   CompileDex(kIntMathDex, "kIntMathDex");
-  AssertStaticLongMethod("IntMath", "longShiftTest", "(JI)J", 0,
-                         0xd5aa96deff00aa01LL, 8);
+  AssertStaticLongMethod("IntMath", "longShiftTest", "(JI)J",
+                         0x96deff00aa010000LL, 0xd5aa96deff00aa01LL, 16);
 }
 
 TEST_F(CompilerTest, SwitchTest1) {
@@ -199,7 +201,7 @@
                         -5LL, -4294967287LL, 4LL, 8LL);
 }
 
-#if 0
+#if 0 // Weird NaN failure.  Needs investigation
 TEST_F(CompilerTest, FloatCompare) {
   CompileDex(kIntMathDex, "kIntMathDex");
   AssertStaticIntMethod("IntMath", "testFloatCompare", "(FFFF)I", 3333
@@ -221,4 +223,28 @@
                         10);
 }
 
+#if 0 // Need to complete try/catch block handling
+TEST_F(CompilerTest, ThrowAndCatch) {
+  CompileDex(kIntMathDex, "kIntMathDex");
+  AssertStaticIntMethod("IntMath", "throwAndCatch", "()I", 4);
+}
+#endif
+
+TEST_F(CompilerTest, ManyArgs) {
+  CompileDex(kIntMathDex, "kIntMathDex");
+  AssertStaticIntMethod("IntMath", "manyArgs",
+                        "(IJIJIJIIDFDSICIIBZIIJJIIIII)I", -1,
+                        0, 1LL, 2, 3LL, 4, 5LL, 6, 7, 8.0, 9.0f, 10.0,
+                        (short)11, 12, (char)13, 14, 15, (int8_t)-16, true, 18,
+                        19, 20LL, 21LL, 22, 23, 24, 25, 26);
+}
+
+#if 0 // White-list needs some work, must allow some virtual methods through
+TEST_F(CompilerTest, VirtualCall) {
+  CompileDex(kIntMathDex, "kIntMathDex");
+  AssertStaticIntMethod("IntMath", "staticCall", "(I)I", 6,
+                        3);
+}
+#endif
+
 }  // namespace art
diff --git a/src/compiler_test.h b/src/compiler_test.h
index 57a08e1..d8eaf02 100644
--- a/src/compiler_test.h
+++ b/src/compiler_test.h
@@ -290,7 +290,7 @@
 //    }
 //
 //    /*
-//     * Shift some data.  (value=0xd5aa96deff00aa01, dist=8)
+//     * Shift some data.  (value=0xd5aa96deff00aa01, dist=16)
 //     */
 //    static long longShiftTest(long value, int dist) {
 //        long results[] = new long[4];
@@ -298,10 +298,10 @@
 //        results[1] = value >> dist;
 //        results[2] = value >>> dist;
 //        results[3] = (((value << dist) >> dist) >>> dist) << dist;
-//        if (results[0] != 0x96deff00aa010000L) { return 1; }
-//        if (results[1] != 0xffffd5aa96deff00L) { return 2; }
-//        if (results[2] != 0x0000d5aa96deff00L) { return 3; }
-//        if (results[3] != 0xffff96deff000000L) { return 4; }
+//        if (results[0] != 0x96deff00aa010000L) { return results[0]; }
+//        if (results[1] != 0xffffd5aa96deff00L) { return results[1]; }
+//        if (results[2] != 0x0000d5aa96deff00L) { return results[2]; }
+//        if (results[3] != 0xffff96deff000000L) { return results[3]; }
 //        if (results.length != 4) { return 5; }
 //
 //        return results[0];      // test return-long
@@ -531,6 +531,68 @@
 //        }
 //    }
 //
+///*
+//    static void throwNullPointerException() {
+//        throw new NullPointerException("first throw");
+//    }
+//
+//    static int throwAndCatch() {
+//        try {
+//            throwNullPointerException();
+//            return 1;
+//        } catch (NullPointerException npe) {
+//            return 0;
+//        }
+//    }
+//*/
+//
+//    static int manyArgs(int a0, long a1, int a2, long a3, int a4, long a5,
+//        int a6, int a7, double a8, float a9, double a10, short a11, int a12,
+//        char a13, int a14, int a15, byte a16, boolean a17, int a18, int a19,
+//        long a20, long a21, int a22, int a23, int a24, int a25, int a26)
+//    {
+//        if (a0 != 0) return 0;
+//        if (a1 !=  1L) return 1;
+//        if (a2 != 2) return 2;
+//        if (a3 != 3L) return 3;
+//        if (a4 != 4) return 4;
+//        if (a5 != 5L) return 5;
+//        if (a6 != 6) return 6;
+//        if (a7 != 7) return 7;
+//        if (a8 != 8.0) return 8;
+//        if (a9 !=  9.0f) return 9;
+//        if (a10 != 10.0) return 10;
+//        if (a11 != (short)11) return 11;
+//        if (a12 != 12) return 12;
+//        if (a13 != (char)13) return 13;
+//        if (a14 != 14) return 14;
+//        if (a15 != 15) return 15;
+//        if (a16 != (byte)-16) return 16;
+//        if (a17 !=  true) return 17;
+//        if (a18 != 18) return 18;
+//        if (a19 != 19) return 19;
+//        if (a20 !=  20L) return 20;
+//        if (a21 != 21L) return 21;
+//        if (a22 != 22) return 22;
+//        if (a23 != 23) return 23;
+//        if (a24 != 24) return 24;
+//        if (a25 != 25) return 25;
+//        if (a26 != 26) return 26;
+//        return -1;
+//    }
+//
+//    int virtualCall(int a)
+//    {
+//        return a * 2;
+//    }
+//
+//    static int staticCall(int a)
+//    {
+//        IntMath foo = new IntMath();
+//        return foo.virtualCall(a);
+//    }
+//
+//
 //    public static void main(String[] args) {
 //        int res = unopTest(38);
 //        if (res == 37) {
@@ -628,144 +690,214 @@
 //        } else {
 //            System.out.printf("fibonacci FAILED: %d\n", res);
 //        }
+//
+///*
+//        res = throwAndCatch();
+//        if (res == 0) {
+//            System.out.printf("throwAndCatch PASSED\n");
+//        } else {
+//            System.out.printf("throwAndCatch FAILED: %d\n", res);
+//        }
+//*/
+//
+//        res = manyArgs(0, 1L, 2, 3L, 4, 5L, 6, 7, 8.0, 9.0f, 10.0,
+//                      (short)11, 12, (char)13, 14, 15, (byte)-16, true, 18,
+//                      19, 20L, 21L, 22, 23, 24, 25, 26);
+//        if (res == -1) {
+//            System.out.printf("manyArgs PASSED\n");
+//        } else {
+//            System.out.printf("manyArgs FAILED: %d\n", res);
+//        }
+//
+//        res = staticCall(3);
+//        if (res == 6) {
+//            System.out.printf("virtualCall PASSED\n");
+//        } else {
+//            System.out.printf("virtualCall FAILED: %d\n", res);
+//        }
+//
 //    }
 //}
 static const char kIntMathDex[] =
-"ZGV4CjAzNQDkd6TZ8pqDxU8AeTvdZuEG1XSONR7DLLU8HgAAcAAAAHhWNBIAAAAAAAAAAJwdAABR"
-"AAAAcAAAAA8AAAC0AQAADQAAAPABAAABAAAAjAIAABcAAACUAgAAAgAAAEwDAACwGgAAjAMAAPIV"
-"AAD6FQAA/RUAAAAWAAADFgAAChYAABEWAAAVFgAAGhYAACEWAAAmFgAALRYAADsWAAA+FgAAQxYA"
-"AEcWAABSFgAAVxYAAG4WAACDFgAAlxYAAKsWAAC/FgAAzBYAAM8WAADTFgAA1xYAANsWAADwFgAA"
-"BRcAABIXAAArFwAAQBcAAEoXAABgFwAAchcAAH0XAACUFwAApxcAALQXAADNFwAA4hcAAPAXAAD7"
-"FwAABRgAABMYAAAtGAAAQxgAAFIYAABtGAAAhBgAAIoYAACPGAAAlxgAAKMYAAC7GAAAzxgAANsY"
-"AADzGAAABxkAABMZAAArGQAAPxkAAFIZAABxGQAAjBkAAJ4ZAAC8GQAA1hkAAOYZAAACGgAAGhoA"
-"ACsaAABIGgAAYRoAAGsaAACBGgAAkxoAAKYaAADFGgAA4BoAAAEAAAACAAAAAwAAAAwAAAAPAAAA"
-"EQAAABIAAAATAAAAFAAAABUAAAAXAAAAGQAAABoAAAAbAAAAHAAAAAMAAAACAAAAAAAAAAQAAAAC"
-"AAAAlBUAAAUAAAACAAAAoBUAAAYAAAACAAAArBUAAAcAAAACAAAAtBUAAAgAAAACAAAAvBUAAAkA"
-"AAACAAAAyBUAAAoAAAACAAAA0BUAAA0AAAADAAAA3BUAABAAAAAFAAAA5BUAAA4AAAAGAAAArBUA"
-"ABcAAAAKAAAAAAAAABgAAAAKAAAA7BUAAAkABQAzAAAABAALAAAAAAAEAAAAHQAAAAQAAAAgAAAA"
-"BAADACMAAAAEAAQAJgAAAAQABAApAAAABAADACoAAAAEAAMAKwAAAAQABgAsAAAABAAIAC8AAAAE"
-"AAwAMgAAAAQAAAA1AAAABAAAADgAAAAEAAMAOwAAAAQAAQA+AAAABAACAEEAAAAEAAUARAAAAAQA"
-"BwBHAAAABAADAEoAAAAEAAAATQAAAAUACQA0AAAABgAKAFAAAAAHAAsAAAAAAAcAAAABAAAA////"
-"/wAAAAAWAAAAAAAAADkdAAAAAAAABAAAAAAAAAAHAAAAAAAAAAsAAAAAAAAAQx0AAAAAAAABAAEA"
-"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"
-"EwAIACjjEwAJACjgEwAKACjdEwALACjaEwAMACjXEwANACjULAJOAAAAErAsAFQAAAATABMAKMoT"
-"AA8AKMcTABAAKMQTABEAKMETABIAKL4BECi8AAEGAP////8EAAAABQAAAA0AAAAHAAAACQAAAAsA"
-"AAAAAQIAAwAAABAAAAASAAAAAAECAHhWNBIEAAAADwAAAAACBQD6////AwAAABYAAAA5AAAAeFY0"
-"EhEAAAAXAAAAFAAAAA4AAAAaAAAAAAICAPr///8DAAAACgAAAA0AAAAAAgMA+////wAAAAAMAAAA"
-"EgAAAA8AAAAMAAAACgAIAAAAAACLHAAASAAAABMAXBEvAQIEPQEEABIQDwAwAQQCOwEEABIgKPov"
+"ZGV4CjAzNQAeDs8/iIoiUVFtgM49kDyM3iE5XGier2cYKAAAcAAAAHhWNBIAAAAAAAAAAHgnAACf"
+"AAAAcAAAABMAAADsAgAADgAAADgDAAABAAAA4AMAABoAAADoAwAAAgAAALgEAAAgIwAA+AQAAL4b"
+"AADGGwAAyRsAAMwbAADPGwAA0hsAANUbAADcGwAA4xsAAOcbAADsGwAA8xsAABEcAAAWHAAAHRwA"
+"ACscAAAuHAAAMxwAADccAABCHAAARxwAAF4cAABzHAAAhxwAAJscAACvHAAAvBwAAL8cAADCHAAA"
+"xhwAAMkcAADNHAAA0RwAAOYcAAD7HAAA/hwAAAIdAAAGHQAACx0AABAdAAAVHQAAGh0AAB8dAAAk"
+"HQAAKR0AAC4dAAAzHQAAOB0AADwdAABBHQAARh0AAEsdAABQHQAAVR0AAFodAABfHQAAYx0AAGcd"
+"AABrHQAAbx0AAHMdAAB3HQAAex0AAIYdAACQHQAAlh0AAJkdAACcHQAAox0AAKodAAC3HQAA0B0A"
+"AOUdAADvHQAABR4AABceAAAaHgAAIB4AACMeAAAmHgAAMR4AAEgeAABbHgAAYB4AAGMeAABmHgAA"
+"aR4AAG0eAABxHgAAfh4AAJceAACsHgAAuh4AAL0eAADIHgAA0h4AAOAeAAD6HgAAEB8AAB8fAAA6"
+"HwAAUR8AAFcfAABfHwAAZR8AAG8fAACFHwAAlx8AAJ8fAACoHwAArx8AALIfAAC3HwAAvx8AAMQf"
+"AADKHwAA0R8AANofAADiHwAA5x8AAO8fAAD4HwAA+x8AAAcgAAAfIAAAMyAAAD8gAABXIAAAayAA"
+"AHcgAACDIAAAmyAAAK8gAADCIAAA4SAAAPwgAAAOIQAALCEAAEYhAABWIQAAciEAAIohAACbIQAA"
+"uCEAANEhAADXIQAA4SEAAPchAAAJIgAAHCIAADsiAABWIgAAXSIAAGYiAABzIgAAjCIAAKEiAACk"
+"IgAApyIAAAEAAAACAAAAAwAAAAQAAAAFAAAADwAAABIAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoA"
+"AAAbAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAFAAAABAAAAAAAAAAGAAAABAAAACQbAAAHAAAABAAA"
+"ADAbAAAIAAAABAAAADwbAAAJAAAABAAAAEQbAAAKAAAABAAAAEwbAAALAAAABAAAAFgbAAAMAAAA"
+"BAAAAJQbAAANAAAABAAAAJwbAAAQAAAABQAAAKgbAAATAAAABwAAALAbAAARAAAACAAAADwbAAAb"
+"AAAADQAAAAAAAAAcAAAADQAAALgbAAALAAcAcQAAAAYADAAAAAAABgAAAEUAAAAGAAAASAAAAAYA"
+"AwBPAAAABgAEAFgAAAAGAAQAWwAAAAYAAwBdAAAABgADAF4AAAAGAAcAXwAAAAYACQBiAAAABgAN"
+"AGcAAAAGAAYAaAAAAAYAAAB6AAAABgAAAH0AAAAGAAMAgAAAAAYAAwCBAAAABgABAIQAAAAGAAIA"
+"hwAAAAYABQCKAAAABgAIAI0AAAAGAAMAkQAAAAYAAACUAAAABgADAJkAAAAHAAoAdQAAAAgACwCY"
+"AAAACQAMAAAAAAAJAAAAAQAAAP////8AAAAAGQAAAAAAAAALJwAAAAAAAAYAAAAAAAAACQAAAAAA"
+"AAAOAAAAAAAAABUnAAAAAAAAAQABAAAAAACtIgAAAQAAAA4AAAABAAEAAQAAALIiAAAEAAAAcBAZ"
+"AAAADgAEAAAAAAAAALciAAAQAAAAEwDpABQB//8AAJECAAEUA+oA//8yMgQAEhMPAxIDKP4FAAAA"
+"AAAAAMwiAAAyAAAAEwDmHYEBFgPmHTEDAQM4AwQAEhMPAxMAGuKBARYDGuIxAwEDOAMEABIjKPUY"
+"AfUAflIBAAAAhBAUA/UAflIyMAQAEjMo6BgBC/+Brf7///+EEBQDC/+BrTIwBAASQyjbEgMo2QMA"
+"AQABAAAA6iIAABUAAAASEDkCBAASAA8AMgL//9gAAv9xEAMAAAAKANgBAv5xEAMAAQAKAbAQKPAA"
+"AA4AAgAAAAAA9SIAALAAAAASNxImEgkSWBIVEwoKACOkDwCQCgwNSwoECZEKDA1LCgQFkgoMDUsK"
+"BAaSCgwMSwoEBxJKkwsMDUsLBAp72pQKDApLCgQIEmqVCwwNSwsEChJ6lgsMDUsLBAoTCggAlwsM"
+"DUsLBAoTCgkAkAsMDbHbstuz27Tbtdu227fbsMtLCwQKFQAAgEQKBAh7oRISFQoAgLMakwMKATID"
+"AwAPBUQKBAkUC20RAQAyugQAAWUo90QKBAUUC3MRAQAyugQAAXUo7kQGBAYUCrDL/P8ypgQAEkUo"
+"5UQGBAcUBwARECQydgQAAYUo3BJGRAYEBhMH26QydgQAEmUo00QGBAgyVgQAEnUozRJlRAUEBRQG"
+"cBEBADJlBQATBQgAKMISdUQFBAUS1jJlBQATBQkAKLkTBQgARAUEBRQGje7+/zJlBQATBQoAKK0T"
+"BQkARAUEBRQGcBEBADJlBQATBQsAKKEBlSifCgACAAAAAAAxIwAAPwAAABJEEjMSIhIREgUjQA8A"
+"mAYICUsGAAWZBggJSwYAAZoGCAlLBgACmAYICbmWupa4lksGAANEBgAFFAcAAaoAMnYDAA8BRAEA"
+"ARQGqgD//zJhBAABISj3RAEAAhQCqgD/ADIhBAABMSjuRAEAAxQCAKoAADIhBAABQSjlAVEo4wAA"
+"CQABAAAAAABIIwAAdQAAABJEEjMSIhIREgUTBggAI2APANCG6ANLBgAF0YboA0sGAAHShugDSwYA"
+"AtOG6ANLBgAD1IboA0sGAAQSVtWH6ANLBwAGEmbWhxj8SwcABhJ214cY/EsHAAZEBgAFFAe5MwEA"
+"MnYDAA8BRAEAARQGF9T+/zJhBAABISj3RAEAAhQCaMiiBDIhBAABMSjuRAEAAxMCTQAyIQQAAUEo"
+"5kQBAAQTAgkDMiEEABJRKN4SUUQBAAETAsADMiEEABJhKNUSYUQBAAETAtn/MiEEABJxKMwScUQB"
+"AAEUAsnT/v8yIQUAEwEIACjBAVEovwAACwABAAAAAABoIwAAfAAAABJGEjUSJBITEgcTCAgAI4IP"
+"ANgICgpLCAIH2QgKCksIAgPaCAoKSwgCBNsICgpLCAIF3AgKCksIAgYSWN0JCgpLCQIIEmjeCQr2"
+"SwkCCBJ43wkK9ksJAggVAACA2wEA/zIBAwAPA0QIAgcUCQcn//8ymAQAAUMo90QDAgMUCA3ZAAAy"
+"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"
-"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"
+"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"
-"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"
-"AAADAAMAAwADAAIAAAADAAIAAgAAAAgADQABAAAADgAGPGluaXQ+AAFEAAFGAAFJAAVJRERERAAF"
-"SUZGRkYAAklJAANJSUkABUlJSUlJAANJSkoABUlKSkpKAAxJbnRNYXRoLmphdmEAAUoAA0pKSQAC"
-"TEkACUxJbnRNYXRoOwADTExMABVMamF2YS9pby9QcmludFN0cmVhbTsAE0xqYXZhL2xhbmcvSW50"
-"ZWdlcjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5n"
-"L1N5c3RlbTsAC09iamVjdC5qYXZhAAFWAAJWTAACW0kAAltKABNbTGphdmEvbGFuZy9PYmplY3Q7"
-"ABNbTGphdmEvbGFuZy9TdHJpbmc7AAtjaGFyU3ViVGVzdAAXY2hhclN1YlRlc3QgRkFJTEVEOiAl"
-"ZAoAE2NoYXJTdWJUZXN0IFBBU1NFRAoACGNvbnZUZXN0ABRjb252VGVzdCBGQUlMRUQ6ICVkCgAQ"
-"Y29udlRlc3QgUEFTU0VECgAJZmlib25hY2NpABVmaWJvbmFjY2kgRkFJTEVEOiAlZAoAEWZpYm9u"
-"YWNjaSBQQVNTRUQKAAtpbnRPcGVyVGVzdAAXaW50T3BlclRlc3QgRkFJTEVEOiAlZAoAE2ludE9w"
-"ZXJUZXN0IFBBU1NFRAoADGludFNoaWZ0VGVzdAAJbGl0MTZUZXN0AAhsaXQ4VGVzdAAMbG9uZ09w"
-"ZXJUZXN0ABhsb25nT3BlclRlc3QgRkFJTEVEOiAlZAoAFGxvbmdPcGVyVGVzdCBQQVNTRUQKAA1s"
-"b25nU2hpZnRUZXN0ABlsb25nU2hpZnRUZXN0IEZBSUxFRDogJWQKABVsb25nU2hpZnRUZXN0IFBB"
-"U1NFRAoABG1haW4AA291dAAGcHJpbnRmAApzaGlmdFRlc3QxABZzaGlmdFRlc3QxIEZBSUxFRDog"
-"JWQKABJzaGlmdFRlc3QxIFBBU1NFRAoACnNoaWZ0VGVzdDIAFnNoaWZ0VGVzdDIgRkFJTEVEOiAl"
-"ZAoAEnNoaWZ0VGVzdDIgUEFTU0VECgAKc3dpdGNoVGVzdAAWc3dpdGNoVGVzdCBGQUlMRUQ6ICVk"
-"CgASc3dpdGNoVGVzdCBQQVNTRUQKABF0ZXN0RG91YmxlQ29tcGFyZQAddGVzdERvdWJsZUNvbXBh"
-"cmUgRkFJTEVEOiAlZAoAGXRlc3REb3VibGVDb21wYXJlIFBBU1NFRAoAEHRlc3RGbG9hdENvbXBh"
-"cmUAHHRlc3RGbG9hdENvbXBhcmUgRkFJTEVEOiAlZAoAGHRlc3RGbG9hdENvbXBhcmUgUEFTU0VE"
-"CgAOdGVzdEludENvbXBhcmUAGnRlc3RJbnRDb21wYXJlIEZBSUxFRDogJWQKABZ0ZXN0SW50Q29t"
-"cGFyZSBQQVNTRUQKAA90ZXN0TG9uZ0NvbXBhcmUAG3Rlc3RMb25nQ29tcGFyZSBGQUlMRUQ6ICVk"
-"CgAXdGVzdExvbmdDb21wYXJlIFBBU1NFRAoACHVub3BUZXN0ABR1bm9wVGVzdCBGQUlMRUQ6ICVk"
-"CgAQdW5vcFRlc3QgUEFTU0VECgARdW5zaWduZWRTaGlmdFRlc3QAHXVuc2lnbmVkU2hpZnRUZXN0"
-"IEZBSUxFRDogJWQKABl1bnNpZ25lZFNoaWZ0VGVzdCBQQVNTRUQKAAd2YWx1ZU9mAAMABw4AAQAH"
-"DgBwAAcOAFQABw4tHgIOdwJ0HS0eiVoeeVoeeAD4AwEABx0tIRovAHgCAAAHWU1LS0tLWlpaWmvj"
-"LT1bAgwsAnUdlpaWlpZptJbD0wDcAQIAAAdZLUtLS3h7GpaWpQCiAQEAB1lNS0tLS0taWlt/Ankd"
-"lpaHh5aWwwC+AQEAB1lNS0tLS0taWl1/AnkdlpaHeJaWwwDtAQIAAAcOTVpaWlpaaVpaauItSy14"
-"AgxZAnUd4eHh4eG08MP/AREPlgCTAgIAAAdZLUtLS3jXAnsd4eHhagCCBAEAB3dpS5lLLZlLLZlL"
-"LZlLLZlLLZmHLZm0LZm0lppLS5paS5rwS5qHS5qlS5ppS5kCpH8dAREUAREUAREUAREUAREUAREU"
-"AREUAREUAREVAREVAREVAREVAREVAREVAA0AB1l9AREPARQPagIOWQJzHXi1ATcXwwJoHQAqAAcO"
-"LS0tLS0tLS4BIxGlAKICAQAHHS5CAigdAlMdLi0tL0E9T0ECbjstQz88PTw+QR4/AnY7PEE9UQJR"
-"HQEQF46LARYWqwDaAwQAAAAABw4uSwIXHQJqHUstSy1LLkstSy1LLUs8SzxLPUsAuQMEAAAAAAcO"
-"LkseSx5LHksfSx5LHkseSy1LLUsuSy4A2QIEAAAAAAcOLi0CJR0CXB0tLS0tLS0tLS0vMi03MS08"
-"LTwtPC08LT0vAIsDBAAAAAAHLC5LAiIdAl8dSy1LLmktaS9RSwJ7OzJLPEs+SzxLPEsABwEABw4e"
-"LQBAAAdoHh4gPxpLTAAAAAEAFoGABIwHAAAUAACAgASgBwEIuAcBCMwHAQjACAEI/AgBCOwLAQj8"
-"DAEI+A4BCPAQAQjgFAEJqBYBCIwfAQjsIQEI/CIBCMAlAQjgJgEI7CcBCIApAQi8KgEI1CoAAAAN"
-"AAAAAAAAAAEAAAAAAAAAAQAAAFEAAABwAAAAAgAAAA8AAAC0AQAAAwAAAA0AAADwAQAABAAAAAEA"
-"AACMAgAABQAAABcAAACUAgAABgAAAAIAAABMAwAAASAAABUAAACMAwAAARAAAAoAAACUFQAAAiAA"
-"AFEAAADyFQAAAyAAABUAAADpGgAAACAAAAIAAAA5HQAAABAAAAEAAACcHQAA";
-
+"AC4BBQM8AQQAEwAKAC0BBQU5AQQAEwALAA8ABgAEAAAAAAB6JgAAQwAAABMAVwQ3MgQAEhEPATQy"
+"BAASISj8NSMEABIxKPg2IwQAEkEo9DMjBAASUSjwMkMEABJhKOwyIwcAPQIHABMBCAAo5RJxKOM6"
+"AgUAEwEJACjeOwMFABMBCgAo2TwDBQATAQsAKNQ5AwUAEwEMACjPOAUFABMBDQAoyjkFBAABASjG"
+"EwEOACjDAAANAAgAAAAAAKsmAABYAAAAFgMBABMArggxAQUJPQEEABIhDwExAQkFOwEEABIxKPox"
+"AQkFOQEEABJBKPSbAQkDMQEJAToBBAASUSjsmwEFAzEBBQE6AQQAEmEo5DEBCQU4AQkAMQEJCz0B"
+"BwATAQgAKNkScSjXMQELCTsBBQATAQkAKNAxAQsJOQEFABMBCgAoyTEBBQc7AQUAEwELACjCMQEH"
+"BT0BBQATAQwAKLsxAQcFOQEFABMBDQAotAEBKLIBAAEAAAAAANkmAAAEAAAAewDfAAD/DwAHAAAA"
+"AAAAAOImAAAjAAAAEwb/DxL1FAT///8PEsASwxQB/P8AABLCjUCPQ45h4gICBDJQBAASFA8EMlME"
+"ABIkKPwyYQQAEjQo+DJCBAASRCj0EgQo8gAAAwACAAAAAAAEJwAAAwAAANoAAgIPAAAABAAAAAIA"
+"AgACAAIABAAAAAMAAwADAAMAAQAAAAQAAAACAAAABAAEAAQAAAAEAAQABAAEABsAAAAEAAUABAAF"
+"AAQABQAEAAQAAgADAAIADAAEAAEABAAEAAAADgAEAAQABQAFAAQABAAEAAQABAAAAAIAAAAFAAUA"
+"BAAAAAUABQAFAAUAAgAAAAUABAACAAAACgARAAEAAAASAAY8aW5pdD4AAUIAAUMAAUQAAUYAAUkA"
+"BUlEREREAAVJRkZGRgACSUkAA0lJSQAFSUlJSUkAHElJSklKSUpJSURGRFNJQ0lJQlpJSUpKSUlJ"
+"SUkAA0lKSgAFSUpKSkoADEludE1hdGguamF2YQABSgADSkpJAAJMSQAJTEludE1hdGg7AANMTEwA"
+"FUxqYXZhL2lvL1ByaW50U3RyZWFtOwATTGphdmEvbGFuZy9JbnRlZ2VyOwASTGphdmEvbGFuZy9P"
+"YmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwALT2JqZWN0Lmph"
+"dmEAAVMAAVYAAlZMAAFaAAJbSQACW0oAE1tMamF2YS9sYW5nL09iamVjdDsAE1tMamF2YS9sYW5n"
+"L1N0cmluZzsAAWEAAmEwAAJhMQADYTEwAANhMTEAA2ExMgADYTEzAANhMTQAA2ExNQADYTE2AANh"
+"MTcAA2ExOAADYTE5AAJhMgADYTIwAANhMjEAA2EyMgADYTIzAANhMjQAA2EyNQADYTI2AAJhMwAC"
+"YTQAAmE1AAJhNgACYTcAAmE4AAJhOQAJYWxzb01pbnVzAAhhbHNvUGx1cwAEYXJncwABYgABYwAF"
+"Y2hhcjEABWNoYXIyAAtjaGFyU3ViVGVzdAAXY2hhclN1YlRlc3QgRkFJTEVEOiAlZAoAE2NoYXJT"
+"dWJUZXN0IFBBU1NFRAoACGNvbnZUZXN0ABRjb252VGVzdCBGQUlMRUQ6ICVkCgAQY29udlRlc3Qg"
+"UEFTU0VECgABZAAEZGlzdAABZQABZgAJZmlib25hY2NpABVmaWJvbmFjY2kgRkFJTEVEOiAlZAoA"
+"EWZpYm9uYWNjaSBQQVNTRUQKAANmb28AAWcAAWgAAWkAAmkxAAJpMgALaW50T3BlclRlc3QAF2lu"
+"dE9wZXJUZXN0IEZBSUxFRDogJWQKABNpbnRPcGVyVGVzdCBQQVNTRUQKAAxpbnRTaGlmdFRlc3QA"
+"AWwACWxpdDE2VGVzdAAIbGl0OFRlc3QADGxvbmdPcGVyVGVzdAAYbG9uZ09wZXJUZXN0IEZBSUxF"
+"RDogJWQKABRsb25nT3BlclRlc3QgUEFTU0VECgANbG9uZ1NoaWZ0VGVzdAAZbG9uZ1NoaWZ0VGVz"
+"dCBGQUlMRUQ6ICVkCgAVbG9uZ1NoaWZ0VGVzdCBQQVNTRUQKAARscmVzAAZtQnl0ZXMABG1haW4A"
+"CG1hbnlBcmdzABRtYW55QXJncyBGQUlMRUQ6ICVkCgAQbWFueUFyZ3MgUEFTU0VECgAGbWluSW50"
+"AAdtaW5Mb25nAAVtaW51cwABbgADbmFuAAZuZWdPbmUAA291dAAEcGx1cwAFcGx1czIAB3BsdXNP"
+"bmUABnByaW50ZgADcmVzAAZyZXN1bHQAB3Jlc3VsdHMAAXMACnNoaWZ0VGVzdDEAFnNoaWZ0VGVz"
+"dDEgRkFJTEVEOiAlZAoAEnNoaWZ0VGVzdDEgUEFTU0VECgAKc2hpZnRUZXN0MgAWc2hpZnRUZXN0"
+"MiBGQUlMRUQ6ICVkCgASc2hpZnRUZXN0MiBQQVNTRUQKAApzdGF0aWNDYWxsAApzd2l0Y2hUZXN0"
+"ABZzd2l0Y2hUZXN0IEZBSUxFRDogJWQKABJzd2l0Y2hUZXN0IFBBU1NFRAoAEXRlc3REb3VibGVD"
+"b21wYXJlAB10ZXN0RG91YmxlQ29tcGFyZSBGQUlMRUQ6ICVkCgAZdGVzdERvdWJsZUNvbXBhcmUg"
+"UEFTU0VECgAQdGVzdEZsb2F0Q29tcGFyZQAcdGVzdEZsb2F0Q29tcGFyZSBGQUlMRUQ6ICVkCgAY"
+"dGVzdEZsb2F0Q29tcGFyZSBQQVNTRUQKAA50ZXN0SW50Q29tcGFyZQAadGVzdEludENvbXBhcmUg"
+"RkFJTEVEOiAlZAoAFnRlc3RJbnRDb21wYXJlIFBBU1NFRAoAD3Rlc3RMb25nQ29tcGFyZQAbdGVz"
+"dExvbmdDb21wYXJlIEZBSUxFRDogJWQKABd0ZXN0TG9uZ0NvbXBhcmUgUEFTU0VECgAEdGhpcwAI"
+"dW5vcFRlc3QAFHVub3BUZXN0IEZBSUxFRDogJWQKABB1bm9wVGVzdCBQQVNTRUQKABF1bnNpZ25l"
+"ZFNoaWZ0VGVzdAAddW5zaWduZWRTaGlmdFRlc3QgRkFJTEVEOiAlZAoAGXVuc2lnbmVkU2hpZnRU"
+"ZXN0IFBBU1NFRAoABXZhbHVlAAd2YWx1ZU9mAAt2aXJ0dWFsQ2FsbAAXdmlydHVhbENhbGwgRkFJ"
+"TEVEOiAlZAoAE3ZpcnR1YWxDYWxsIFBBU1NFRAoAAXgAAXkABHplcm8AAwAHDgABAAcOAGkABw4t"
+"AwBEAj8DAUUCLQMCVgVpAFQABw4tAwBWBR4DAV0GAg53AnQdLR6JWh55Wh54APgDAW8HHS0hGi8A"
+"eAKdAZ4BB1lNAwR5EEtLS0taWlpaa+MtAwBsBTwDAXEFHgMCdQVbAwN4BQIMLAJ1HZaWlpaWabSW"
+"w9MA3AECmAFNB1ktAwB5EEtLS3h7GpaWpQCiAQGdAQdZTQMAeRBLS0tLS1paW38CeR2WloeHlpbD"
+"AL4BAZ0BB1lNAwJ5EEtLS0tLWlpaLQMAbAUtAwF4BTUCeB2WlpaHeJaWwwDtAQKdAZ4BBw5NAwh5"
+"EVpaWlpaaVpaauItAwBtBksDAnEGLQMEdQZpAwZ4BgIMWQJ1HeHh4eHhtPDD/wERD5YAkwICmAFN"
+"B1ktAwB5EUtLS3jXAnsd4eHhagDABAFBBw5pAyV3BWmoSy2oSy2oSy2oSy2oSy2ohy2otC2otAMj"
+"ZgaWqVppqYdpqfBpqcNpqcNpqWlpAg6kATURWqlaWqkCin8dBSMBExQBExQBExQBExQBExQBExQB"
+"ExQBExQGIwETFQETFQETFQETFQETFQETFQISARMOARMVAJUEGyQlMDg5Ojs8PT4mJygpKissLS4v"
+"MTIzNDU2NwcOAhs7AmYdh1qHWodaWpaWlpaWlpaWlpalpaWlpaWlpaUADQAHWX0DBGcQARIPAwBX"
+"BQEVDwMBWAV5AwJdBgIOWQJzHXi1ATgXwwJoHQAqAAcOLQMAIwYtAwJCBi0DBEMGLQMGTAYtAwhO"
+"Bi0DCk8GLQMMVAYuAw5VBgEqEQMQeAa0ALoEASMHDloDAFMHAKICASMHDi4DAHcFQgIoLAUAAwF3"
+"BQJSHQUBBgABAgUABgEeBQEGAAECBQAGAR8FAQYAAQIFAAYBHgUBBgABAgUABgEeBQEGAAECBQAG"
+"ASAFAQYAQT0+AQIFAAYBAnYdBQEGAAECBQAGAR4FAQYAAQMFAAYBJQUBBgABAwUABgEgBQEGAEEB"
+"AwUABgECex0FAQYAAQMFAAYBHgUBBgABAwUABgEfBQEGAAEDBQAGAR4FAQYAAQMFAAYBIAUBBgBB"
+"Hj8BAwUABgECdh0FAQYAAQMFAAYBHgUBBgABAwUABgEjBQEGAAEDBQAGAR8FAQYAAQMFAAYBAQEF"
+"AQYAJAUABgECUR0BEBeOiwEWFqsA2gMEbnN0cAcOLgMAdwVLAhcdBQACah0GAEstSy1LLkstSy1L"
+"LUs8SzxLPUsAuQMEbnN0cAcOLgMAdwVLHkseSx5LH0seSx5LHkstSy1LLksuANkCBG5zdJ8BBw4u"
+"AwB3BS0CJR0CXB0tLS0tLS0tLS0vMi03MS08LTwtPC08LT1AGwCLAwRuP3NABywuAwB3BUsCIh0C"
+"Xx1LLUsuaS1pL1FLAns7Mks8Sz5LPEs8S0wABwGdAQcOHi0AOwAHaB4DAEIBHgMDeg08AwFDAh8D"
+"AlYFHh4eLj8aS0tLALUEASMHDgAAAAEAGYGABPgJAAAWAQCAgASMCgEIpAoBCNQKAQjICwEIhAwB"
+"CPQOAQiEEAEIgBIBCIgUAQj0FwEJvBkBCJglAQj4KAEI4CsBCIQtAQioLQEImDABCLgxAQjEMgEI"
+"3DMBCJw1AQi0NRYAjDYADQAAAAAAAAABAAAAAAAAAAEAAACfAAAAcAAAAAIAAAATAAAA7AIAAAMA"
+"AAAOAAAAOAMAAAQAAAABAAAA4AMAAAUAAAAaAAAA6AMAAAYAAAACAAAAuAQAAAEgAAAYAAAA+AQA"
+"AAEQAAALAAAAJBsAAAIgAACfAAAAvhsAAAMgAAAYAAAArSIAAAAgAAACAAAACycAAAAQAAABAAAA"
+"eCcAAA==";
 }  // namespace art
diff --git a/src/runtime_support.h b/src/runtime_support.h
index 02b176b..e104035 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -4,9 +4,44 @@
 #define ART_SRC_RUNTIME_SUPPORT_H_
 
 #if defined(__arm__)
+  /* Compiler helpers */
   extern "C" uint64_t art_shl_long(uint64_t, uint32_t);
   extern "C" uint64_t art_shr_long(uint64_t, uint32_t);
   extern "C" uint64_t art_ushr_long(uint64_t, uint32_t);
+  extern int64_t artD2L(double);
+  extern int64_t artF2L(float);
+
+  /* Conversions */
+  extern "C" float __aeabi_i2f(int op1);             // OP_INT_TO_FLOAT
+  extern "C" int __aeabi_f2iz(float op1);            // OP_FLOAT_TO_INT
+  extern "C" float __aeabi_d2f(double op1);          // OP_DOUBLE_TO_FLOAT
+  extern "C" double __aeabi_f2d(float op1);          // OP_FLOAT_TO_DOUBLE
+  extern "C" double __aeabi_i2d(int op1);            // OP_INT_TO_DOUBLE
+  extern "C" int __aeabi_d2iz(double op1);           // OP_DOUBLE_TO_INT
+  extern "C" float __aeabi_l2f(long op1);            // OP_LONG_TO_FLOAT
+  extern "C" double __aeabi_l2d(long op1);           // OP_LONG_TO_DOUBLE
+
+  /* Single-precision FP arithmetics */
+  extern "C" float __aeabi_fadd(float a, float b);   // OP_ADD_FLOAT[_2ADDR]
+  extern "C" float __aeabi_fsub(float a, float b);   // OP_SUB_FLOAT[_2ADDR]
+  extern "C" float __aeabi_fdiv(float a, float b);   // OP_DIV_FLOAT[_2ADDR]
+  extern "C" float __aeabi_fmul(float a, float b);   // OP_MUL_FLOAT[_2ADDR]
+  extern "C" float fmodf(float a, float b);          // OP_REM_FLOAT[_2ADDR]
+
+  /* Double-precision FP arithmetics */
+  extern "C" double __aeabi_dadd(double a, double b); // OP_ADD_DOUBLE[_2ADDR]
+  extern "C" double __aeabi_dsub(double a, double b); // OP_SUB_DOUBLE[_2ADDR]
+  extern "C" double __aeabi_ddiv(double a, double b); // OP_DIV_DOUBLE[_2ADDR]
+  extern "C" double __aeabi_dmul(double a, double b); // OP_MUL_DOUBLE[_2ADDR]
+  extern "C" double fmod(double a, double b);         // OP_REM_DOUBLE[_2ADDR]
+
+  /* Integer arithmetics */
+  extern "C" int __aeabi_idivmod(int op1, int op2);  // OP_REM_INT[_2ADDR|_LIT8|_LIT16]
+  extern "C" int __aeabi_idiv(int op1, int op2);     // OP_DIV_INT[_2ADDR|_LIT8|_LIT16]
+
+/* Long long arithmetics - OP_REM_LONG[_2ADDR] & OP_DIV_LONG[_2ADDR] */
+extern "C" long long __aeabi_ldivmod(long long op1, long long op2);
+
 #endif
 
 #endif  // ART_SRC_RUNTIME_SUPPORT_H_
diff --git a/src/thread.cc b/src/thread.cc
index 047c89d..4d9386f 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -37,34 +37,32 @@
   pShlLong = art_shl_long;
   pShrLong = art_shr_long;
   pUshrLong = art_ushr_long;
+  pIdiv = __aeabi_idiv;
+  pIdivmod = __aeabi_idivmod;
+  pI2f = __aeabi_i2f;
+  pF2iz = __aeabi_f2iz;
+  pD2f = __aeabi_d2f;
+  pF2d = __aeabi_f2d;
+  pD2iz = __aeabi_d2iz;
+  pL2f = __aeabi_l2f;
+  pL2d = __aeabi_l2d;
+  pFadd = __aeabi_fadd;
+  pFsub = __aeabi_fsub;
+  pFdiv = __aeabi_fdiv;
+  pFmul = __aeabi_fmul;
+  pFmodf = fmodf;
+  pDadd = __aeabi_dadd;
+  pDsub = __aeabi_dsub;
+  pDdiv = __aeabi_ddiv;
+  pDmul = __aeabi_dmul;
+  pFmod = fmod;
+  pArtF2l = artF2L;
+  pArtD2l = artD2L;
+  pLdivmod = __aeabi_ldivmod;
 #endif
   pArtAllocArrayByClass = Array::Alloc;
   pMemcpy = memcpy;
 #if 0
-//void* (Thread::*pMemcpy)(void*, const void*, size_t) /* = memcpy*/ ;
-float (Thread::*pI2f)(int);
-int (Thread::*pF2iz)(float);
-float (Thread::*pD2f)(double);
-double (Thread::*pF2d)(float);
-double (Thread::*pI2d)(int);
-int (Thread::*pD2iz)(double);
-float (Thread::*pL2f)(long);
-double (Thread::*pL2d)(long);
-long long (Thread::*pArtF2l)(float);
-long long (Thread::*pArtD2l)(double);
-float (Thread::*pFadd)(float, float);
-float (Thread::*pFsub)(float, float);
-float (Thread::*pFdiv)(float, float);
-float (Thread::*pFmul)(float, float);
-float (Thread::*pFmodf)(float, float);
-double (Thread::*pDadd)(double, double);
-double (Thread::*pDsub)(double, double);
-double (Thread::*pDdiv)(double, double);
-double (Thread::*pDmul)(double, double);
-double (Thread::*pFmod)(double, double);
-int (Thread::*pIdivmod)(int, int);
-int (Thread::*pIdiv)(int, int);
-long long (Thread::*pLdivmod)(long long, long long);
 bool (Thread::*pArtUnlockObject)(struct Thread*, struct Object*);
 bool (Thread::*pArtCanPutArrayElementNoThrow)(const struct ClassObject*,
       const struct ClassObject*);