ARM64: Improve Mterp.
Several straight-forward optimizations:
- use ubfx instead of SHR+AND,
- do not mask shifting distance,
- use 64-bit LDRSH to avoid subsequent sign extension,
- use CBNZ instead of CMP+BNE for null checks,
- style: use SXTW alias instead of explicit SBFM.
Test: Run ART test suite on Nexus 9 with the interpreter.
Change-Id: Ibcc11ce7f455432ecb789f727da21f269f8370f0
diff --git a/runtime/interpreter/mterp/arm64/fbinop2addr.S b/runtime/interpreter/mterp/arm64/fbinop2addr.S
index 0d57cbf..04236ad 100644
--- a/runtime/interpreter/mterp/arm64/fbinop2addr.S
+++ b/runtime/interpreter/mterp/arm64/fbinop2addr.S
@@ -7,8 +7,7 @@
*/
/* binop/2addr vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
$instr // s2<- op
diff --git a/runtime/interpreter/mterp/arm64/footer.S b/runtime/interpreter/mterp/arm64/footer.S
index 2d3a11e..7628ed3 100644
--- a/runtime/interpreter/mterp/arm64/footer.S
+++ b/runtime/interpreter/mterp/arm64/footer.S
@@ -234,7 +234,7 @@
#if MTERP_LOGGING
mov x0, xSELF
add x1, xFP, #OFF_FP_SHADOWFRAME
- sbfm x2, xINST, 0, 31
+ sxtw x2, wINST
bl MterpLogOSR
#endif
mov x0, #1 // Signal normal return
diff --git a/runtime/interpreter/mterp/arm64/funopNarrow.S b/runtime/interpreter/mterp/arm64/funopNarrow.S
index 9f5ad1e..aed830b 100644
--- a/runtime/interpreter/mterp/arm64/funopNarrow.S
+++ b/runtime/interpreter/mterp/arm64/funopNarrow.S
@@ -8,10 +8,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG $srcreg, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
$instr // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG $tgtreg, w4 // vA<- d0
diff --git a/runtime/interpreter/mterp/arm64/funopNarrower.S b/runtime/interpreter/mterp/arm64/funopNarrower.S
index 411396b..6fddfea 100644
--- a/runtime/interpreter/mterp/arm64/funopNarrower.S
+++ b/runtime/interpreter/mterp/arm64/funopNarrower.S
@@ -7,10 +7,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE $srcreg, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
$instr // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG $tgtreg, w4 // vA<- d0
diff --git a/runtime/interpreter/mterp/arm64/funopWide.S b/runtime/interpreter/mterp/arm64/funopWide.S
index d83b39c..409e26b 100644
--- a/runtime/interpreter/mterp/arm64/funopWide.S
+++ b/runtime/interpreter/mterp/arm64/funopWide.S
@@ -7,10 +7,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE $srcreg, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
$instr // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE $tgtreg, w4 // vA<- d0
diff --git a/runtime/interpreter/mterp/arm64/funopWider.S b/runtime/interpreter/mterp/arm64/funopWider.S
index 50a73f1..4c91ebc 100644
--- a/runtime/interpreter/mterp/arm64/funopWider.S
+++ b/runtime/interpreter/mterp/arm64/funopWider.S
@@ -7,10 +7,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG $srcreg, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
$instr // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE $tgtreg, w4 // vA<- d0
diff --git a/runtime/interpreter/mterp/arm64/op_const_wide_16.S b/runtime/interpreter/mterp/arm64/op_const_wide_16.S
index e43628b..553d481 100644
--- a/runtime/interpreter/mterp/arm64/op_const_wide_16.S
+++ b/runtime/interpreter/mterp/arm64/op_const_wide_16.S
@@ -1,8 +1,7 @@
/* const-wide/16 vAA, #+BBBB */
- FETCH_S w0, 1 // w0<- ssssBBBB (sign-extended
+ FETCH_S x0, 1 // x0<- ssssssssssssBBBB (sign-extended)
lsr w3, wINST, #8 // w3<- AA
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- sbfm x0, x0, 0, 31
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3
GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_wide_32.S b/runtime/interpreter/mterp/arm64/op_const_wide_32.S
index 527f7d8..9dc4fc3 100644
--- a/runtime/interpreter/mterp/arm64/op_const_wide_32.S
+++ b/runtime/interpreter/mterp/arm64/op_const_wide_32.S
@@ -1,10 +1,9 @@
/* const-wide/32 vAA, #+BBBBbbbb */
- FETCH w0, 1 // w0<- 0000bbbb (low)
+ FETCH w0, 1 // x0<- 000000000000bbbb (low)
lsr w3, wINST, #8 // w3<- AA
- FETCH_S w2, 2 // w2<- ssssBBBB (high)
+ FETCH_S x2, 2 // x2<- ssssssssssssBBBB (high)
FETCH_ADVANCE_INST 3 // advance rPC, load wINST
GET_INST_OPCODE ip // extract opcode from wINST
- orr w0, w0, w2, lsl #16 // w0<- BBBBbbbb
- sbfm x0, x0, 0, 31
+ orr x0, x0, x2, lsl #16 // x0<- ssssssssBBBBbbbb
SET_VREG_WIDE x0, w3
GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iget_quick.S b/runtime/interpreter/mterp/arm64/op_iget_quick.S
index 45c68a3..699b2c4 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_quick.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_quick.S
@@ -5,8 +5,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
$load w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
$extend
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S b/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S
index 2480d2d..30b30c2 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S
@@ -3,7 +3,7 @@
FETCH w4, 1 // w4<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cbz w3, common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
add x4, x3, x4 // create direct pointer
ldr x0, [x4]
FETCH_ADVANCE_INST 2 // advance rPC, load wINST
diff --git a/runtime/interpreter/mterp/arm64/op_instance_of.S b/runtime/interpreter/mterp/arm64/op_instance_of.S
index 647bc75..a56705a 100644
--- a/runtime/interpreter/mterp/arm64/op_instance_of.S
+++ b/runtime/interpreter/mterp/arm64/op_instance_of.S
@@ -13,8 +13,7 @@
mov x3, xSELF // w3<- self
bl MterpInstanceOf // (index, &obj, method, self)
ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- A+
- and w2, w2, #15 // w2<- A
+ ubfx w2, wINST, #8, #4 // w2<- A
PREFETCH_INST 2
cbnz x1, MterpException
ADVANCE 2 // advance rPC
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_long.S b/runtime/interpreter/mterp/arm64/op_int_to_long.S
index 13d2120..35830f3 100644
--- a/runtime/interpreter/mterp/arm64/op_int_to_long.S
+++ b/runtime/interpreter/mterp/arm64/op_int_to_long.S
@@ -1 +1 @@
-%include "arm64/funopWider.S" {"instr":"sbfm x0, x0, 0, 31", "srcreg":"w0", "tgtreg":"x0"}
+%include "arm64/funopWider.S" {"instr":"sxtw x0, w0", "srcreg":"w0", "tgtreg":"x0"}
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S b/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S
index 27b5dc5..566e2bf 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S
@@ -3,8 +3,7 @@
FETCH w3, 1 // w3<- field byte offset
GET_VREG w2, w2 // w2<- fp[B], the object pointer
ubfx w0, wINST, #8, #4 // w0<- A
- cmp w2, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w2, common_errNullObject // object was null
GET_VREG_WIDE x0, w0 // x0-< fp[A]
FETCH_ADVANCE_INST 2 // advance rPC, load wINST
add x1, x2, x3 // create a direct pointer
diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S
index fd7ca62..4faa6d2 100644
--- a/runtime/interpreter/mterp/arm64/op_packed_switch.S
+++ b/runtime/interpreter/mterp/arm64/op_packed_switch.S
@@ -16,5 +16,5 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl $func // w0<- code-unit branch offset
- sbfm xINST, x0, 0, 31
+ sxtw xINST, w0
b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S
index 0b91891..95f81c5 100644
--- a/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S
+++ b/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S
@@ -1,12 +1,10 @@
/* rem vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
bl fmodf
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG s0, w9
diff --git a/runtime/interpreter/mterp/arm64/op_shl_int.S b/runtime/interpreter/mterp/arm64/op_shl_int.S
index bd0f237..3062a3f 100644
--- a/runtime/interpreter/mterp/arm64/op_shl_int.S
+++ b/runtime/interpreter/mterp/arm64/op_shl_int.S
@@ -1 +1 @@
-%include "arm64/binop.S" {"preinstr":"and w1, w1, #31", "instr":"lsl w0, w0, w1"}
+%include "arm64/binop.S" {"instr":"lsl w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_shl_int_2addr.S b/runtime/interpreter/mterp/arm64/op_shl_int_2addr.S
index b4671d2..9a7e09f 100644
--- a/runtime/interpreter/mterp/arm64/op_shl_int_2addr.S
+++ b/runtime/interpreter/mterp/arm64/op_shl_int_2addr.S
@@ -1 +1 @@
-%include "arm64/binop2addr.S" {"preinstr":"and w1, w1, #31", "instr":"lsl w0, w0, w1"}
+%include "arm64/binop2addr.S" {"instr":"lsl w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_shl_int_lit8.S b/runtime/interpreter/mterp/arm64/op_shl_int_lit8.S
index 4dd32e0..17f57f9 100644
--- a/runtime/interpreter/mterp/arm64/op_shl_int_lit8.S
+++ b/runtime/interpreter/mterp/arm64/op_shl_int_lit8.S
@@ -1 +1 @@
-%include "arm64/binopLit8.S" {"preinstr":"and w1, w1, #31", "instr":"lsl w0, w0, w1"}
+%include "arm64/binopLit8.S" {"instr":"lsl w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_shr_int.S b/runtime/interpreter/mterp/arm64/op_shr_int.S
index c214a18..493b740 100644
--- a/runtime/interpreter/mterp/arm64/op_shr_int.S
+++ b/runtime/interpreter/mterp/arm64/op_shr_int.S
@@ -1 +1 @@
-%include "arm64/binop.S" {"preinstr":"and w1, w1, #31", "instr":"asr w0, w0, w1"}
+%include "arm64/binop.S" {"instr":"asr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_shr_int_2addr.S b/runtime/interpreter/mterp/arm64/op_shr_int_2addr.S
index 3c1484b..6efe8ee 100644
--- a/runtime/interpreter/mterp/arm64/op_shr_int_2addr.S
+++ b/runtime/interpreter/mterp/arm64/op_shr_int_2addr.S
@@ -1 +1 @@
-%include "arm64/binop2addr.S" {"preinstr":"and w1, w1, #31", "instr":"asr w0, w0, w1"}
+%include "arm64/binop2addr.S" {"instr":"asr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_shr_int_lit8.S b/runtime/interpreter/mterp/arm64/op_shr_int_lit8.S
index 26d5024..274080c 100644
--- a/runtime/interpreter/mterp/arm64/op_shr_int_lit8.S
+++ b/runtime/interpreter/mterp/arm64/op_shr_int_lit8.S
@@ -1 +1 @@
-%include "arm64/binopLit8.S" {"preinstr":"and w1, w1, #31", "instr":"asr w0, w0, w1"}
+%include "arm64/binopLit8.S" {"instr":"asr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_int.S b/runtime/interpreter/mterp/arm64/op_ushr_int.S
index bb8382b..005452b 100644
--- a/runtime/interpreter/mterp/arm64/op_ushr_int.S
+++ b/runtime/interpreter/mterp/arm64/op_ushr_int.S
@@ -1 +1 @@
-%include "arm64/binop.S" {"preinstr":"and w1, w1, #31", "instr":"lsr w0, w0, w1"}
+%include "arm64/binop.S" {"instr":"lsr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_int_2addr.S b/runtime/interpreter/mterp/arm64/op_ushr_int_2addr.S
index dbccb99..1cb8cb7 100644
--- a/runtime/interpreter/mterp/arm64/op_ushr_int_2addr.S
+++ b/runtime/interpreter/mterp/arm64/op_ushr_int_2addr.S
@@ -1 +1 @@
-%include "arm64/binop2addr.S" {"preinstr":"and w1, w1, #31", "instr":"lsr w0, w0, w1"}
+%include "arm64/binop2addr.S" {"instr":"lsr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_int_lit8.S b/runtime/interpreter/mterp/arm64/op_ushr_int_lit8.S
index 35090c4..ff30e1f 100644
--- a/runtime/interpreter/mterp/arm64/op_ushr_int_lit8.S
+++ b/runtime/interpreter/mterp/arm64/op_ushr_int_lit8.S
@@ -1 +1 @@
-%include "arm64/binopLit8.S" {"preinstr":"and w1, w1, #31", "instr":"lsr w0, w0, w1"}
+%include "arm64/binopLit8.S" {"instr":"lsr w0, w0, w1"}
diff --git a/runtime/interpreter/mterp/arm64/shiftWide.S b/runtime/interpreter/mterp/arm64/shiftWide.S
index 6306fca..dcb2fb7 100644
--- a/runtime/interpreter/mterp/arm64/shiftWide.S
+++ b/runtime/interpreter/mterp/arm64/shiftWide.S
@@ -12,8 +12,7 @@
and w1, w0, #255 // w1<- BB
GET_VREG_WIDE x1, w1 // x1<- vBB
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and x2, x2, #63 // Mask low 6
- $opcode x0, x1, x2 // Do the shift.
+ $opcode x0, x1, x2 // Do the shift. Only low 6 bits of x2 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3 // vAA<- x0
GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/shiftWide2addr.S b/runtime/interpreter/mterp/arm64/shiftWide2addr.S
index 77d104a..b860dfd 100644
--- a/runtime/interpreter/mterp/arm64/shiftWide2addr.S
+++ b/runtime/interpreter/mterp/arm64/shiftWide2addr.S
@@ -8,8 +8,7 @@
GET_VREG w1, w1 // x1<- vB
GET_VREG_WIDE x0, w2 // x0<- vA
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and x1, x1, #63 // Mask low 6 bits.
- $opcode x0, x0, x1
+ $opcode x0, x0, x1 // Do the shift. Only low 6 bits of x1 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w2 // vAA<- result
GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index 51e7163..d470551 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -747,10 +747,9 @@
.L_op_const_wide_16: /* 0x16 */
/* File: arm64/op_const_wide_16.S */
/* const-wide/16 vAA, #+BBBB */
- FETCH_S w0, 1 // w0<- ssssBBBB (sign-extended
+ FETCH_S x0, 1 // x0<- ssssssssssssBBBB (sign-extended)
lsr w3, wINST, #8 // w3<- AA
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- sbfm x0, x0, 0, 31
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3
GOTO_OPCODE ip // jump to next instruction
@@ -760,13 +759,12 @@
.L_op_const_wide_32: /* 0x17 */
/* File: arm64/op_const_wide_32.S */
/* const-wide/32 vAA, #+BBBBbbbb */
- FETCH w0, 1 // w0<- 0000bbbb (low)
+ FETCH w0, 1 // x0<- 000000000000bbbb (low)
lsr w3, wINST, #8 // w3<- AA
- FETCH_S w2, 2 // w2<- ssssBBBB (high)
+ FETCH_S x2, 2 // x2<- ssssssssssssBBBB (high)
FETCH_ADVANCE_INST 3 // advance rPC, load wINST
GET_INST_OPCODE ip // extract opcode from wINST
- orr w0, w0, w2, lsl #16 // w0<- BBBBbbbb
- sbfm x0, x0, 0, 31
+ orr x0, x0, x2, lsl #16 // x0<- ssssssssBBBBbbbb
SET_VREG_WIDE x0, w3
GOTO_OPCODE ip // jump to next instruction
@@ -934,8 +932,7 @@
mov x3, xSELF // w3<- self
bl MterpInstanceOf // (index, &obj, method, self)
ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- A+
- and w2, w2, #15 // w2<- A
+ ubfx w2, wINST, #8, #4 // w2<- A
PREFETCH_INST 2
cbnz x1, MterpException
ADVANCE 2 // advance rPC
@@ -1150,7 +1147,7 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl MterpDoPackedSwitch // w0<- code-unit branch offset
- sbfm xINST, x0, 0, 31
+ sxtw xINST, w0
b MterpCommonTakenBranchNoFlags
/* ------------------------------ */
@@ -1175,7 +1172,7 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2
bl MterpDoSparseSwitch // w0<- code-unit branch offset
- sbfm xINST, x0, 0, 31
+ sxtw xINST, w0
b MterpCommonTakenBranchNoFlags
@@ -3345,11 +3342,10 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG w0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
- sbfm x0, x0, 0, 31 // d0<- op
+ sxtw x0, w0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE x0, w4 // vA<- d0
GOTO_OPCODE ip // jump to next instruction
@@ -3369,10 +3365,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG w0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
scvtf s0, w0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG s0, w4 // vA<- d0
@@ -3392,10 +3387,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG w0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
scvtf d0, w0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE d0, w4 // vA<- d0
@@ -3415,10 +3409,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE x0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
// d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG w0, w4 // vA<- d0
@@ -3438,10 +3431,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE x0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
scvtf s0, x0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG s0, w4 // vA<- d0
@@ -3461,10 +3453,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE x0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
scvtf d0, x0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE d0, w4 // vA<- d0
@@ -3485,10 +3476,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG s0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvtzs w0, s0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG w0, w4 // vA<- d0
@@ -3508,10 +3498,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG s0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvtzs x0, s0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE x0, w4 // vA<- d0
@@ -3531,10 +3520,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG s0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvt d0, s0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE d0, w4 // vA<- d0
@@ -3554,10 +3542,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE d0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvtzs w0, d0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG w0, w4 // vA<- d0
@@ -3577,10 +3564,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE d0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvtzs x0, d0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG_WIDE x0, w4 // vA<- d0
@@ -3600,10 +3586,9 @@
*/
/* unop vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w4, wINST, #8 // w4<- A+
+ ubfx w4, wINST, #8, #4 // w4<- A
GET_VREG_WIDE d0, w3
FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- and w4, w4, #15 // w4<- A
fcvt s0, d0 // d0<- op
GET_INST_OPCODE ip // extract opcode from wINST
SET_VREG s0, w4 // vA<- d0
@@ -4032,7 +4017,7 @@
cbz w1, common_errDivideByZero // is second operand zero?
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsl w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -4071,7 +4056,7 @@
cbz w1, common_errDivideByZero // is second operand zero?
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
asr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -4110,7 +4095,7 @@
cbz w1, common_errDivideByZero // is second operand zero?
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -4424,8 +4409,7 @@
and w1, w0, #255 // w1<- BB
GET_VREG_WIDE x1, w1 // x1<- vBB
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and x2, x2, #63 // Mask low 6
- lsl x0, x1, x2 // Do the shift.
+ lsl x0, x1, x2 // Do the shift. Only low 6 bits of x2 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3 // vAA<- x0
GOTO_OPCODE ip // jump to next instruction
@@ -4450,8 +4434,7 @@
and w1, w0, #255 // w1<- BB
GET_VREG_WIDE x1, w1 // x1<- vBB
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and x2, x2, #63 // Mask low 6
- asr x0, x1, x2 // Do the shift.
+ asr x0, x1, x2 // Do the shift. Only low 6 bits of x2 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3 // vAA<- x0
GOTO_OPCODE ip // jump to next instruction
@@ -4476,8 +4459,7 @@
and w1, w0, #255 // w1<- BB
GET_VREG_WIDE x1, w1 // x1<- vBB
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and x2, x2, #63 // Mask low 6
- lsr x0, x1, x2 // Do the shift.
+ lsr x0, x1, x2 // Do the shift. Only low 6 bits of x2 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w3 // vAA<- x0
GOTO_OPCODE ip // jump to next instruction
@@ -5089,7 +5071,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsl w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -5125,7 +5107,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
asr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -5161,7 +5143,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -5463,8 +5445,7 @@
GET_VREG w1, w1 // x1<- vB
GET_VREG_WIDE x0, w2 // x0<- vA
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and x1, x1, #63 // Mask low 6 bits.
- lsl x0, x0, x1
+ lsl x0, x0, x1 // Do the shift. Only low 6 bits of x1 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w2 // vAA<- result
GOTO_OPCODE ip // jump to next instruction
@@ -5485,8 +5466,7 @@
GET_VREG w1, w1 // x1<- vB
GET_VREG_WIDE x0, w2 // x0<- vA
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and x1, x1, #63 // Mask low 6 bits.
- asr x0, x0, x1
+ asr x0, x0, x1 // Do the shift. Only low 6 bits of x1 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w2 // vAA<- result
GOTO_OPCODE ip // jump to next instruction
@@ -5507,8 +5487,7 @@
GET_VREG w1, w1 // x1<- vB
GET_VREG_WIDE x0, w2 // x0<- vA
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- and x1, x1, #63 // Mask low 6 bits.
- lsr x0, x0, x1
+ lsr x0, x0, x1 // Do the shift. Only low 6 bits of x1 are used.
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG_WIDE x0, w2 // vAA<- result
GOTO_OPCODE ip // jump to next instruction
@@ -5529,8 +5508,7 @@
*/
/* binop/2addr vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
fadd s2, s0, s1 // s2<- op
@@ -5554,8 +5532,7 @@
*/
/* binop/2addr vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
fsub s2, s0, s1 // s2<- op
@@ -5579,8 +5556,7 @@
*/
/* binop/2addr vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
fmul s2, s0, s1 // s2<- op
@@ -5604,8 +5580,7 @@
*/
/* binop/2addr vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
fdiv s2, s0, s1 // s2<- op
@@ -5621,13 +5596,11 @@
/* File: arm64/op_rem_float_2addr.S */
/* rem vA, vB */
lsr w3, wINST, #12 // w3<- B
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
GET_VREG s1, w3
GET_VREG s0, w9
bl fmodf
- lsr w9, wINST, #8 // w9<- A+
- and w9, w9, #15 // w9<- A
+ ubfx w9, wINST, #8, #4 // w9<- A
FETCH_ADVANCE_INST 1 // advance rPC, load rINST
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG s0, w9
@@ -6381,7 +6354,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsl w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -6417,7 +6390,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
asr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -6453,7 +6426,7 @@
cbz w1, common_errDivideByZero
.endif
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- and w1, w1, #31 // optional op; may set condition codes
+ // optional op; may set condition codes
lsr w0, w0, w1 // w0<- op, w0-w3 changed
GET_INST_OPCODE ip // extract opcode from rINST
SET_VREG w0, w9 // vAA<- w0
@@ -6471,8 +6444,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
ldr w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
@@ -6489,7 +6461,7 @@
FETCH w4, 1 // w4<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cbz w3, common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
add x4, x3, x4 // create direct pointer
ldr x0, [x4]
FETCH_ADVANCE_INST 2 // advance rPC, load wINST
@@ -6544,8 +6516,7 @@
FETCH w3, 1 // w3<- field byte offset
GET_VREG w2, w2 // w2<- fp[B], the object pointer
ubfx w0, wINST, #8, #4 // w0<- A
- cmp w2, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w2, common_errNullObject // object was null
GET_VREG_WIDE x0, w0 // x0-< fp[A]
FETCH_ADVANCE_INST 2 // advance rPC, load wINST
add x1, x2, x3 // create a direct pointer
@@ -6710,8 +6681,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
ldrb w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
@@ -6731,8 +6701,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
ldrsb w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
@@ -6752,8 +6721,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
ldrh w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
@@ -6773,8 +6741,7 @@
FETCH w1, 1 // w1<- field byte offset
GET_VREG w3, w2 // w3<- object we're operating on
ubfx w2, wINST, #8, #4 // w2<- A
- cmp x3, #0 // check object for null
- beq common_errNullObject // object was null
+ cbz w3, common_errNullObject // object was null
ldrsh w0, [x3, x1] // w0<- obj.field
FETCH_ADVANCE_INST 2 // advance rPC, load rINST
@@ -11521,7 +11488,7 @@
#if MTERP_LOGGING
mov x0, xSELF
add x1, xFP, #OFF_FP_SHADOWFRAME
- sbfm x2, xINST, 0, 31
+ sxtw x2, wINST
bl MterpLogOSR
#endif
mov x0, #1 // Signal normal return