MIPS32: Improve method entry/exit code

Improvements:
- the stack frame is (de)allocated in one step instead of two
- callee-saved FPU registers are 8-byte aligned within the frame,
  allowing a single ldc1/sdc1 instruction to load/store an FPU
  register without causing exceptions due to misaligned accesses
- the return address register, RA, is restored early for better
  instruction scheduling

Change-Id: I556b139c62839490a9fdbce8c5e6e3e2d1cc7bb7
diff --git a/compiler/optimizing/optimizing_cfi_test_expected.inc b/compiler/optimizing/optimizing_cfi_test_expected.inc
index fc66823..764160a 100644
--- a/compiler/optimizing/optimizing_cfi_test_expected.inc
+++ b/compiler/optimizing/optimizing_cfi_test_expected.inc
@@ -140,53 +140,43 @@
 // 0x0000002d: .cfi_def_cfa_offset: 64
 
 static constexpr uint8_t expected_asm_kMips[] = {
-    0xE4, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
-    0x10, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0xB6, 0xE7, 0x0C, 0x00, 0xB7, 0xE7,
-    0x00, 0x00, 0xB4, 0xE7, 0x04, 0x00, 0xB5, 0xE7, 0xDC, 0xFF, 0xBD, 0x27,
-    0x00, 0x00, 0xA4, 0xAF, 0x24, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xB4, 0xC7,
-    0x04, 0x00, 0xB5, 0xC7, 0x08, 0x00, 0xB6, 0xC7, 0x0C, 0x00, 0xB7, 0xC7,
-    0x10, 0x00, 0xB0, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xBF, 0x8F,
-    0x1C, 0x00, 0xBD, 0x27, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+    0xC0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xB1, 0xAF,
+    0x34, 0x00, 0xB0, 0xAF, 0x28, 0x00, 0xB6, 0xF7, 0x20, 0x00, 0xB4, 0xF7,
+    0x00, 0x00, 0xA4, 0xAF, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xB1, 0x8F,
+    0x34, 0x00, 0xB0, 0x8F, 0x28, 0x00, 0xB6, 0xD7, 0x20, 0x00, 0xB4, 0xD7,
+    0x40, 0x00, 0xBD, 0x27, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
 };
 static constexpr uint8_t expected_cfi_kMips[] = {
-    0x44, 0x0E, 0x1C, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03,
-    0x54, 0x0E, 0x40, 0x44, 0x0A, 0x44, 0x0E, 0x1C, 0x54, 0xD0, 0x44, 0xD1,
-    0x44, 0xDF, 0x44, 0x0E, 0x00, 0x48, 0x0B, 0x0E, 0x40,
+    0x44, 0x0E, 0x40, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03,
+    0x4C, 0x0A, 0x44, 0xDF, 0x44, 0xD1, 0x44, 0xD0, 0x4C, 0x0E, 0x00, 0x48,
+    0x0B, 0x0E, 0x40,
 };
-// 0x00000000: addiu r29, r29, -28
-// 0x00000004: .cfi_def_cfa_offset: 28
-// 0x00000004: sw r31, +24(r29)
+// 0x00000000: addiu r29, r29, -64
+// 0x00000004: .cfi_def_cfa_offset: 64
+// 0x00000004: sw r31, +60(r29)
 // 0x00000008: .cfi_offset: r31 at cfa-4
-// 0x00000008: sw r17, +20(r29)
+// 0x00000008: sw r17, +56(r29)
 // 0x0000000c: .cfi_offset: r17 at cfa-8
-// 0x0000000c: sw r16, +16(r29)
+// 0x0000000c: sw r16, +52(r29)
 // 0x00000010: .cfi_offset: r16 at cfa-12
-// 0x00000010: swc1 f22, +8(r29)
-// 0x00000014: swc1 f23, +12(r29)
-// 0x00000018: swc1 f20, +0(r29)
-// 0x0000001c: swc1 f21, +4(r29)
-// 0x00000020: addiu r29, r29, -36
-// 0x00000024: .cfi_def_cfa_offset: 64
-// 0x00000024: sw r4, +0(r29)
-// 0x00000028: .cfi_remember_state
-// 0x00000028: addiu r29, r29, 36
-// 0x0000002c: .cfi_def_cfa_offset: 28
-// 0x0000002c: lwc1 f20, +0(r29)
-// 0x00000030: lwc1 f21, +4(r29)
-// 0x00000034: lwc1 f22, +8(r29)
-// 0x00000038: lwc1 f23, +12(r29)
-// 0x0000003c: lw r16, +16(r29)
-// 0x00000040: .cfi_restore: r16
-// 0x00000040: lw r17, +20(r29)
-// 0x00000044: .cfi_restore: r17
-// 0x00000044: lw r31, +24(r29)
-// 0x00000048: .cfi_restore: r31
-// 0x00000048: addiu r29, r29, 28
-// 0x0000004c: .cfi_def_cfa_offset: 0
-// 0x0000004c: jr r31
-// 0x00000050: nop
-// 0x00000054: .cfi_restore_state
-// 0x00000054: .cfi_def_cfa_offset: 64
+// 0x00000010: sdc1 f22, +40(r29)
+// 0x00000014: sdc1 f20, +32(r29)
+// 0x00000018: sw r4, +0(r29)
+// 0x0000001c: .cfi_remember_state
+// 0x0000001c: lw r31, +60(r29)
+// 0x00000020: .cfi_restore: r31
+// 0x00000020: lw r17, +56(r29)
+// 0x00000024: .cfi_restore: r17
+// 0x00000024: lw r16, +52(r29)
+// 0x00000028: .cfi_restore: r16
+// 0x00000028: ldc1 f22, +40(r29)
+// 0x0000002c: ldc1 f20, +32(r29)
+// 0x00000030: addiu r29, r29, 64
+// 0x00000034: .cfi_def_cfa_offset: 0
+// 0x00000034: jr r31
+// 0x00000038: nop
+// 0x0000003c: .cfi_restore_state
+// 0x0000003c: .cfi_def_cfa_offset: 64
 
 static constexpr uint8_t expected_asm_kMips64[] = {
     0xD8, 0xFF, 0xBD, 0x67, 0x20, 0x00, 0xBF, 0xFF, 0x18, 0x00, 0xB1, 0xFF,
@@ -349,75 +339,65 @@
 // 0x00000098: .cfi_def_cfa_offset: 64
 
 static constexpr uint8_t expected_asm_kMips_adjust_head[] = {
-    0xE4, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
-    0x10, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0xB6, 0xE7, 0x0C, 0x00, 0xB7, 0xE7,
-    0x00, 0x00, 0xB4, 0xE7, 0x04, 0x00, 0xB5, 0xE7, 0xDC, 0xFF, 0xBD, 0x27,
+    0xC0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xB1, 0xAF,
+    0x34, 0x00, 0xB0, 0xAF, 0x28, 0x00, 0xB6, 0xF7, 0x20, 0x00, 0xB4, 0xF7,
     0x00, 0x00, 0xA4, 0xAF, 0x08, 0x00, 0x04, 0x14, 0xFC, 0xFF, 0xBD, 0x27,
     0x00, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x10, 0x04, 0x02, 0x00, 0x01, 0x3C,
     0x18, 0x00, 0x21, 0x34, 0x21, 0x08, 0x3F, 0x00, 0x00, 0x00, 0xBF, 0x8F,
     0x09, 0x00, 0x20, 0x00, 0x04, 0x00, 0xBD, 0x27,
 };
 static constexpr uint8_t expected_asm_kMips_adjust_tail[] = {
-    0x24, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xB4, 0xC7, 0x04, 0x00, 0xB5, 0xC7,
-    0x08, 0x00, 0xB6, 0xC7, 0x0C, 0x00, 0xB7, 0xC7, 0x10, 0x00, 0xB0, 0x8F,
-    0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xBD, 0x27,
+    0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xB1, 0x8F, 0x34, 0x00, 0xB0, 0x8F,
+    0x28, 0x00, 0xB6, 0xD7, 0x20, 0x00, 0xB4, 0xD7, 0x40, 0x00, 0xBD, 0x27,
     0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
 };
 static constexpr uint8_t expected_cfi_kMips_adjust[] = {
-    0x44, 0x0E, 0x1C, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03,
-    0x54, 0x0E, 0x40, 0x4C, 0x0E, 0x44, 0x60, 0x0E, 0x40, 0x04, 0x04, 0x00,
-    0x02, 0x00, 0x0A, 0x44, 0x0E, 0x1C, 0x54, 0xD0, 0x44, 0xD1, 0x44, 0xDF,
-    0x44, 0x0E, 0x00, 0x48, 0x0B, 0x0E, 0x40,
+    0x44, 0x0E, 0x40, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03,
+    0x54, 0x0E, 0x44, 0x60, 0x0E, 0x40, 0x04, 0x04, 0x00, 0x02, 0x00, 0x0A,
+    0x44, 0xDF, 0x44, 0xD1, 0x44, 0xD0, 0x4C, 0x0E, 0x00, 0x48, 0x0B, 0x0E,
+    0x40,
 };
-// 0x00000000: addiu r29, r29, -28
-// 0x00000004: .cfi_def_cfa_offset: 28
-// 0x00000004: sw r31, +24(r29)
+// 0x00000000: addiu r29, r29, -64
+// 0x00000004: .cfi_def_cfa_offset: 64
+// 0x00000004: sw r31, +60(r29)
 // 0x00000008: .cfi_offset: r31 at cfa-4
-// 0x00000008: sw r17, +20(r29)
+// 0x00000008: sw r17, +56(r29)
 // 0x0000000c: .cfi_offset: r17 at cfa-8
-// 0x0000000c: sw r16, +16(r29)
+// 0x0000000c: sw r16, +52(r29)
 // 0x00000010: .cfi_offset: r16 at cfa-12
-// 0x00000010: swc1 f22, +8(r29)
-// 0x00000014: swc1 f23, +12(r29)
-// 0x00000018: swc1 f20, +0(r29)
-// 0x0000001c: swc1 f21, +4(r29)
-// 0x00000020: addiu r29, r29, -36
-// 0x00000024: .cfi_def_cfa_offset: 64
-// 0x00000024: sw r4, +0(r29)
-// 0x00000028: bne r0, r4, 0x0000004c ; +36
-// 0x0000002c: addiu r29, r29, -4
-// 0x00000030: .cfi_def_cfa_offset: 68
-// 0x00000030: sw r31, +0(r29)
-// 0x00000034: bltzal r0, 0x00000038 ; +4
-// 0x00000038: lui r1, 0x20000
-// 0x0000003c: ori r1, r1, 24
-// 0x00000040: addu r1, r1, r31
-// 0x00000044: lw r31, +0(r29)
-// 0x00000048: jr r1
-// 0x0000004c: addiu r29, r29, 4
-// 0x00000050: .cfi_def_cfa_offset: 64
-// 0x00000050: nop
+// 0x00000010: sdc1 f22, +40(r29)
+// 0x00000014: sdc1 f20, +32(r29)
+// 0x00000018: sw r4, +0(r29)
+// 0x0000001c: bne r0, r4, 0x00000040 ; +36
+// 0x00000020: addiu r29, r29, -4
+// 0x00000024: .cfi_def_cfa_offset: 68
+// 0x00000024: sw r31, +0(r29)
+// 0x00000028: bltzal r0, 0x0000002c ; +4
+// 0x0000002c: lui r1, 0x20000
+// 0x00000030: ori r1, r1, 24
+// 0x00000034: addu r1, r1, r31
+// 0x00000038: lw r31, +0(r29)
+// 0x0000003c: jr r1
+// 0x00000040: addiu r29, r29, 4
+// 0x00000044: .cfi_def_cfa_offset: 64
+// 0x00000044: nop
 //             ...
-// 0x00020050: nop
-// 0x00020054: .cfi_remember_state
-// 0x00020054: addiu r29, r29, 36
-// 0x00020058: .cfi_def_cfa_offset: 28
-// 0x00020058: lwc1 f20, +0(r29)
-// 0x0002005c: lwc1 f21, +4(r29)
-// 0x00020060: lwc1 f22, +8(r29)
-// 0x00020064: lwc1 f23, +12(r29)
-// 0x00020068: lw r16, +16(r29)
-// 0x0002006c: .cfi_restore: r16
-// 0x0002006c: lw r17, +20(r29)
-// 0x00020070: .cfi_restore: r17
-// 0x00020070: lw r31, +24(r29)
-// 0x00020074: .cfi_restore: r31
-// 0x00020074: addiu r29, r29, 28
-// 0x00020078: .cfi_def_cfa_offset: 0
-// 0x00020078: jr r31
-// 0x0002007c: nop
-// 0x00020080: .cfi_restore_state
-// 0x00020080: .cfi_def_cfa_offset: 64
+// 0x00020044: nop
+// 0x00020048: .cfi_remember_state
+// 0x00020048: lw r31, +60(r29)
+// 0x0002004c: .cfi_restore: r31
+// 0x0002004c: lw r17, +56(r29)
+// 0x00020050: .cfi_restore: r17
+// 0x00020050: lw r16, +52(r29)
+// 0x00020054: .cfi_restore: r16
+// 0x00020054: ldc1 f22, +40(r29)
+// 0x00020058: ldc1 f20, +32(r29)
+// 0x0002005c: addiu r29, r29, 64
+// 0x00020060: .cfi_def_cfa_offset: 0
+// 0x00020060: jr r31
+// 0x00020064: nop
+// 0x00020068: .cfi_restore_state
+// 0x00020068: .cfi_def_cfa_offset: 64
 
 static constexpr uint8_t expected_asm_kMips64_adjust_head[] = {
     0xD8, 0xFF, 0xBD, 0x67, 0x20, 0x00, 0xBF, 0xFF, 0x18, 0x00, 0xB1, 0xFF,