diff options
author | 2016-07-20 17:52:51 +0100 | |
---|---|---|
committer | 2016-07-20 18:19:45 +0100 | |
commit | 5733e98d4889b7a94e4e647fa4033239038e07e8 (patch) | |
tree | 6e7790cc1c4030fe9d7526097b9847fa6fcd91b7 | |
parent | 360b4b0137ce5f0bb771e2ddbfd4735cae932565 (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.S | 8 | ||||
-rw-r--r-- | runtime/interpreter/mterp/out/mterp_arm64.S | 16 | ||||
-rw-r--r-- | test/501-regression-packed-switch/info.txt | 2 | ||||
-rw-r--r-- | test/501-regression-packed-switch/smali/Test.smali | 25 | ||||
-rw-r--r-- | test/501-regression-packed-switch/src/Main.java | 5 |
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); + } } } |