JIT: Reworked the assembler to be smarter about short instruction forms

Previously, the JIT wasn't generating short-form compare and branch on
zero/not zero instructions for Thumb2.  The reason was that these only
allow a 1-byte displacement, and when they didn't reach the assembler would
abort the trace, split it in half and try again.  This change re-enables
cbz, cbnz generation and introduces a relatively lightweight retry
mechanism.

Also includes changes for Thumb2 to always generate large displacement
literal loads and conditional branches to minimize the number of retry
attempts.

Change-Id: Icf066836fad203f5c0fcbbb2ae8e1aa73d1cf816
diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c
index a828886..8e5a5e2 100644
--- a/vm/compiler/Frontend.c
+++ b/vm/compiler/Frontend.c
@@ -918,15 +918,17 @@
     /* Convert MIR to LIR, etc. */
     dvmCompilerMIR2LIR(&cUnit);
 
-    /* Convert LIR into machine code. */
-    dvmCompilerAssembleLIR(&cUnit, info);
+    /* Convert LIR into machine code. Loop for recoverable retries */
+    do {
+        dvmCompilerAssembleLIR(&cUnit, info);
+        cUnit.assemblerRetries++;
+        if (cUnit.printMe && cUnit.assemblerStatus != kSuccess)
+            LOGD("Assembler abort #%d on %d",cUnit.assemblerRetries,
+                  cUnit.assemblerStatus);
+    } while (cUnit.assemblerStatus == kRetryAll);
 
     if (cUnit.printMe) {
-        if (cUnit.halveInstCount) {
-            LOGD("Assembler aborted");
-        } else {
-            dvmCompilerCodegenDump(&cUnit);
-        }
+        dvmCompilerCodegenDump(&cUnit);
         LOGD("End %s%s, %d Dalvik instructions",
              desc->method->clazz->descriptor, desc->method->name,
              cUnit.numInsts);
@@ -935,18 +937,17 @@
     /* Reset the compiler resource pool */
     dvmCompilerArenaReset();
 
-    /* Success */
-    if (!cUnit.halveInstCount) {
-#if defined(WITH_JIT_TUNING)
-        methodStats->nativeSize += cUnit.totalSize;
-#endif
-        return info->codeAddress != NULL;
-
-    /* Halve the instruction count and retry again */
-    } else {
+    if (cUnit.assemblerStatus == kRetryHalve) {
+        /* Halve the instruction count and start from the top */
         return dvmCompileTrace(desc, cUnit.numInsts / 2, info, bailPtr,
                                optHints);
     }
+
+    assert(cUnit.assemblerStatus == kSuccess);
+#if defined(WITH_JIT_TUNING)
+    methodStats->nativeSize += cUnit.totalSize;
+#endif
+    return info->codeAddress != NULL;
 }
 
 /*
@@ -1290,7 +1291,7 @@
     /* Convert LIR into machine code. */
     dvmCompilerAssembleLIR(cUnit, info);
 
-    if (cUnit->halveInstCount) {
+    if (cUnit->assemblerStatus != kSuccess) {
         return false;
     }