Misc fixes, new compiler unit tests

Fixed disassembly logging, miscellaneous codegen bugs and added a
set of unit tests (most of which fail because array allocation isn't quite
there yet in the codegen).

Failing tests conditionally compiled out for now.

Change-Id: I39c148f9a7686fac21c844a7a7f5ec86d4e0e1c5
diff --git a/src/common_test.h b/src/common_test.h
index a405ce5..1f3f573 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -374,6 +374,447 @@
 "AAABEAAABAAAANwCAAACIAAAGgAAAPoCAAADIAAABAAAAEAEAAAAIAAAAgAAAGgEAAAAEAAAAQAA"
 "AIQEAAA=";
 
+//class IntMath {
+//
+//    /*
+//     * Try to cause some unary operations.
+//     */
+//    static int unopTest(int x) {
+//        x = -x;
+//        x ^= 0xffffffff;
+//        return x;
+//    }
+//
+//    static int shiftTest1() {
+//        final int[] mBytes = {
+//            0x11, 0x22, 0x33, 0x44, 0x88, 0x99, 0xaa, 0xbb
+//        };
+//        long l;
+//        int i1, i2;
+//
+//        i1 = mBytes[0] | mBytes[1] << 8 | mBytes[2] << 16 | mBytes[3] << 24;
+//        i2 = mBytes[4] | mBytes[5] << 8 | mBytes[6] << 16 | mBytes[7] << 24;
+//        l = i1 | ((long)i2 << 32);
+//
+//        if (i1 != 0x44332211) { return 1; }
+//        if (i2 != 0xbbaa9988) { return 2; }
+//        if (l != 0xbbaa998844332211L) { return 3; }
+//
+//        l = (long)mBytes[0]
+//            | (long)mBytes[1] << 8
+//            | (long)mBytes[2] << 16
+//            | (long)mBytes[3] << 24
+//            | (long)mBytes[4] << 32
+//            | (long)mBytes[5] << 40
+//            | (long)mBytes[6] << 48
+//            | (long)mBytes[7] << 56;
+//
+//        if (l != 0xbbaa998844332211L) { return 4; }
+//        return 0;
+//    }
+//
+//    static int shiftTest2() {
+//
+//        long    a = 0x11;
+//        long    b = 0x22;
+//        long    c = 0x33;
+//        long    d = 0x44;
+//        long    e = 0x55;
+//        long    f = 0x66;
+//        long    g = 0x77;
+//        long    h = 0x88;
+//
+//        long    result = ((a << 56) | (b << 48) | (c << 40) | (d << 32) |
+//                         (e << 24) | (f << 16) | (g <<  8) | h);
+//
+//        if (result != 0x1122334455667788L) { return 1; }
+//        return 0;
+//    }
+//
+//    static int unsignedShiftTest() {
+//        byte b = -4;
+//        short s = -4;
+//        char c = 0xfffc;
+//        int i = -4;
+//
+//        b >>>= 4;
+//        s >>>= 4;
+//        c >>>= 4;
+//        i >>>= 4;
+//
+//        if ((int) b != -1) { return 1; }
+//        if ((int) s != -1) { return 2; }
+//        if ((int) c != 0x0fff) { return 3; }
+//        if (i != 268435455) { return 4; }
+//        return 0;
+//    }
+//
+//    static int convTest() {
+//
+//        float f;
+//        double d;
+//        int i;
+//        long l;
+//
+//        /* int --> long */
+//        i = 7654;
+//        l = (long) i;
+//        if (l != 7654L) { return 1; }
+//
+//        i = -7654;
+//        l = (long) i;
+//        if (l != -7654L) { return 2; }
+//
+//        /* long --> int (with truncation) */
+//        l = 5678956789L;
+//        i = (int) l;
+//        if (i != 1383989493) { return 3; }
+//
+//        l = -5678956789L;
+//        i = (int) l;
+//        if (i != -1383989493) { return 4; }
+//        return 0;
+//    }
+//
+//    static int charSubTest() {
+//
+//        char char1 = 0x00e9;
+//        char char2 = 0xffff;
+//        int i;
+//
+//        /* chars are unsigned-expanded to ints before subtraction */
+//        i = char1 - char2;
+//        if (i != 0xffff00ea) { return 1; }
+//        return 0;
+//    }
+//
+//    /*
+//     * We pass in the arguments and return the results so the compiler
+//     * doesn't do the math for us.  (x=70000, y=-3)
+//     */
+//    static int intOperTest(int x, int y) {
+//        int[] results = new int[10];
+//
+//        /* this seems to generate "op-int" instructions */
+//        results[0] = x + y;
+//        results[1] = x - y;
+//        results[2] = x * y;
+//        results[3] = x * x;
+//        results[4] = x / y;
+//        results[5] = x % -y;
+//        results[6] = x & y;
+//        results[7] = x | y;
+//        results[8] = x ^ y;
+//
+//        /* this seems to generate "op-int/2addr" instructions */
+//        results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
+//
+//        /* check this edge case while we're here (div-int/2addr) */
+//        int minInt = -2147483648;
+//        int negOne = -results[5];
+//        int plusOne = 1;
+//        int result = (((minInt + plusOne) - plusOne) / negOne) / negOne;
+//
+//        if (result != minInt) { return 1;};
+//        if (results[0] != 69997) { return 2;};
+//        if (results[1] != 70003) { return 3;};
+//        if (results[2] != -210000) { return 4;};
+//        if (results[3] != 605032704) { return 5;};
+//        if (results[4] != -23333) { return 6;};
+//        if (results[5] != 1) { return 7;};
+//        if (results[6] != 70000) { return 8;};
+//        if (results[7] != -3) { return 9;};
+//        if (results[8] != -70003) { return 10;};
+//        if (results[9] != 70000) { return 11;};
+//
+//        return 0;
+//    }
+//
+//    /*
+//     * More operations, this time with 16-bit constants.  (x=77777)
+//     */
+//    static int lit16Test(int x) {
+//
+//        int[] results = new int[8];
+//
+//        /* try to generate op-int/lit16" instructions */
+//        results[0] = x + 1000;
+//        results[1] = 1000 - x;
+//        results[2] = x * 1000;
+//        results[3] = x / 1000;
+//        results[4] = x % 1000;
+//        results[5] = x & 1000;
+//        results[6] = x | -1000;
+//        results[7] = x ^ -1000;
+//
+//        if (results[0] != 78777) { return 1; }
+//        if (results[1] != -76777) { return 2; }
+//        if (results[2] != 77777000) { return 3; }
+//        if (results[3] != 77) { return 4; }
+//        if (results[4] != 777) { return 5; }
+//        if (results[5] != 960) { return 6; }
+//        if (results[6] != -39) { return 7; }
+//        if (results[7] != -76855) { return 8; }
+//        return 0;
+//    }
+//
+//    /*
+//     * More operations, this time with 8-bit constants.  (x=-55555)
+//     */
+//    static int lit8Test(int x) {
+//
+//        int[] results = new int[8];
+//
+//        /* try to generate op-int/lit8" instructions */
+//        results[0] = x + 10;
+//        results[1] = 10 - x;
+//        results[2] = x * 10;
+//        results[3] = x / 10;
+//        results[4] = x % 10;
+//        results[5] = x & 10;
+//        results[6] = x | -10;
+//        results[7] = x ^ -10;
+//        int minInt = -2147483648;
+//        int result = minInt / -1;
+//        if (result != minInt) {return 1; }
+//        if (results[0] != -55545) {return 2; }
+//        if (results[1] != 55565) {return 3; }
+//        if (results[2] != -555550) {return 4; }
+//        if (results[3] != -5555) {return 5; }
+//        if (results[4] != -5) {return 6; }
+//        if (results[5] != 8) {return 7; }
+//        if (results[6] != -1) {return 8; }
+//        if (results[7] != 55563) {return 9; }
+//        return 0;
+//    }
+//
+//
+//    /*
+//     * Shift some data.  (value=0xff00aa01, dist=8)
+//     */
+//    static int intShiftTest(int value, int dist) {
+//        int results[] = new int[4];
+//        results[0] = value << dist;
+//        results[1] = value >> dist;
+//        results[2] = value >>> dist;
+//        results[3] = (((value << dist) >> dist) >>> dist) << dist;
+//        if (results[0] != 0x00aa0100) {return 1; }
+//        if (results[1] != 0xffff00aa) {return 2; }
+//        if (results[2] != 0x00ff00aa) {return 3; }
+//        if (results[3] != 0xaa00) {return 4; }
+//        return 0;
+//    }
+//
+//    /*
+//     * We pass in the arguments and return the results so the compiler
+//     * doesn't do the math for us.  (x=70000000000, y=-3)
+//     */
+//    static int longOperTest(long x, long y) {
+//        long[] results = new long[10];
+//
+//        /* this seems to generate "op-long" instructions */
+//        results[0] = x + y;
+//        results[1] = x - y;
+//        results[2] = x * y;
+//        results[3] = x * x;
+//        results[4] = x / y;
+//        results[5] = x % -y;
+//        results[6] = x & y;
+//        results[7] = x | y;
+//        results[8] = x ^ y;
+//        /* this seems to generate "op-long/2addr" instructions */
+//        results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
+//        /* check this edge case while we're here (div-long/2addr) */
+//        long minLong = -9223372036854775808L;
+//        long negOne = -results[5];
+//        long plusOne = 1;
+//        long result = (((minLong + plusOne) - plusOne) / negOne) / negOne;
+//        if (result != minLong) { return 1; }
+//        if (results[0] != 69999999997L) { return 2; }
+//        if (results[1] != 70000000003L) { return 3; }
+//        if (results[2] != -210000000000L) { return 4; }
+//        if (results[3] != -6833923606740729856L) { return 5; }    // overflow
+//        if (results[4] != -23333333333L) { return 6; }
+//        if (results[5] != 1) { return 7; }
+//        if (results[6] != 70000000000L) { return 8; }
+//        if (results[7] != -3) { return 9; }
+//        if (results[8] != -70000000003L) { return 10; }
+//        if (results[9] != 70000000000L) { return 11; }
+//        if (results.length != 10) { return 12; }
+//        return 0;
+//    }
+//
+//    /*
+//     * Shift some data.  (value=0xd5aa96deff00aa01, dist=8)
+//     */
+//    static long longShiftTest(long value, int dist) {
+//        long results[] = new long[4];
+//        results[0] = value << dist;
+//        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.length != 4) { return 5; }
+//
+//        return results[0];      // test return-long
+//    }
+//
+//
+//    public static void main(String[] args) {
+//        int res = unopTest(38);
+//        if (res == 37) {
+//            System.out.printf("unopTest PASSED\n");
+//        } else {
+//            System.out.printf("unopTest FAILED: %d\n", res);
+//        }
+//        res = shiftTest1();
+//        if (res == 0) {
+//            System.out.printf("shiftTest1 PASSED\n");
+//        } else {
+//            System.out.printf("shiftTest1 FAILED: %d\n", res);
+//        }
+//        res = shiftTest2();
+//        if (res == 0) {
+//            System.out.printf("shiftTest2 PASSED\n");
+//        } else {
+//            System.out.printf("shiftTest2 FAILED: %d\n", res);
+//        }
+//        res = unsignedShiftTest();
+//        if (res == 0) {
+//            System.out.printf("unsignedShiftTest PASSED\n");
+//        } else {
+//            System.out.printf("unsignedShiftTest FAILED: %d\n", res);
+//        }
+//        res = convTest();
+//        if (res == 0) {
+//            System.out.printf("convTest PASSED\n");
+//        } else {
+//            System.out.printf("convTest FAILED: %d\n", res);
+//        }
+//        res = charSubTest();
+//        if (res == 0) {
+//            System.out.printf("charSubTest PASSED\n");
+//        } else {
+//            System.out.printf("charSubTest FAILED: %d\n", res);
+//        }
+//        res = intOperTest(70000, -3);
+//        if (res == 0) {
+//            System.out.printf("intOperTest PASSED\n");
+//        } else {
+//            System.out.printf("intOperTest FAILED: %d\n", res);
+//        }
+//        res = longOperTest(70000000000L, -3L);
+//        if (res == 0) {
+//            System.out.printf("longOperTest PASSED\n");
+//        } else {
+//            System.out.printf("longOperTest FAILED: %d\n", res);
+//        }
+//        long lres = longShiftTest(0xd5aa96deff00aa01L, 16);
+//        if (lres == 0x96deff00aa010000L) {
+//            System.out.printf("longShiftTest PASSED\n");
+//        } else {
+//            System.out.printf("longShiftTest FAILED: %d\n", res);
+//        }
+//    }
+//}
+static const char kIntMathDex[] =
+"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"
+"Fg6IABMQOACjAAAQExAwAKMCAhDBIBMCKACjAgQCwSATAiAAowIGAsEgEwIYAKMCCALBIBMCEACj"
+"AgoCwSATAggAowIMAsEgweAYAoh3ZlVEMyIRMQAAAjgABAASEA8AEgAo/gIAAQAAAAAAqxMAAAQA"
+"AAB7EN8AAP8PAAUAAAAAAAAAsxMAABcAAAAUAf///w8TBP8PEvONEI8RjkIyMAQAEhAPADIxBAAS"
+"ICj8MkIEABIwKPgSACj2AAABAAAAAAAAAAIAAAAAAAAAAgAAAAEAAQACAAAAAQAAAAIAAAAGAAsA"
+"AQAAAAwABjxpbml0PgABSQACSUkAA0lJSQADSUpKAAxJbnRNYXRoLmphdmEAAUoAA0pKSQACTEkA"
+"CUxJbnRNYXRoOwADTExMABVMamF2YS9pby9QcmludFN0cmVhbTsAE0xqYXZhL2xhbmcvSW50ZWdl"
+"cjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
+"c3RlbTsAC09iamVjdC5qYXZhAAFWAAJWTAACW0kAAltKABNbTGphdmEvbGFuZy9PYmplY3Q7ABNb"
+"TGphdmEvbGFuZy9TdHJpbmc7AAtjaGFyU3ViVGVzdAAXY2hhclN1YlRlc3QgRkFJTEVEOiAlZAoA"
+"E2NoYXJTdWJUZXN0IFBBU1NFRAoACGNvbnZUZXN0ABRjb252VGVzdCBGQUlMRUQ6ICVkCgAQY29u"
+"dlRlc3QgUEFTU0VECgALaW50T3BlclRlc3QAF2ludE9wZXJUZXN0IEZBSUxFRDogJWQKABNpbnRP"
+"cGVyVGVzdCBQQVNTRUQKAAxpbnRTaGlmdFRlc3QACWxpdDE2VGVzdAAIbGl0OFRlc3QADGxvbmdP"
+"cGVyVGVzdAAYbG9uZ09wZXJUZXN0IEZBSUxFRDogJWQKABRsb25nT3BlclRlc3QgUEFTU0VECgAN"
+"bG9uZ1NoaWZ0VGVzdAAZbG9uZ1NoaWZ0VGVzdCBGQUlMRUQ6ICVkCgAVbG9uZ1NoaWZ0VGVzdCBQ"
+"QVNTRUQKAARtYWluAANvdXQABnByaW50ZgAKc2hpZnRUZXN0MQAWc2hpZnRUZXN0MSBGQUlMRUQ6"
+"ICVkCgASc2hpZnRUZXN0MSBQQVNTRUQKAApzaGlmdFRlc3QyABZzaGlmdFRlc3QyIEZBSUxFRDog"
+"JWQKABJzaGlmdFRlc3QyIFBBU1NFRAoACHVub3BUZXN0ABR1bm9wVGVzdCBGQUlMRUQ6ICVkCgAQ"
+"dW5vcFRlc3QgUEFTU0VECgARdW5zaWduZWRTaGlmdFRlc3QAHXVuc2lnbmVkU2hpZnRUZXN0IEZB"
+"SUxFRDogJWQKABl1bnNpZ25lZFNoaWZ0VGVzdCBQQVNTRUQKAAd2YWx1ZU9mAAMABw4AAQAHDgBw"
+"AAcOAFQABw4tHgIOdwJ0HS0eiVoeeVoeeAB4AgAAB1lNS0tLS1paWlpr4y09WwIMLAJ1HZaWlpaW"
+"abSWw9MA3AECAAAHWS1LS0t4exqWlqUAogEBAAdZTUtLS0tLWlpbfwJ5HZaWh4eWlsMAvgEBAAdZ"
+"TUtLS0tLWlpdfwJ5HZaWh3iWlsMA7QECAAAHDk1aWlpaWmlaWmriLUsteAIMWQJ1HeHh4eHhtPDD"
+"/wERD5YAkwICAAAHWS1LS0t41wJ7HeHh4WoAowIBAAcsaUuZSy2ZSy2ZSy2ZSy2ZSy2Zhy2ZtC2Z"
+"tJaZAk4dAREUAREUAREUAREUAREUAREUAREUAREUAA0AB1l9AREPARQPagIOWQJzHXi1ATcXwwJo"
+"HQAqAAcOLS0tLS0tLS4BIxGlAAcBAAcOHi0AQAAHaB4eID8aS0wAAAABABCBgATEBQAADgAAgIAE"
+"2AUBCPAFAQiEBgEI+AYBCOgJAQj4CgEI9AwBCOwOAQjcEgEJpBQBCLQZAQiUHAEIpB0BCLwdAA0A"
+"AAAAAAAAAQAAAAAAAAABAAAAOQAAAHAAAAACAAAADQAAAFQBAAADAAAACQAAAIgBAAAEAAAAAQAA"
+"APQBAAAFAAAAEQAAAPwBAAAGAAAAAgAAAIQCAAABIAAADwAAAMQCAAABEAAABgAAAPwOAAACIAAA"
+"OQAAACoPAAADIAAADwAAAHASAAAAIAAAAgAAAL8TAAAAEAAAAQAAAAgUAAA=";
+
 static inline DexFile* OpenDexFileBase64(const char* base64,
                                          const std::string& location) {
   CHECK(base64 != NULL);
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 17d6a34..4202a39 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -697,9 +697,14 @@
  */
 bool oatCompileMethod(Method* method, art::InstructionSet insnSet)
 {
-    if (PrettyMethod(method, false) != "Fibonacci.fibonacci") {
+    if ((method->GetName()->ToModifiedUtf8().find("init>") !=
+        std::string::npos) ||
+        (method->GetName()->ToModifiedUtf8().find("foo") !=
+        std::string::npos)) {
         LOG(INFO) << "not compiling " << PrettyMethod(method, false);
         return false;
+    } else {
+        LOG(INFO) << "Compiling " << PrettyMethod(method, false);
     }
 
     CompilationUnit cUnit;
@@ -724,17 +729,16 @@
     cUnit.insns = code_item->insns_;
     cUnit.insnsSize = code_item->insns_size_;
 #if 1
+    // TODO: Use command-line argument passing mechanism
     cUnit.printMe = true;
     cUnit.printMeVerbose = true;
-#endif
-#if 1
-      cUnit.disableOpt = 0 |
-           (1 << kLoadStoreElimination) |
-           (1 << kLoadHoisting) |
-           (1 << kTrackLiveTemps) |
-           (1 << kSuppressLoads) |
-           //(1 << kPromoteRegs) |:
-           0;
+    cUnit.disableOpt = 0 |
+         (1 << kLoadStoreElimination) |
+         (1 << kLoadHoisting) |
+         (1 << kTrackLiveTemps) |
+         (1 << kSuppressLoads) |
+         (1 << kPromoteRegs) |
+         0;
 #endif
 
     /* Initialize the block list */
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index dd63621..5a75cee 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -183,6 +183,10 @@
 {
     LIR* defStart;
     LIR* defEnd;
+    if(FPREG(rlSrc.lowReg)!=FPREG(rlSrc.highReg)) {
+        LOG(WARNING) << "rlSrc.lowreg:" << rlSrc.lowReg << ", rlSrc.highReg:"
+                     << rlSrc.highReg;
+    }
     assert(FPREG(rlSrc.lowReg)==FPREG(rlSrc.highReg));
     assert(rlDest.wide);
     assert(rlSrc.wide);
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index 2f3af44..21ed8aa 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -308,8 +308,6 @@
     ArmLIR* lir = (ArmLIR*) arg;
     if (lir->flags.isNop)
         return;
-    char buf[256];
-    char opName[256];
     int offset = lir->generic.offset;
     int dest = lir->operands[0];
     const bool dumpNop = false;
@@ -361,16 +359,19 @@
         default:
             if (lir->flags.isNop && !dumpNop) {
                 break;
+            } else {
+                // TODO: rewrite using string
+                char opOperands[256];
+                char opName[256];
+                buildInsnString(EncodingMap[lir->opcode].name, lir, opName,
+                                baseAddr, 256);
+                buildInsnString(EncodingMap[lir->opcode].fmt, lir, opOperands,
+                                baseAddr, 256);
+                char tBuf[256];
+                snprintf(tBuf, 256, "%p (%04x): %-8s%s%s", baseAddr + offset, offset,
+                         opName, opOperands, lir->flags.isNop ? "(nop)" : "");
+                LOG(INFO) << tBuf;
             }
-            buildInsnString(EncodingMap[lir->opcode].name, lir, opName,
-                            baseAddr, 256);
-            buildInsnString(EncodingMap[lir->opcode].fmt, lir, buf, baseAddr,
-                            256);
-            char buf[100];
-            snprintf(buf, 100, "%p (%04x): %-8s%s%s",
-                 baseAddr + offset, offset, opName, buf,
-                 lir->flags.isNop ? "(nop)" : "");
-            LOG(INFO) << buf;
             break;
     }
 
@@ -450,7 +451,7 @@
     std::string descriptor = method->GetDeclaringClass()->GetDescriptor()->
         ToModifiedUtf8();
 
-    char buf[100];
+    char buf[256];
     LOG(INFO) << "*/";
     sprintf(buf,"\n    u1 %s%s_%s_code[] = {", descriptor.c_str(),
             name.c_str(), signature.c_str());
@@ -458,8 +459,9 @@
         if (buf[i] == ';') buf[i] = '_';
     LOG(INFO) << buf;
     strcpy(buf,"        ");
-    for (int i = 0; i < cUnit->totalSize/2; i++) {
-        sprintf(buf+strlen(buf),"0x%04x,", cUnit->codeBuffer[i]);
+    u1* pLiterals = (u1*)&cUnit->codeBuffer[0];
+    for (int i = 0; i < cUnit->totalSize; i++) {
+        sprintf(buf+strlen(buf),"0x%02x,", pLiterals[i]);
         if (++linebreak == 8) {
             linebreak = 0;
             LOG(INFO) << buf;
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 0a0c9bc..400fff6 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -60,12 +60,16 @@
                     sReg = DECODE_REG(
                         oatConvertSSARegToDalvik(cUnit, ssaRep->defs[0]));
                     counts[sReg].doubleStart = true;
+                }
+                if (attrs & DF_DA_WIDE) {
                     cUnit->regLocation[ssaRep->defs[0]].wide = true;
                 }
                 if ((attrs & (DF_UA_WIDE|DF_FP_A)) == (DF_UA_WIDE|DF_FP_A)) {
                     sReg = DECODE_REG(
                         oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
                     counts[sReg].doubleStart = true;
+                }
+                if (attrs & DF_UA_WIDE) {
                     cUnit->regLocation[ssaRep->uses[first]].wide = true;
                     first += 2;
                 }
@@ -73,6 +77,8 @@
                     sReg = DECODE_REG(
                         oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
                     counts[sReg].doubleStart = true;
+                }
+                if (attrs & DF_UB_WIDE) {
                     cUnit->regLocation[ssaRep->uses[first]].wide = true;
                     first += 2;
                 }
@@ -80,6 +86,8 @@
                     sReg = DECODE_REG(
                         oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
                     counts[sReg].doubleStart = true;
+                }
+                if (attrs & DF_UC_WIDE) {
                     cUnit->regLocation[ssaRep->uses[first]].wide = true;
                 }
             }
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index b8dcdb2..fd1b8a7 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -28,15 +28,16 @@
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
         GetResolvedClass(mir->dalvikInsn.vC);
     if (classPtr == NULL) {
-         LOG(FATAL) << "Unexpected null passPtr";
+         LOG(FATAL) << "Unexpected null classPtr";
     } else {
          loadValueDirectFixed(cUnit, rlSrc, r1);    /* get Len */
          loadConstant(cUnit, r0, (int)classPtr);
     }
-    // FIXME: need this to throw errNegativeArraySize
+    UNIMPLEMENTED(WARNING) << "Support for throwing errNegativeArraySize";
     genRegImmCheck(cUnit, kArmCondMi, r1, 0, mir->offset, NULL);
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pArtAllocArrayByClass),
                  rLR);
+    UNIMPLEMENTED(WARNING) << "Need NoThrow wrapper";
     newLIR1(cUnit, kThumbBlxR, rLR); // (arrayClass, length, allocFlags)
     storeValue(cUnit, rlDest, retLoc);
 }
@@ -63,7 +64,7 @@
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
         GetResolvedClass(typeIndex);
     if (classPtr == NULL) {
-         LOG(FATAL) << "Unexpected null passPtr";
+         LOG(FATAL) << "Unexpected null classPtr";
     } else {
          loadConstant(cUnit, r0, (int)classPtr);
          loadConstant(cUnit, r1, elems);
@@ -897,7 +898,7 @@
             rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
             loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
                                   0, mir->dalvikInsn.vB);
-            storeValue(cUnit, rlDest, rlResult);
+            storeValueWide(cUnit, rlDest, rlResult);
             break;
 
         case OP_CONST_WIDE_HIGH16:
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 1a126e4..d8ecc84 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -1335,18 +1335,18 @@
     switch( mir->dalvikInsn.opcode) {
         case OP_SHL_LONG:
         case OP_SHL_LONG_2ADDR:
+            UNIMPLEMENTED(FATAL) << "Need SHL_LONG helper";
             //genDispatchToHandler(cUnit, TEMPLATE_SHL_LONG);
-            assert(0);  // unimp
             break;
         case OP_SHR_LONG:
         case OP_SHR_LONG_2ADDR:
+            UNIMPLEMENTED(FATAL) << "Need SHR_LONG helper";
             //genDispatchToHandler(cUnit, TEMPLATE_SHR_LONG);
-            assert(0); // unimp
             break;
         case OP_USHR_LONG:
         case OP_USHR_LONG_2ADDR:
+            UNIMPLEMENTED(FATAL) << "Need USHR_LONG helper";
             //genDispatchToHandler(cUnit, TEMPLATE_USHR_LONG);
-            assert(0); // unimp
             break;
         default:
             return true;
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index c0d0c90..004a4a8 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -37,6 +37,287 @@
 
   ASSERT_EQ(55, result);
 }
+
+TEST_F(CompilerTest, UnopTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "unopTest", "(I)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 38);
+  LOG(INFO) << "unopTest(38) == " << result;
+
+  ASSERT_EQ(37, result);
+}
+
+#if 0 // Does filled array - needs load-time class resolution
+TEST_F(CompilerTest, ShiftTest1) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "shiftTest1", "()I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m);
+
+  ASSERT_EQ(0, result);
+}
 #endif
 
+#if 0 // Fails, needs 64-bit shift helper functions
+TEST_F(CompilerTest, ShiftTest2) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "shiftTest2", "()I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+TEST_F(CompilerTest, UnsignedShiftTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "unsignedShiftTest", "()I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m);
+
+  ASSERT_EQ(0, result);
+}
+
+#if 0 // Fail subtest #3, long to int conversion w/ truncation.
+TEST_F(CompilerTest, ConvTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "convTest", "()I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+TEST_F(CompilerTest, CharSubTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "charSubTest", "()I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m);
+
+  ASSERT_EQ(0, result);
+}
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, IntOperTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "intOperTest", "(II)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 70000, -3);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit16Test) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "lit16Test", "(I)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 77777);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit8Test) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "lit8Test", "(I)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, -55555);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit8Test) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "lit8Test", "(I)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, -55555);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, IntShiftTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "intShiftTest", "(II)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 0xff00aa01, 8);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, LongOperTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "longOperTest", "(LL)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 70000000000L, 3);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, LongShiftTest) {
+  scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+                               "kIntMathDex"));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+  Thread::Current()->SetClassLoaderOverride(class_loader);
+
+  JNIEnv* env = Thread::Current()->GetJniEnv();
+
+  jclass c = env->FindClass("IntMath");
+  ASSERT_TRUE(c != NULL);
+
+  jmethodID m = env->GetStaticMethodID(c, "longShiftTest", "(LL)I");
+  ASSERT_TRUE(m != NULL);
+
+  jint result = env->CallStaticIntMethod(c, m, 0xd5aa96deff00aa01, 8);
+
+  ASSERT_EQ(0, result);
+}
+#endif
+
+#endif // Arm
 }  // namespace art
diff --git a/src/thread.cc b/src/thread.cc
index 8d11541..409db2a 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -18,6 +18,51 @@
 
 pthread_key_t Thread::pthread_key_self_;
 
+void Thread::InitFunctionPointers() {
+  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*);
+int (Thread::*pArtInstanceofNonTrivialNoThrow)
+  (const struct ClassObject*, const struct ClassObject*);
+int (Thread::*pArtInstanceofNonTrivial) (const struct ClassObject*,
+     const struct ClassObject*);
+struct Method* (Thread::*pArtFindInterfaceMethodInCache)(ClassObject*, uint32_t,
+      const struct Method*, struct DvmDex*);
+bool (Thread::*pArtUnlockObjectNoThrow)(struct Thread*, struct Object*);
+void (Thread::*pArtLockObjectNoThrow)(struct Thread*, struct Object*);
+struct Object* (Thread::*pArtAllocObjectNoThrow)(struct ClassObject*, int);
+void (Thread::*pArtThrowException)(struct Thread*, struct Object*);
+bool (Thread::*pArtHandleFillArrayDataNoThrow)(struct ArrayObject*, const uint16_t*);
+#endif
+}
+
 Mutex* Mutex::Create(const char* name) {
   Mutex* mu = new Mutex(name);
   int result = pthread_mutex_init(&mu->lock_impl_, NULL);
diff --git a/src/thread.h b/src/thread.h
index 7204577..bb97d4e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -26,6 +26,8 @@
 class Thread;
 class ThreadList;
 class Throwable;
+class Array;
+class Class;
 
 class Mutex {
  public:
@@ -166,7 +168,6 @@
 
   static const size_t kDefaultStackSize = 64 * KB;
 
-// TODO - needs to be redone properly, just hacked into place for now
   // Runtime support function pointers
   void* (*pMemcpy)(void*, const void*, size_t);
   float (*pI2f)(int);
@@ -194,22 +195,19 @@
   long long (*pLdivmod)(long long, long long);
   bool (*pArtUnlockObject)(struct Thread*, struct Object*);
   bool (*pArtCanPutArrayElementNoThrow)(const struct ClassObject*,
-        const struct ClassObject*);
-  int (*pArtInstanceofNonTrivialNoThrow)
-    (const struct ClassObject*, const struct ClassObject*);
-  int (*pArtInstanceofNonTrivial) (const struct ClassObject*,
-       const struct ClassObject*);
-  struct ArrayObject* (*pArtAllocArrayByClass)(struct ClassObject*,
-       size_t, int);
+                 const struct ClassObject*);
+  int (*pArtInstanceofNonTrivialNoThrow) (const struct ClassObject*,
+                const struct ClassObject*);
+  int (*pArtInstanceofNonTrivial) (const struct ClassObject*, const struct ClassObject*);
+  Array* (*pArtAllocArrayByClass)(Class*, size_t);
   struct Method* (*pArtFindInterfaceMethodInCache)(ClassObject*, uint32_t,
-        const struct Method*, struct DvmDex*);
+                           const struct Method*, struct DvmDex*);
   bool (*pArtUnlockObjectNoThrow)(struct Thread*, struct Object*);
   void (*pArtLockObjectNoThrow)(struct Thread*, struct Object*);
   struct Object* (*pArtAllocObjectNoThrow)(struct ClassObject*, int);
   void (*pArtThrowException)(struct Thread*, struct Object*);
   bool (*pArtHandleFillArrayDataNoThrow)(struct ArrayObject*, const uint16_t*);
 
-
   // Creates a new thread.
   static Thread* Create(const Runtime* runtime);
 
@@ -388,6 +386,7 @@
         exception_(NULL),
         suspend_count_(0),
         class_loader_override_(NULL) {
+    InitFunctionPointers();
   }
 
   ~Thread() {
@@ -395,6 +394,7 @@
   }
 
   void InitCpu();
+  void InitFunctionPointers();
 
   // Managed thread id.
   uint32_t id_;