summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2016-07-20 17:52:51 +0100
committer Vladimir Marko <vmarko@google.com> 2016-07-20 18:19:45 +0100
commit5733e98d4889b7a94e4e647fa4033239038e07e8 (patch)
tree6e7790cc1c4030fe9d7526097b9847fa6fcd91b7
parent360b4b0137ce5f0bb771e2ddbfd4735cae932565 (diff)
ARM64: Fix mterp switch table pointer calculation.
Do not mix 32-bit and 64-bit registers with add x0, xPC, w0, lsl #1 that ends up compiled as add x0, xPC, w0, uxtx #1 instead of the required sxtx. Just sing-extend the offset correctly in previous instructions. Test: Additional test in 501-regression-packed-switch. Change-Id: I9867dc1180743e98f9707a312241d2f5b726ca8c
-rw-r--r--runtime/interpreter/mterp/arm64/op_packed_switch.S8
-rw-r--r--runtime/interpreter/mterp/out/mterp_arm64.S16
-rw-r--r--test/501-regression-packed-switch/info.txt2
-rw-r--r--test/501-regression-packed-switch/smali/Test.smali25
-rw-r--r--test/501-regression-packed-switch/src/Main.java5
5 files changed, 44 insertions, 12 deletions
diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S
index 1456f1a650..fd7ca62bb0 100644
--- a/runtime/interpreter/mterp/arm64/op_packed_switch.S
+++ b/runtime/interpreter/mterp/arm64/op_packed_switch.S
@@ -9,12 +9,12 @@
* for: packed-switch, sparse-switch
*/
/* op vAA, +BBBB */
- FETCH w0, 1 // w0<- bbbb (lo)
- FETCH w1, 2 // w1<- BBBB (hi)
+ FETCH w0, 1 // x0<- 000000000000bbbb (lo)
+ FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
lsr w3, wINST, #8 // w3<- AA
- orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
+ orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb
GET_VREG w1, w3 // w1<- vAA
- add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
+ add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl $func // w0<- code-unit branch offset
sbfm xINST, x0, 0, 31
b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index df0b686d37..51e71634a5 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -1143,12 +1143,12 @@ artMterpAsmInstructionStart = .L_op_nop
* for: packed-switch, sparse-switch
*/
/* op vAA, +BBBB */
- FETCH w0, 1 // w0<- bbbb (lo)
- FETCH w1, 2 // w1<- BBBB (hi)
+ FETCH w0, 1 // x0<- 000000000000bbbb (lo)
+ FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
lsr w3, wINST, #8 // w3<- AA
- orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
+ orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb
GET_VREG w1, w3 // w1<- vAA
- add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
+ add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl MterpDoPackedSwitch // w0<- code-unit branch offset
sbfm xINST, x0, 0, 31
b MterpCommonTakenBranchNoFlags
@@ -1168,12 +1168,12 @@ artMterpAsmInstructionStart = .L_op_nop
* for: packed-switch, sparse-switch
*/
/* op vAA, +BBBB */
- FETCH w0, 1 // w0<- bbbb (lo)
- FETCH w1, 2 // w1<- BBBB (hi)
+ FETCH w0, 1 // x0<- 000000000000bbbb (lo)
+ FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
lsr w3, wINST, #8 // w3<- AA
- orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
+ orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb
GET_VREG w1, w3 // w1<- vAA
- add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
+ add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl MterpDoSparseSwitch // w0<- code-unit branch offset
sbfm xINST, x0, 0, 31
b MterpCommonTakenBranchNoFlags
diff --git a/test/501-regression-packed-switch/info.txt b/test/501-regression-packed-switch/info.txt
index fbd93fa815..988b220a87 100644
--- a/test/501-regression-packed-switch/info.txt
+++ b/test/501-regression-packed-switch/info.txt
@@ -1,2 +1,4 @@
Regression test for the interpreter and optimizing's builder which used
to trip when compiled code contained a packed switch with no targets.
+Regression test for the arm64 mterp miscalculating the switch table
+address, zero-extending a register instead of sign-extending.
diff --git a/test/501-regression-packed-switch/smali/Test.smali b/test/501-regression-packed-switch/smali/Test.smali
index 8756ed5f23..5a760c7880 100644
--- a/test/501-regression-packed-switch/smali/Test.smali
+++ b/test/501-regression-packed-switch/smali/Test.smali
@@ -27,3 +27,28 @@
.packed-switch 0x0
.end packed-switch
.end method
+
+.method public static PackedSwitchAfterData(I)I
+ .registers 1
+ goto :pswitch_instr
+
+ :case0
+ const/4 v0, 0x1
+ return v0
+
+ :pswitch_data
+ .packed-switch 0x0
+ :case0
+ :case1
+ .end packed-switch
+
+ :pswitch_instr
+ packed-switch v0, :pswitch_data
+ const/4 v0, 0x7
+ return v0
+
+ :case1
+ const/4 v0, 0x4
+ return v0
+
+.end method
diff --git a/test/501-regression-packed-switch/src/Main.java b/test/501-regression-packed-switch/src/Main.java
index b80bc62c50..12bc1a8138 100644
--- a/test/501-regression-packed-switch/src/Main.java
+++ b/test/501-regression-packed-switch/src/Main.java
@@ -29,5 +29,10 @@ public class Main {
if (result != 5) {
throw new Error("Expected 5, got " + result);
}
+ m = c.getMethod("PackedSwitchAfterData", new Class[] { int.class });
+ result = (Integer) m.invoke(null, new Integer(0));
+ if (result != 1) {
+ throw new Error("Expected 1, got " + result);
+ }
}
}