diff options
author | Serban Constantinescu <serban.constantinescu@arm.com> | 2013-12-19 13:33:29 +0000 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2014-02-02 01:53:44 -0800 |
commit | a1af431e1dc63addfe1dc7138663838f89806f6b (patch) | |
tree | 5bbf05f4e6b30fd072e2c177ff7e0b40949b37e8 /vm | |
parent | a58cee84b2015474e7ca1fe4e66f5d83d6447cad (diff) | |
download | android_dalvik-a1af431e1dc63addfe1dc7138663838f89806f6b.tar.gz android_dalvik-a1af431e1dc63addfe1dc7138663838f89806f6b.tar.bz2 android_dalvik-a1af431e1dc63addfe1dc7138663838f89806f6b.zip |
Dalvik: Add sdiv support in the interpreter
This patch adds hardware divide support in the interpreter side of
dalvik. This operation is supported on new armv7 cpus such as A15 or A7.
Opcodes added:
OP_DIV_INT
OP_DIV_INT_2ADDR
OP_DIV_INT_LIT16
OP_DIV_INT_LIT8
OP_REM_INT
OP_REM_INT_2ADDR
OP_REM_INT_LIT16
OP_REM_INT_LIT8
Change-Id: Ib1ec5856d957feadd90807fe53ec34cc0e1fd4a2
Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
Diffstat (limited to 'vm')
-rw-r--r-- | vm/mterp/armv7-a/OP_DIV_INT.S | 31 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_DIV_INT_2ADDR.S | 30 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_DIV_INT_LIT16.S | 29 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_DIV_INT_LIT8.S | 30 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_REM_INT.S | 34 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_REM_INT_2ADDR.S | 33 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_REM_INT_LIT16.S | 32 | ||||
-rw-r--r-- | vm/mterp/armv7-a/OP_REM_INT_LIT8.S | 33 | ||||
-rw-r--r-- | vm/mterp/config-armv7-a | 12 | ||||
-rw-r--r-- | vm/mterp/config-armv7-a-neon | 12 | ||||
-rw-r--r-- | vm/mterp/out/InterpAsm-armv7-a-neon.S | 268 | ||||
-rw-r--r-- | vm/mterp/out/InterpAsm-armv7-a.S | 268 |
12 files changed, 504 insertions, 308 deletions
diff --git a/vm/mterp/armv7-a/OP_DIV_INT.S b/vm/mterp/armv7-a/OP_DIV_INT.S new file mode 100644 index 000000000..9c88b2600 --- /dev/null +++ b/vm/mterp/armv7-a/OP_DIV_INT.S @@ -0,0 +1,31 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int + * + */ + FETCH(r0, 1) @ r0<- CCBB + mov r9, rINST, lsr #8 @ r9<- AA + mov r3, r0, lsr #8 @ r3<- CC + and r2, r0, #255 @ r2<- BB + GET_VREG(r1, r3) @ r1<- vCC + GET_VREG(r0, r2) @ r0<- vBB + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction + /* 11-14 instructions */ diff --git a/vm/mterp/armv7-a/OP_DIV_INT_2ADDR.S b/vm/mterp/armv7-a/OP_DIV_INT_2ADDR.S new file mode 100644 index 000000000..be6de6d11 --- /dev/null +++ b/vm/mterp/armv7-a/OP_DIV_INT_2ADDR.S @@ -0,0 +1,30 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/2addr + * + */ + mov r3, rINST, lsr #12 @ r3<- B + ubfx r9, rINST, #8, #4 @ r9<- A + GET_VREG(r1, r3) @ r1<- vB + GET_VREG(r0, r9) @ r0<- vA + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(1) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-13 instructions */ + diff --git a/vm/mterp/armv7-a/OP_DIV_INT_LIT16.S b/vm/mterp/armv7-a/OP_DIV_INT_LIT16.S new file mode 100644 index 000000000..f140c3cf1 --- /dev/null +++ b/vm/mterp/armv7-a/OP_DIV_INT_LIT16.S @@ -0,0 +1,29 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit16 + * + */ + FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) + mov r2, rINST, lsr #12 @ r2<- B + ubfx r9, rINST, #8, #4 @ r9<- A + GET_VREG(r0, r2) @ r0<- vB + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-13 instructions */ diff --git a/vm/mterp/armv7-a/OP_DIV_INT_LIT8.S b/vm/mterp/armv7-a/OP_DIV_INT_LIT8.S new file mode 100644 index 000000000..08d67fa4e --- /dev/null +++ b/vm/mterp/armv7-a/OP_DIV_INT_LIT8.S @@ -0,0 +1,30 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit8 + * + */ + FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) + mov r9, rINST, lsr #8 @ r9<- AA + and r2, r3, #255 @ r2<- BB + GET_VREG(r0, r2) @ r0<- vBB + movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) + @cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-12 instructions */ diff --git a/vm/mterp/armv7-a/OP_REM_INT.S b/vm/mterp/armv7-a/OP_REM_INT.S new file mode 100644 index 000000000..cd033381c --- /dev/null +++ b/vm/mterp/armv7-a/OP_REM_INT.S @@ -0,0 +1,34 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int + * + */ + FETCH(r0, 1) @ r0<- CCBB + mov r9, rINST, lsr #8 @ r9<- AA + mov r3, r0, lsr #8 @ r3<- CC + and r2, r0, #255 @ r2<- BB + GET_VREG(r1, r3) @ r1<- vCC + GET_VREG(r0, r2) @ r0<- vBB + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op, r0-r2 changed +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r1, r9) @ vAA<- r1 + GOTO_OPCODE(ip) @ jump to next instruction + /* 11-14 instructions */ diff --git a/vm/mterp/armv7-a/OP_REM_INT_2ADDR.S b/vm/mterp/armv7-a/OP_REM_INT_2ADDR.S new file mode 100644 index 000000000..509964274 --- /dev/null +++ b/vm/mterp/armv7-a/OP_REM_INT_2ADDR.S @@ -0,0 +1,33 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/2addr + * + */ + mov r3, rINST, lsr #12 @ r3<- B + ubfx r9, rINST, #8, #4 @ r9<- A + GET_VREG(r1, r3) @ r1<- vB + GET_VREG(r0, r9) @ r0<- vA + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(1) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r1, r9) @ vAA<- r1 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-13 instructions */ + diff --git a/vm/mterp/armv7-a/OP_REM_INT_LIT16.S b/vm/mterp/armv7-a/OP_REM_INT_LIT16.S new file mode 100644 index 000000000..3fc86a405 --- /dev/null +++ b/vm/mterp/armv7-a/OP_REM_INT_LIT16.S @@ -0,0 +1,32 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit16 + * + */ + FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) + mov r2, rINST, lsr #12 @ r2<- B + ubfx r9, rINST, #8, #4 @ r9<- A + GET_VREG(r0, r2) @ r0<- vB + cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r1, r9) @ vAA<- r1 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-13 instructions */ diff --git a/vm/mterp/armv7-a/OP_REM_INT_LIT8.S b/vm/mterp/armv7-a/OP_REM_INT_LIT8.S new file mode 100644 index 000000000..61bffff98 --- /dev/null +++ b/vm/mterp/armv7-a/OP_REM_INT_LIT8.S @@ -0,0 +1,33 @@ +%default {} +%verify "executed" + /* + * Specialized 32-bit binary operation + * + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit8 + * + */ + FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) + mov r9, rINST, lsr #8 @ r9<- AA + and r2, r3, #255 @ r2<- BB + GET_VREG(r0, r2) @ r0<- vBB + movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) + @cmp r1, #0 @ is second operand zero? + beq common_errDivideByZero + FETCH_ADVANCE_INST(2) @ advance rPC, load rINST + +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif + GET_INST_OPCODE(ip) @ extract opcode from rINST + SET_VREG(r1, r9) @ vAA<- r1 + GOTO_OPCODE(ip) @ jump to next instruction + /* 10-12 instructions */ diff --git a/vm/mterp/config-armv7-a b/vm/mterp/config-armv7-a index eadaeca35..3f609ce0c 100644 --- a/vm/mterp/config-armv7-a +++ b/vm/mterp/config-armv7-a @@ -61,8 +61,10 @@ op-start armv5te op OP_CONST_4 armv6t2 op OP_DIV_DOUBLE_2ADDR armv6t2 op OP_DIV_FLOAT_2ADDR armv6t2 - op OP_DIV_INT_2ADDR armv6t2 - op OP_DIV_INT_LIT16 armv6t2 + op OP_DIV_INT armv7-a + op OP_DIV_INT_2ADDR armv7-a + op OP_DIV_INT_LIT16 armv7-a + op OP_DIV_INT_LIT8 armv7-a op OP_DIV_LONG_2ADDR armv6t2 op OP_DOUBLE_TO_FLOAT armv6t2 op OP_DOUBLE_TO_INT armv6t2 @@ -110,8 +112,10 @@ op-start armv5te op OP_OR_LONG_2ADDR armv6t2 op OP_REM_DOUBLE_2ADDR armv6t2 op OP_REM_FLOAT_2ADDR armv6t2 - op OP_REM_INT_2ADDR armv6t2 - op OP_REM_INT_LIT16 armv6t2 + op OP_REM_INT armv7-a + op OP_REM_INT_2ADDR armv7-a + op OP_REM_INT_LIT16 armv7-a + op OP_REM_INT_LIT8 armv7-a op OP_REM_LONG_2ADDR armv6t2 op OP_RSUB_INT armv6t2 op OP_SHL_INT_2ADDR armv6t2 diff --git a/vm/mterp/config-armv7-a-neon b/vm/mterp/config-armv7-a-neon index 5f91365e0..7f4295023 100644 --- a/vm/mterp/config-armv7-a-neon +++ b/vm/mterp/config-armv7-a-neon @@ -61,8 +61,10 @@ op-start armv5te op OP_CONST_4 armv6t2 op OP_DIV_DOUBLE_2ADDR armv6t2 op OP_DIV_FLOAT_2ADDR armv6t2 - op OP_DIV_INT_2ADDR armv6t2 - op OP_DIV_INT_LIT16 armv6t2 + op OP_DIV_INT armv7-a + op OP_DIV_INT_2ADDR armv7-a + op OP_DIV_INT_LIT16 armv7-a + op OP_DIV_INT_LIT8 armv7-a op OP_DIV_LONG_2ADDR armv6t2 op OP_DOUBLE_TO_FLOAT armv6t2 op OP_DOUBLE_TO_INT armv6t2 @@ -110,8 +112,10 @@ op-start armv5te op OP_OR_LONG_2ADDR armv6t2 op OP_REM_DOUBLE_2ADDR armv6t2 op OP_REM_FLOAT_2ADDR armv6t2 - op OP_REM_INT_2ADDR armv6t2 - op OP_REM_INT_LIT16 armv6t2 + op OP_REM_INT armv7-a + op OP_REM_INT_2ADDR armv7-a + op OP_REM_INT_LIT16 armv7-a + op OP_REM_INT_LIT8 armv7-a op OP_REM_LONG_2ADDR armv6t2 op OP_RSUB_INT armv6t2 op OP_SHL_INT_2ADDR armv6t2 diff --git a/vm/mterp/out/InterpAsm-armv7-a-neon.S b/vm/mterp/out/InterpAsm-armv7-a-neon.S index d86d0bde2..9dc851c08 100644 --- a/vm/mterp/out/InterpAsm-armv7-a-neon.S +++ b/vm/mterp/out/InterpAsm-armv7-a-neon.S @@ -4053,86 +4053,74 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT: /* 0x93 */ -/* File: armv5te/OP_DIV_INT.S */ -/* File: armv5te/binop.S */ +/* File: armv7-a/OP_DIV_INT.S */ /* - * Generic 32-bit binary operation. Provide an "instr" line that - * specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. Note that we - * *don't* check for (INT_MIN / -1) here, because the ARM math lib - * handles it correctly. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int * - * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, - * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, - * mul-float, div-float, rem-float */ - /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 11-14 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT: /* 0x94 */ -/* File: armv5te/OP_REM_INT.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv5te/binop.S */ +/* File: armv7-a/OP_REM_INT.S */ /* - * Generic 32-bit binary operation. Provide an "instr" line that - * specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. Note that we - * *don't* check for (INT_MIN / -1) here, because the ARM math lib - * handles it correctly. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int * - * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, - * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, - * mul-float, div-float, rem-float */ - /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op, r0-r2 changed +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 11-14 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT: /* 0x95 */ @@ -5259,37 +5247,32 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ -/* File: armv6t2/OP_DIV_INT_2ADDR.S */ -/* File: armv6t2/binop2addr.S */ +/* File: armv7-a/OP_DIV_INT_2ADDR.S */ /* - * Generic 32-bit "/2addr" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/2addr * - * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, - * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, - * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, - * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr */ - /* binop/2addr vA, vB */ mov r3, rINST, lsr #12 @ r3<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r1, r3) @ r1<- vB GET_VREG(r0, r9) @ r0<- vA - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(1) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ @@ -5297,38 +5280,35 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_REM_INT_2ADDR: /* 0xb4 */ -/* File: armv6t2/OP_REM_INT_2ADDR.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv6t2/binop2addr.S */ +/* File: armv7-a/OP_REM_INT_2ADDR.S */ /* - * Generic 32-bit "/2addr" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/2addr * - * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, - * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, - * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, - * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr */ - /* binop/2addr vA, vB */ mov r3, rINST, lsr #12 @ r3<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r1, r3) @ r1<- vB GET_VREG(r0, r9) @ r0<- vA - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(1) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ @@ -6364,74 +6344,70 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_LIT16: /* 0xd3 */ -/* File: armv6t2/OP_DIV_INT_LIT16.S */ -/* File: armv6t2/binopLit16.S */ +/* File: armv7-a/OP_DIV_INT_LIT16.S */ /* - * Generic 32-bit "lit16" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit16 * - * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, - * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 */ - /* binop/lit16 vA, vB, #+CCCC */ FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) mov r2, rINST, lsr #12 @ r2<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r0, r2) @ r0<- vB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT_LIT16: /* 0xd4 */ -/* File: armv6t2/OP_REM_INT_LIT16.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv6t2/binopLit16.S */ +/* File: armv7-a/OP_REM_INT_LIT16.S */ /* - * Generic 32-bit "lit16" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit16 * - * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, - * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 */ - /* binop/lit16 vA, vB, #+CCCC */ FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) mov r2, rINST, lsr #12 @ r2<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r0, r2) @ r0<- vB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT_LIT16: /* 0xd5 */ @@ -6655,80 +6631,72 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_LIT8: /* 0xdb */ -/* File: armv5te/OP_DIV_INT_LIT8.S */ -/* File: armv5te/binopLit8.S */ +/* File: armv7-a/OP_DIV_INT_LIT8.S */ /* - * Generic 32-bit "lit8" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit8 * - * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, - * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, - * shl-int/lit8, shr-int/lit8, ushr-int/lit8 */ - /* binop/lit8 vAA, vBB, #+CC */ FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) mov r9, rINST, lsr #8 @ r9<- AA and r2, r3, #255 @ r2<- BB GET_VREG(r0, r2) @ r0<- vBB movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) - .if 1 - @cmp r1, #0 @ is second operand zero? + @cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-12 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT_LIT8: /* 0xdc */ -/* File: armv5te/OP_REM_INT_LIT8.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv5te/binopLit8.S */ +/* File: armv7-a/OP_REM_INT_LIT8.S */ /* - * Generic 32-bit "lit8" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit8 * - * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, - * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, - * shl-int/lit8, shr-int/lit8, ushr-int/lit8 */ - /* binop/lit8 vAA, vBB, #+CC */ FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) mov r9, rINST, lsr #8 @ r9<- AA and r2, r3, #255 @ r2<- BB GET_VREG(r0, r2) @ r0<- vBB movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) - .if 1 - @cmp r1, #0 @ is second operand zero? + @cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-12 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT_LIT8: /* 0xdd */ diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S index 7e4741358..5d598a2c9 100644 --- a/vm/mterp/out/InterpAsm-armv7-a.S +++ b/vm/mterp/out/InterpAsm-armv7-a.S @@ -4053,86 +4053,74 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT: /* 0x93 */ -/* File: armv5te/OP_DIV_INT.S */ -/* File: armv5te/binop.S */ +/* File: armv7-a/OP_DIV_INT.S */ /* - * Generic 32-bit binary operation. Provide an "instr" line that - * specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. Note that we - * *don't* check for (INT_MIN / -1) here, because the ARM math lib - * handles it correctly. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int * - * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, - * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, - * mul-float, div-float, rem-float */ - /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 11-14 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT: /* 0x94 */ -/* File: armv5te/OP_REM_INT.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv5te/binop.S */ +/* File: armv7-a/OP_REM_INT.S */ /* - * Generic 32-bit binary operation. Provide an "instr" line that - * specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. Note that we - * *don't* check for (INT_MIN / -1) here, because the ARM math lib - * handles it correctly. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int * - * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, - * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, - * mul-float, div-float, rem-float */ - /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op, r0-r2 changed +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 11-14 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT: /* 0x95 */ @@ -5259,37 +5247,32 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ -/* File: armv6t2/OP_DIV_INT_2ADDR.S */ -/* File: armv6t2/binop2addr.S */ +/* File: armv7-a/OP_DIV_INT_2ADDR.S */ /* - * Generic 32-bit "/2addr" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/2addr * - * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, - * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, - * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, - * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr */ - /* binop/2addr vA, vB */ mov r3, rINST, lsr #12 @ r3<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r1, r3) @ r1<- vB GET_VREG(r0, r9) @ r0<- vA - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(1) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ @@ -5297,38 +5280,35 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_REM_INT_2ADDR: /* 0xb4 */ -/* File: armv6t2/OP_REM_INT_2ADDR.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv6t2/binop2addr.S */ +/* File: armv7-a/OP_REM_INT_2ADDR.S */ /* - * Generic 32-bit "/2addr" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/2addr * - * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, - * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, - * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, - * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr */ - /* binop/2addr vA, vB */ mov r3, rINST, lsr #12 @ r3<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r1, r3) @ r1<- vB GET_VREG(r0, r9) @ r0<- vA - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(1) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ @@ -6364,74 +6344,70 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_LIT16: /* 0xd3 */ -/* File: armv6t2/OP_DIV_INT_LIT16.S */ -/* File: armv6t2/binopLit16.S */ +/* File: armv7-a/OP_DIV_INT_LIT16.S */ /* - * Generic 32-bit "lit16" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit16 * - * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, - * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 */ - /* binop/lit16 vA, vB, #+CCCC */ FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) mov r2, rINST, lsr #12 @ r2<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r0, r2) @ r0<- vB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT_LIT16: /* 0xd4 */ -/* File: armv6t2/OP_REM_INT_LIT16.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv6t2/binopLit16.S */ +/* File: armv7-a/OP_REM_INT_LIT16.S */ /* - * Generic 32-bit "lit16" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit16 * - * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, - * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 */ - /* binop/lit16 vA, vB, #+CCCC */ FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) mov r2, rINST, lsr #12 @ r2<- B ubfx r9, rINST, #8, #4 @ r9<- A GET_VREG(r0, r2) @ r0<- vB - .if 1 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-13 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT_LIT16: /* 0xd5 */ @@ -6655,80 +6631,72 @@ dalvik_inst: /* ------------------------------ */ .balign 64 .L_OP_DIV_INT_LIT8: /* 0xdb */ -/* File: armv5te/OP_DIV_INT_LIT8.S */ -/* File: armv5te/binopLit8.S */ +/* File: armv7-a/OP_DIV_INT_LIT8.S */ /* - * Generic 32-bit "lit8" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r0 = r0 div r1". The selection between sdiv or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * div-int/lit8 * - * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, - * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, - * shl-int/lit8, shr-int/lit8, ushr-int/lit8 */ - /* binop/lit8 vAA, vBB, #+CC */ FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) mov r9, rINST, lsr #8 @ r9<- AA and r2, r3, #255 @ r2<- BB GET_VREG(r0, r2) @ r0<- vBB movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) - .if 1 - @cmp r1, #0 @ is second operand zero? + @cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idiv @ r0<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r0, r0, r1 @ r0<- op +#else + bl __aeabi_idiv @ r0<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r0, r9) @ vAA<- r0 + SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 10-12 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_REM_INT_LIT8: /* 0xdc */ -/* File: armv5te/OP_REM_INT_LIT8.S */ -/* idivmod returns quotient in r0 and remainder in r1 */ -/* File: armv5te/binopLit8.S */ +/* File: armv7-a/OP_REM_INT_LIT8.S */ /* - * Generic 32-bit "lit8" binary operation. Provide an "instr" line - * that specifies an instruction that performs "result = r0 op r1". - * This could be an ARM instruction or a function call. (If the result - * comes back in a register other than r0, you can override "result".) + * Specialized 32-bit binary operation * - * If "chkzero" is set to 1, we perform a divide-by-zero check on - * vCC (r1). Useful for integer division and modulus. + * Performs "r1 = r0 rem r1". The selection between sdiv block or the gcc helper + * depends on the compile time value of __ARM_ARCH_EXT_IDIV__ (defined for + * ARMv7 CPUs that have hardware division support). + * + * NOTE: idivmod returns quotient in r0 and remainder in r1 + * + * rem-int/lit8 * - * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, - * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, - * shl-int/lit8, shr-int/lit8, ushr-int/lit8 */ - /* binop/lit8 vAA, vBB, #+CC */ FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) mov r9, rINST, lsr #8 @ r9<- AA and r2, r3, #255 @ r2<- BB GET_VREG(r0, r2) @ r0<- vBB movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) - .if 1 - @cmp r1, #0 @ is second operand zero? + @cmp r1, #0 @ is second operand zero? beq common_errDivideByZero - .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST - @ optional op; may set condition codes - bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#ifdef __ARM_ARCH_EXT_IDIV__ + sdiv r2, r0, r1 + mls r1, r1, r2, r0 @ r1<- op +#else + bl __aeabi_idivmod @ r1<- op, r0-r3 changed +#endif GET_INST_OPCODE(ip) @ extract opcode from rINST - SET_VREG(r1, r9) @ vAA<- r1 + SET_VREG(r1, r9) @ vAA<- r1 GOTO_OPCODE(ip) @ jump to next instruction /* 10-12 instructions */ - /* ------------------------------ */ .balign 64 .L_OP_AND_INT_LIT8: /* 0xdd */ |