[PATCH] Fix mterp assembly to use uxtw instead of lsl where needed.
authorDavid Srbecky <dsrbecky@google.com>
Thu, 4 Apr 2019 15:16:17 +0000 (16:16 +0100)
committerRoger Shimizu <rosh@debian.org>
Fri, 21 Jan 2022 15:26:23 +0000 (15:26 +0000)
Bug: https://bugs.llvm.org/show_bug.cgi?id=41504
Origin: https://android-review.googlesource.com/c/platform/art/+/940018

The old instructions are invalid according to the ARM spec.

Event though UXTW and LSL are aliases this is binary change:
"add x0, x1, w2, lsl #1" was invalid and would be treated as
"add x0, x1, x2, uxtx #1" which would keep the high bits.

With uxtw, we ignore the high bits, as expected in code.

Test: test.py -r --target --interpreter
Change-Id: I66f67ccc5a401d0cf6ac5b42d41d8df26a190046

Gbp-Pq: Name fix-mterp-assembly-to-use-uxtw-instead-of-lsl-where-needed.patch

runtime/interpreter/mterp/arm64/array.S
runtime/interpreter/mterp/arm64/main.S
runtime/interpreter/mterp/arm64/other.S

index a023d22ff5c625c332c46a3040e9664c52343565..628f832e3a859328db04106efa12eaac31ac0055 100644 (file)
@@ -75,7 +75,7 @@
     GET_VREG w1, w3                     // w1<- vCC (requested index)
     cbz     w0, common_errNullObject        // yes, bail
     ldr     w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET]    // w3<- arrayObj->length
-    add     x0, x0, w1, lsl #3          // w0<- arrayObj + index*width
+    add     x0, x0, w1, uxtw #3         // w0<- arrayObj + index*width
     cmp     w1, w3                      // compare unsigned index, length
     bcs     common_errArrayIndex        // index >= length, bail
     FETCH_ADVANCE_INST 2                // advance rPC, load wINST
     GET_VREG w1, w3                     // w1<- vCC (requested index)
     cbz     w0, common_errNullObject    // bail if null
     ldr     w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET]     // w3<- arrayObj->length
-    add     x0, x0, w1, lsl #$shift     // w0<- arrayObj + index*width
+    add     x0, x0, w1, uxtw #$shift    // w0<- arrayObj + index*width
     cmp     w1, w3                      // compare unsigned index, length
     bcs     common_errArrayIndex        // index >= length, bail
     FETCH_ADVANCE_INST 2                // advance rPC, load rINST
     GET_VREG w1, w3                     // w1<- vCC (requested index)
     cbz     w0, common_errNullObject    // bail if null
     ldr     w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET]    // w3<- arrayObj->length
-    add     x0, x0, w1, lsl #3          // w0<- arrayObj + index*width
+    add     x0, x0, w1, uxtw #3         // w0<- arrayObj + index*width
     cmp     w1, w3                      // compare unsigned index, length
     bcs     common_errArrayIndex        // index >= length, bail
     GET_VREG_WIDE x1, w4
index aefec61879bc4011da977d0259e084d9a43010ca..fd745f1bd15759dd9fd1470ac2b61062321a45e7 100644 (file)
@@ -268,23 +268,23 @@ codes.
  * Get/set the 64-bit value from a Dalvik register.
  */
 .macro GET_VREG_WIDE reg, vreg
-    add     ip2, xFP, \vreg, lsl #2
+    add     ip2, xFP, \vreg, uxtw #2
     ldr     \reg, [ip2]
 .endm
 .macro SET_VREG_WIDE reg, vreg
-    add     ip2, xFP, \vreg, lsl #2
+    add     ip2, xFP, \vreg, uxtw #2
     str     \reg, [ip2]
-    add     ip2, xREFS, \vreg, lsl #2
+    add     ip2, xREFS, \vreg, uxtw #2
     str     xzr, [ip2]
 .endm
 .macro GET_VREG_DOUBLE reg, vreg
-    add     ip2, xFP, \vreg, lsl #2
+    add     ip2, xFP, \vreg, uxtw #2
     ldr     \reg, [ip2]
 .endm
 .macro SET_VREG_DOUBLE reg, vreg
-    add     ip2, xFP, \vreg, lsl #2
+    add     ip2, xFP, \vreg, uxtw #2
     str     \reg, [ip2]
-    add     ip2, xREFS, \vreg, lsl #2
+    add     ip2, xREFS, \vreg, uxtw #2
     str     xzr, [ip2]
 .endm
 
@@ -300,7 +300,7 @@ codes.
  * Convert a virtual register index into an address.
  */
 .macro VREG_INDEX_TO_ADDR reg, vreg
-    add     \reg, xFP, \vreg, lsl #2   /* WARNING: handle shadow frame vreg zero if store */
+    add     \reg, xFP, \vreg, uxtw #2   /* WARNING: handle shadow frame vreg zero if store */
 .endm
 
 /*
@@ -418,9 +418,9 @@ ENTRY ExecuteMterpImpl
     mov     xSELF, x0
     ldr     w0, [x2, #SHADOWFRAME_NUMBER_OF_VREGS_OFFSET]
     add     xFP, x2, #SHADOWFRAME_VREGS_OFFSET     // point to vregs.
-    add     xREFS, xFP, w0, lsl #2                 // point to reference array in shadow frame
+    add     xREFS, xFP, w0, uxtw #2                // point to reference array in shadow frame
     ldr     w0, [x2, #SHADOWFRAME_DEX_PC_OFFSET]   // Get starting dex_pc.
-    add     xPC, x1, w0, lsl #1                    // Create direct pointer to 1st dex opcode
+    add     xPC, x1, w0, uxtw #1                   // Create direct pointer to 1st dex opcode
     CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
     EXPORT_PC
 
index f1d0ef34dc1bc4cbd7f75a0d352d37254db26f62..eccd5213721ae02aa1e9b5d3382153d6ead8c3a6 100644 (file)
     ldr     x0, [xFP, #OFF_FP_RESULT_REGISTER]  // get pointer to result JType.
     ldr     x0, [x0]                    // r0 <- result.i.
     GET_INST_OPCODE ip                  // extract opcode from wINST
-    SET_VREG_WIDE x0, x2                // fp[AA]<- r0
+    SET_VREG_WIDE x0, w2                // fp[AA]<- r0
     GOTO_OPCODE ip                      // jump to next instruction
 
 %def op_move_wide():