Group mterp files
Group hundreds of tiny files into larger files
(but still less than 1000 lines of code each).
This should make editing and reviews simpler.
This CL is just simple file concatenation.
The filenames don't have any meaning any more.
The generated assembly output is still the same.
Test: test-art-host-gtest
Change-Id: Iee493f334999c2e06a72e19d3c065d19c67323f1
diff --git a/runtime/interpreter/mterp/arm/alt_stub.S b/runtime/interpreter/mterp/arm/alt_stub.S
deleted file mode 100644
index 9e6f91e..0000000
--- a/runtime/interpreter/mterp/arm/alt_stub.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Note that the call to MterpCheckBefore is done as a tail call.
- */
- .extern MterpCheckBefore
- ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh IBASE.
- adr lr, .L_ALT_${opcode}
- sub lr, lr, #(.L_ALT_${opcode} - .L_${opcode}) @ Addr of primary handler.
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rPC
- b MterpCheckBefore @ (self, shadow_frame, dex_pc_ptr) @ Tail call.
diff --git a/runtime/interpreter/mterp/arm/arithmetic.S b/runtime/interpreter/mterp/arm/arithmetic.S
new file mode 100644
index 0000000..6413b63
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/arithmetic.S
@@ -0,0 +1,975 @@
+%def binop(preinstr="", result="r0", chkzero="0", instr=""):
+ /*
+ * 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".)
+ *
+ * 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.
+ *
+ * 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 $chkzero
+ cmp r1, #0 @ is second operand zero?
+ beq common_errDivideByZero
+ .endif
+
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $preinstr @ optional op; may set condition codes
+ $instr @ $result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG $result, r9 @ vAA<- $result
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 11-14 instructions */
+
+%def binop2addr(preinstr="", result="r0", chkzero="0", instr=""):
+ /*
+ * 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".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (r1). Useful for integer division and modulus.
+ *
+ * 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 $chkzero
+ cmp r1, #0 @ is second operand zero?
+ beq common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+
+ $preinstr @ optional op; may set condition codes
+ $instr @ $result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG $result, r9 @ vAA<- $result
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 10-13 instructions */
+
+%def binopLit16(result="r0", chkzero="0", instr=""):
+ /*
+ * 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".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (r1). Useful for integer division and modulus.
+ *
+ * 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 $chkzero
+ cmp r1, #0 @ is second operand zero?
+ beq common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+
+ $instr @ $result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG $result, r9 @ vAA<- $result
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 10-13 instructions */
+
+%def binopLit8(extract="asr r1, r3, #8", result="r0", chkzero="0", instr=""):
+ /*
+ * 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".)
+ *
+ * You can override "extract" if the extraction of the literal value
+ * from r3 to r1 is not the default "asr r1, r3, #8". The extraction
+ * can be omitted completely if the shift is embedded in "instr".
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (r1). Useful for integer division and modulus.
+ *
+ * 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
+ $extract @ optional; typically r1<- ssssssCC (sign extended)
+ .if $chkzero
+ @cmp r1, #0 @ is second operand zero?
+ beq common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+
+ $instr @ $result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG $result, r9 @ vAA<- $result
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 10-12 instructions */
+
+%def binopWide(preinstr="", result0="r0", result1="r1", chkzero="0", instr=""):
+ /*
+ * Generic 64-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = r0-r1 op r2-r3".
+ * 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".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (r1). Useful for integer division and modulus.
+ *
+ * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
+ * xor-long, add-double, sub-double, mul-double, div-double,
+ * rem-double
+ *
+ * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov rINST, rINST, lsr #8 @ rINST<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[AA]
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
+ ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
+ ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
+ .if $chkzero
+ orrs ip, r2, r3 @ second arg (r2-r3) is zero?
+ beq common_errDivideByZero
+ .endif
+ CLEAR_SHADOW_PAIR rINST, lr, ip @ Zero out the shadow regs
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $preinstr @ optional op; may set condition codes
+ $instr @ result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {$result0,$result1} @ vAA/vAA+1<- $result0/$result1
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 14-17 instructions */
+
+%def binopWide2addr(preinstr="", result0="r0", result1="r1", chkzero="0", instr=""):
+ /*
+ * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = r0-r1 op r2-r3".
+ * 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".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (r1). Useful for integer division and modulus.
+ *
+ * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
+ * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
+ * sub-double/2addr, mul-double/2addr, div-double/2addr,
+ * rem-double/2addr
+ */
+ /* binop/2addr vA, vB */
+ mov r1, rINST, lsr #12 @ r1<- B
+ ubfx rINST, rINST, #8, #4 @ rINST<- A
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &fp[B]
+ VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
+ ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1
+ ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
+ .if $chkzero
+ orrs ip, r2, r3 @ second arg (r2-r3) is zero?
+ beq common_errDivideByZero
+ .endif
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $preinstr @ optional op; may set condition codes
+ $instr @ result<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {$result0,$result1} @ vAA/vAA+1<- $result0/$result1
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 12-15 instructions */
+
+%def unop(preinstr="", instr=""):
+ /*
+ * Generic 32-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op r0".
+ * This could be an ARM instruction or a function call.
+ *
+ * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
+ * int-to-byte, int-to-char, int-to-short
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ GET_VREG r0, r3 @ r0<- vB
+ $preinstr @ optional op; may set condition codes
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $instr @ r0<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG r0, r9 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 8-9 instructions */
+
+%def unopNarrower(preinstr="", instr=""):
+ /*
+ * Generic 64bit-to-32bit unary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = op r0/r1", where
+ * "result" is a 32-bit quantity in r0.
+ *
+ * For: long-to-float, double-to-int, double-to-float
+ *
+ * (This would work for long-to-int, but that instruction is actually
+ * an exact match for op_move.)
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
+ ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $preinstr @ optional op; may set condition codes
+ $instr @ r0<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG r0, r9 @ vA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 9-10 instructions */
+
+%def unopWide(preinstr="", instr=""):
+ /*
+ * Generic 64-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op r0/r1".
+ * This could be an ARM instruction or a function call.
+ *
+ * For: neg-long, not-long, neg-double, long-to-double, double-to-long
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx rINST, rINST, #8, #4 @ rINST<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
+ VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
+ ldmia r3, {r0-r1} @ r0/r1<- vAA
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $preinstr @ optional op; may set condition codes
+ $instr @ r0/r1<- op, r2-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 10-11 instructions */
+
+%def unopWider(preinstr="", instr=""):
+ /*
+ * Generic 32bit-to-64bit unary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = op r0", where
+ * "result" is a 64-bit quantity in r0/r1.
+ *
+ * For: int-to-long, int-to-double, float-to-long, float-to-double
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx rINST, rINST, #8, #4 @ rINST<- A
+ GET_VREG r0, r3 @ r0<- vB
+ VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
+ $preinstr @ optional op; may set condition codes
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $instr @ r0<- op, r0-r3 changed
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vA/vA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+ /* 9-10 instructions */
+
+%def op_add_int():
+% binop(instr="add r0, r0, r1")
+
+%def op_add_int_2addr():
+% binop2addr(instr="add r0, r0, r1")
+
+%def op_add_int_lit16():
+% binopLit16(instr="add r0, r0, r1")
+
+%def op_add_int_lit8():
+% binopLit8(extract="", instr="add r0, r0, r3, asr #8")
+
+%def op_add_long():
+% binopWide(preinstr="adds r0, r0, r2", instr="adc r1, r1, r3")
+
+%def op_add_long_2addr():
+% binopWide2addr(preinstr="adds r0, r0, r2", instr="adc r1, r1, r3")
+
+%def op_and_int():
+% binop(instr="and r0, r0, r1")
+
+%def op_and_int_2addr():
+% binop2addr(instr="and r0, r0, r1")
+
+%def op_and_int_lit16():
+% binopLit16(instr="and r0, r0, r1")
+
+%def op_and_int_lit8():
+% binopLit8(extract="", instr="and r0, r0, r3, asr #8")
+
+%def op_and_long():
+% binopWide(preinstr="and r0, r0, r2", instr="and r1, r1, r3")
+
+%def op_and_long_2addr():
+% binopWide2addr(preinstr="and r0, r0, r2", instr="and r1, r1, r3")
+
+%def op_cmp_long():
+ /*
+ * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
+ * register based on the results of the comparison.
+ */
+ /* cmp-long vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
+ ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
+ ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
+ cmp r0, r2
+ sbcs ip, r1, r3 @ Sets correct CCs for checking LT (but not EQ/NE)
+ mov ip, #0
+ mvnlt ip, #0 @ -1
+ cmpeq r0, r2 @ For correct EQ/NE, we may need to repeat the first CMP
+ orrne ip, #1
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ SET_VREG ip, r9 @ vAA<- ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_div_int():
+ /*
+ * 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 */
+
+%def op_div_int_2addr():
+ /*
+ * 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 */
+
+
+%def op_div_int_lit16():
+ /*
+ * 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 */
+
+%def op_div_int_lit8():
+ /*
+ * 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 */
+
+%def op_div_long():
+% binopWide(instr="bl __aeabi_ldivmod", chkzero="1")
+
+%def op_div_long_2addr():
+% binopWide2addr(instr="bl __aeabi_ldivmod", chkzero="1")
+
+%def op_int_to_byte():
+% unop(instr="sxtb r0, r0")
+
+%def op_int_to_char():
+% unop(instr="uxth r0, r0")
+
+%def op_int_to_long():
+% unopWider(instr="mov r1, r0, asr #31")
+
+%def op_int_to_short():
+% unop(instr="sxth r0, r0")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
+% binop(instr="mul r0, r1, r0")
+
+%def op_mul_int_2addr():
+/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
+% binop2addr(instr="mul r0, r1, r0")
+
+%def op_mul_int_lit16():
+/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
+% binopLit16(instr="mul r0, r1, r0")
+
+%def op_mul_int_lit8():
+/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
+% binopLit8(instr="mul r0, r1, r0")
+
+%def op_mul_long():
+ /*
+ * Signed 64-bit integer multiply.
+ *
+ * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
+ * WX
+ * x YZ
+ * --------
+ * ZW ZX
+ * YW YX
+ *
+ * The low word of the result holds ZX, the high word holds
+ * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because
+ * it doesn't fit in the low 64 bits.
+ *
+ * Unlike most ARM math operations, multiply instructions have
+ * restrictions on using the same register more than once (Rd and Rm
+ * cannot be the same).
+ */
+ /* mul-long vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
+ ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
+ ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
+ mul ip, r2, r1 @ ip<- ZxW
+ umull r1, lr, r2, r0 @ r1/lr <- ZxX
+ mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
+ mov r0, rINST, lsr #8 @ r0<- AA
+ add r2, r2, lr @ r2<- lr + low(ZxW + (YxX))
+ CLEAR_SHADOW_PAIR r0, lr, ip @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r0, r0 @ r0<- &fp[AA]
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r0, {r1-r2 } @ vAA/vAA+1<- r1/r2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_mul_long_2addr():
+ /*
+ * Signed 64-bit integer multiply, "/2addr" version.
+ *
+ * See op_mul_long for an explanation.
+ *
+ * We get a little tight on registers, so to avoid looking up &fp[A]
+ * again we stuff it into rINST.
+ */
+ /* mul-long/2addr vA, vB */
+ mov r1, rINST, lsr #12 @ r1<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &fp[B]
+ VREG_INDEX_TO_ADDR rINST, r9 @ rINST<- &fp[A]
+ ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1
+ ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1
+ mul ip, r2, r1 @ ip<- ZxW
+ umull r1, lr, r2, r0 @ r1/lr <- ZxX
+ mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
+ mov r0, rINST @ r0<- &fp[A] (free up rINST)
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ add r2, r2, lr @ r2<- r2 + low(ZxW + (YxX))
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r0, {r1-r2} @ vAA/vAA+1<- r1/r2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_neg_int():
+% unop(instr="rsb r0, r0, #0")
+
+%def op_neg_long():
+% unopWide(preinstr="rsbs r0, r0, #0", instr="rsc r1, r1, #0")
+
+%def op_not_int():
+% unop(instr="mvn r0, r0")
+
+%def op_not_long():
+% unopWide(preinstr="mvn r0, r0", instr="mvn r1, r1")
+
+%def op_or_int():
+% binop(instr="orr r0, r0, r1")
+
+%def op_or_int_2addr():
+% binop2addr(instr="orr r0, r0, r1")
+
+%def op_or_int_lit16():
+% binopLit16(instr="orr r0, r0, r1")
+
+%def op_or_int_lit8():
+% binopLit8(extract="", instr="orr r0, r0, r3, asr #8")
+
+%def op_or_long():
+% binopWide(preinstr="orr r0, r0, r2", instr="orr r1, r1, r3")
+
+%def op_or_long_2addr():
+% binopWide2addr(preinstr="orr r0, r0, r2", instr="orr r1, r1, r3")
+
+%def op_rem_int():
+ /*
+ * 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 */
+
+%def op_rem_int_2addr():
+ /*
+ * 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 */
+
+
+%def op_rem_int_lit16():
+ /*
+ * 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 */
+
+%def op_rem_int_lit8():
+ /*
+ * 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 */
+
+%def op_rem_long():
+/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
+% binopWide(instr="bl __aeabi_ldivmod", result0="r2", result1="r3", chkzero="1")
+
+%def op_rem_long_2addr():
+/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
+% binopWide2addr(instr="bl __aeabi_ldivmod", result0="r2", result1="r3", chkzero="1")
+
+%def op_rsub_int():
+/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
+% binopLit16(instr="rsb r0, r0, r1")
+
+%def op_rsub_int_lit8():
+% binopLit8(extract="", instr="rsb r0, r0, r3, asr #8")
+
+%def op_shl_int():
+% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, asl r1")
+
+%def op_shl_int_2addr():
+% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, asl r1")
+
+%def op_shl_int_lit8():
+% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, asl r1")
+
+%def op_shl_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* shl-long vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r3, r0, #255 @ r3<- BB
+ mov r0, r0, lsr #8 @ r0<- CC
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
+ GET_VREG r2, r0 @ r2<- vCC
+ ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ and r2, r2, #63 @ r2<- r2 & 0x3f
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ mov r1, r1, asl r2 @ r1<- r1 << r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mov r0, r0, asl r2 @ r0<- r0 << r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_shl_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shl-long/2addr vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ GET_VREG r2, r3 @ r2<- vB
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
+ and r2, r2, #63 @ r2<- r2 & 0x3f
+ ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
+ mov r1, r1, asl r2 @ r1<- r1 << r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
+ mov r0, r0, asl r2 @ r0<- r0 << r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_shr_int():
+% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, asr r1")
+
+%def op_shr_int_2addr():
+% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, asr r1")
+
+%def op_shr_int_lit8():
+% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, asr r1")
+
+%def op_shr_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* shr-long vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r3, r0, #255 @ r3<- BB
+ mov r0, r0, lsr #8 @ r0<- CC
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
+ GET_VREG r2, r0 @ r2<- vCC
+ ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ and r2, r2, #63 @ r0<- r0 & 0x3f
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ mov r0, r0, lsr r2 @ r0<- r2 >> r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mov r1, r1, asr r2 @ r1<- r1 >> r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_shr_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shr-long/2addr vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ GET_VREG r2, r3 @ r2<- vB
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
+ and r2, r2, #63 @ r2<- r2 & 0x3f
+ ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
+ mov r0, r0, lsr r2 @ r0<- r2 >> r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
+ mov r1, r1, asr r2 @ r1<- r1 >> r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_sub_int():
+% binop(instr="sub r0, r0, r1")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="sub r0, r0, r1")
+
+%def op_sub_long():
+% binopWide(preinstr="subs r0, r0, r2", instr="sbc r1, r1, r3")
+
+%def op_sub_long_2addr():
+% binopWide2addr(preinstr="subs r0, r0, r2", instr="sbc r1, r1, r3")
+
+%def op_ushr_int():
+% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, lsr r1")
+
+%def op_ushr_int_2addr():
+% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, lsr r1")
+
+%def op_ushr_int_lit8():
+% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, lsr r1")
+
+%def op_ushr_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* ushr-long vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r3, r0, #255 @ r3<- BB
+ mov r0, r0, lsr #8 @ r0<- CC
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
+ GET_VREG r2, r0 @ r2<- vCC
+ ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ and r2, r2, #63 @ r0<- r0 & 0x3f
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ mov r0, r0, lsr r2 @ r0<- r2 >> r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mov r1, r1, lsr r2 @ r1<- r1 >>> r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_ushr_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* ushr-long/2addr vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ GET_VREG r2, r3 @ r2<- vB
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
+ and r2, r2, #63 @ r2<- r2 & 0x3f
+ ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
+ mov r0, r0, lsr r2 @ r0<- r2 >> r2
+ rsb r3, r2, #32 @ r3<- 32 - r2
+ orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
+ subs ip, r2, #32 @ ip<- r2 - 32
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
+ mov r1, r1, lsr r2 @ r1<- r1 >>> r2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_xor_int():
+% binop(instr="eor r0, r0, r1")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="eor r0, r0, r1")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="eor r0, r0, r1")
+
+%def op_xor_int_lit8():
+% binopLit8(extract="", instr="eor r0, r0, r3, asr #8")
+
+%def op_xor_long():
+% binopWide(preinstr="eor r0, r0, r2", instr="eor r1, r1, r3")
+
+%def op_xor_long_2addr():
+% binopWide2addr(preinstr="eor r0, r0, r2", instr="eor r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/array.S b/runtime/interpreter/mterp/arm/array.S
new file mode 100644
index 0000000..88d89c5
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/array.S
@@ -0,0 +1,250 @@
+%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
+ * instructions. We use a pair of FETCH_Bs instead.
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short
+ *
+ * NOTE: assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B r2, 1, 0 @ r2<- BB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ FETCH_B r3, 1, 1 @ r3<- CC
+ GET_VREG r0, r2 @ r0<- vBB (array object)
+ GET_VREG r1, r3 @ r1<- vCC (requested index)
+ cmp r0, #0 @ null array object?
+ beq common_errNullObject @ yes, bail
+ ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
+ add r0, r0, r1, lsl #$shift @ r0<- arrayObj + index*width
+ cmp r1, r3 @ compare unsigned index, length
+ bcs common_errArrayIndex @ index >= length, bail
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $load r2, [r0, #$data_offset] @ r2<- vBB[vCC]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG r2, r9 @ vAA<- r2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_aget_boolean():
+% op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+ /*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B r2, 1, 0 @ r2<- BB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ FETCH_B r3, 1, 1 @ r3<- CC
+ EXPORT_PC
+ GET_VREG r0, r2 @ r0<- vBB (array object)
+ GET_VREG r1, r3 @ r1<- vCC (requested index)
+ bl artAGetObjectFromMterp @ (array, index)
+ ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
+ PREFETCH_INST 2
+ cmp r1, #0
+ bne MterpException
+ SET_VREG_OBJECT r0, r9
+ ADVANCE 2
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_aget_short():
+% op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+ /*
+ * Array get, 64 bits. vAA <- vBB[vCC].
+ *
+ * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
+ */
+ /* aget-wide vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ GET_VREG r0, r2 @ r0<- vBB (array object)
+ GET_VREG r1, r3 @ r1<- vCC (requested index)
+ cmp r0, #0 @ null array object?
+ beq common_errNullObject @ yes, bail
+ ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
+ add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width
+ cmp r1, r3 @ compare unsigned index, length
+ bcs common_errArrayIndex @ index >= length, bail
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
+ ldrd r2, [r0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] @ r2/r3<- vBB[vCC]
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
+ * instructions. We use a pair of FETCH_Bs instead.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short
+ *
+ * NOTE: this assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B r2, 1, 0 @ r2<- BB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ FETCH_B r3, 1, 1 @ r3<- CC
+ GET_VREG r0, r2 @ r0<- vBB (array object)
+ GET_VREG r1, r3 @ r1<- vCC (requested index)
+ cmp r0, #0 @ null array object?
+ beq common_errNullObject @ yes, bail
+ ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
+ add r0, r0, r1, lsl #$shift @ r0<- arrayObj + index*width
+ cmp r1, r3 @ compare unsigned index, length
+ bcs common_errArrayIndex @ index >= length, bail
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_VREG r2, r9 @ r2<- vAA
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ $store r2, [r0, #$data_offset] @ vBB[vCC]<- r2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_aput_boolean():
+% op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+ /*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ */
+ /* op vAA, vBB, vCC */
+ EXPORT_PC
+ add r0, rFP, #OFF_FP_SHADOWFRAME
+ mov r1, rPC
+ mov r2, rINST
+ bl MterpAputObject
+ cmp r0, #0
+ beq MterpPossibleException
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_aput_short():
+% op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+ /*
+ * Array put, 64 bits. vBB[vCC] <- vAA.
+ *
+ * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
+ */
+ /* aput-wide vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ GET_VREG r0, r2 @ r0<- vBB (array object)
+ GET_VREG r1, r3 @ r1<- vCC (requested index)
+ cmp r0, #0 @ null array object?
+ beq common_errNullObject @ yes, bail
+ ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
+ add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width
+ cmp r1, r3 @ compare unsigned index, length
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ bcs common_errArrayIndex @ index >= length, bail
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ strd r2, [r0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] @ r2/r3<- vBB[vCC]
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_array_length():
+ /*
+ * Return the length of an array.
+ */
+ mov r1, rINST, lsr #12 @ r1<- B
+ ubfx r2, rINST, #8, #4 @ r2<- A
+ GET_VREG r0, r1 @ r0<- vB (object ref)
+ cmp r0, #0 @ is object null?
+ beq common_errNullObject @ yup, fail
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- array length
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG r3, r2 @ vB<- length
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ EXPORT_PC
+ FETCH r0, 1 @ r0<- bbbb (lo)
+ FETCH r1, 2 @ r1<- BBBB (hi)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb
+ GET_VREG r0, r3 @ r0<- vAA (array object)
+ add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.)
+ bl MterpFillArrayData @ (obj, payload)
+ cmp r0, #0 @ 0 means an exception is thrown
+ beq MterpPossibleException @ exception?
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+ /*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
+ .extern $helper
+ EXPORT_PC
+ add r0, rFP, #OFF_FP_SHADOWFRAME
+ mov r1, rPC
+ mov r2, rSELF
+ bl $helper
+ cmp r0, #0
+ beq MterpPossibleException
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+ /*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class@CCCC */
+ EXPORT_PC
+ add r0, rFP, #OFF_FP_SHADOWFRAME
+ mov r1, rPC
+ mov r2, rINST
+ mov r3, rSELF
+ bl MterpNewArray
+ cmp r0, #0
+ beq MterpPossibleException
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/bincmp.S b/runtime/interpreter/mterp/arm/bincmp.S
deleted file mode 100644
index 368c2d6..0000000
--- a/runtime/interpreter/mterp/arm/bincmp.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def bincmp(condition=""):
- /*
- * Generic two-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- mov r1, rINST, lsr #12 @ r1<- B
- ubfx r0, rINST, #8, #4 @ r0<- A
- GET_VREG r3, r1 @ r3<- vB
- GET_VREG r0, r0 @ r0<- vA
- FETCH_S rINST, 1 @ rINST<- branch offset, in code units
- cmp r0, r3 @ compare (vA, vB)
- b${condition} MterpCommonTakenBranchNoFlags
- cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
- beq .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/binop.S b/runtime/interpreter/mterp/arm/binop.S
deleted file mode 100644
index 72ae9f4..0000000
--- a/runtime/interpreter/mterp/arm/binop.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def binop(preinstr="", result="r0", chkzero="0", instr=""):
- /*
- * 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".)
- *
- * 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.
- *
- * 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 $chkzero
- cmp r1, #0 @ is second operand zero?
- beq common_errDivideByZero
- .endif
-
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $preinstr @ optional op; may set condition codes
- $instr @ $result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG $result, r9 @ vAA<- $result
- GOTO_OPCODE ip @ jump to next instruction
- /* 11-14 instructions */
diff --git a/runtime/interpreter/mterp/arm/binop2addr.S b/runtime/interpreter/mterp/arm/binop2addr.S
deleted file mode 100644
index 6f7f23c..0000000
--- a/runtime/interpreter/mterp/arm/binop2addr.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def binop2addr(preinstr="", result="r0", chkzero="0", instr=""):
- /*
- * 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".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (r1). Useful for integer division and modulus.
- *
- * 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 $chkzero
- cmp r1, #0 @ is second operand zero?
- beq common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
-
- $preinstr @ optional op; may set condition codes
- $instr @ $result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG $result, r9 @ vAA<- $result
- GOTO_OPCODE ip @ jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm/binopLit16.S b/runtime/interpreter/mterp/arm/binopLit16.S
deleted file mode 100644
index 86291b5..0000000
--- a/runtime/interpreter/mterp/arm/binopLit16.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def binopLit16(result="r0", chkzero="0", instr=""):
- /*
- * 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".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (r1). Useful for integer division and modulus.
- *
- * 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 $chkzero
- cmp r1, #0 @ is second operand zero?
- beq common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
-
- $instr @ $result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG $result, r9 @ vAA<- $result
- GOTO_OPCODE ip @ jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm/binopLit8.S b/runtime/interpreter/mterp/arm/binopLit8.S
deleted file mode 100644
index b850e49..0000000
--- a/runtime/interpreter/mterp/arm/binopLit8.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def binopLit8(extract="asr r1, r3, #8", result="r0", chkzero="0", instr=""):
- /*
- * 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".)
- *
- * You can override "extract" if the extraction of the literal value
- * from r3 to r1 is not the default "asr r1, r3, #8". The extraction
- * can be omitted completely if the shift is embedded in "instr".
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (r1). Useful for integer division and modulus.
- *
- * 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
- $extract @ optional; typically r1<- ssssssCC (sign extended)
- .if $chkzero
- @cmp r1, #0 @ is second operand zero?
- beq common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
-
- $instr @ $result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG $result, r9 @ vAA<- $result
- GOTO_OPCODE ip @ jump to next instruction
- /* 10-12 instructions */
diff --git a/runtime/interpreter/mterp/arm/binopWide.S b/runtime/interpreter/mterp/arm/binopWide.S
deleted file mode 100644
index b708627..0000000
--- a/runtime/interpreter/mterp/arm/binopWide.S
+++ /dev/null
@@ -1,38 +0,0 @@
-%def binopWide(preinstr="", result0="r0", result1="r1", chkzero="0", instr=""):
- /*
- * Generic 64-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = r0-r1 op r2-r3".
- * 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".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (r1). Useful for integer division and modulus.
- *
- * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
- * xor-long, add-double, sub-double, mul-double, div-double,
- * rem-double
- *
- * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
- */
- /* binop vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov rINST, rINST, lsr #8 @ rINST<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[AA]
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
- ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
- ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
- .if $chkzero
- orrs ip, r2, r3 @ second arg (r2-r3) is zero?
- beq common_errDivideByZero
- .endif
- CLEAR_SHADOW_PAIR rINST, lr, ip @ Zero out the shadow regs
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $preinstr @ optional op; may set condition codes
- $instr @ result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {$result0,$result1} @ vAA/vAA+1<- $result0/$result1
- GOTO_OPCODE ip @ jump to next instruction
- /* 14-17 instructions */
diff --git a/runtime/interpreter/mterp/arm/binopWide2addr.S b/runtime/interpreter/mterp/arm/binopWide2addr.S
deleted file mode 100644
index 2ce5130..0000000
--- a/runtime/interpreter/mterp/arm/binopWide2addr.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def binopWide2addr(preinstr="", result0="r0", result1="r1", chkzero="0", instr=""):
- /*
- * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = r0-r1 op r2-r3".
- * 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".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (r1). Useful for integer division and modulus.
- *
- * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
- * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
- * sub-double/2addr, mul-double/2addr, div-double/2addr,
- * rem-double/2addr
- */
- /* binop/2addr vA, vB */
- mov r1, rINST, lsr #12 @ r1<- B
- ubfx rINST, rINST, #8, #4 @ rINST<- A
- VREG_INDEX_TO_ADDR r1, r1 @ r1<- &fp[B]
- VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
- ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1
- ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
- .if $chkzero
- orrs ip, r2, r3 @ second arg (r2-r3) is zero?
- beq common_errDivideByZero
- .endif
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $preinstr @ optional op; may set condition codes
- $instr @ result<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {$result0,$result1} @ vAA/vAA+1<- $result0/$result1
- GOTO_OPCODE ip @ jump to next instruction
- /* 12-15 instructions */
diff --git a/runtime/interpreter/mterp/arm/const.S b/runtime/interpreter/mterp/arm/const.S
deleted file mode 100644
index a22f366..0000000
--- a/runtime/interpreter/mterp/arm/const.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC
- FETCH r0, 1 @ r0<- BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- add r2, rFP, #OFF_FP_SHADOWFRAME
- mov r3, rSELF
- bl $helper @ (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 2 @ load rINST
- cmp r0, #0 @ fail?
- bne MterpPossibleException @ let reference interpreter deal with it.
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/control_flow.S b/runtime/interpreter/mterp/arm/control_flow.S
new file mode 100644
index 0000000..51832e1
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/control_flow.S
@@ -0,0 +1,209 @@
+%def bincmp(condition=""):
+ /*
+ * Generic two-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ mov r1, rINST, lsr #12 @ r1<- B
+ ubfx r0, rINST, #8, #4 @ r0<- A
+ GET_VREG r3, r1 @ r3<- vB
+ GET_VREG r0, r0 @ r0<- vA
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
+ cmp r0, r3 @ compare (vA, vB)
+ b${condition} MterpCommonTakenBranchNoFlags
+ cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
+ beq .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def zcmp(condition=""):
+ /*
+ * Generic one-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ mov r0, rINST, lsr #8 @ r0<- AA
+ GET_VREG r0, r0 @ r0<- vAA
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
+ cmp r0, #0 @ compare (vA, 0)
+ b${condition} MterpCommonTakenBranchNoFlags
+ cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
+ beq .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_goto():
+ /*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ sbfx rINST, rINST, #8, #8 @ rINST<- ssssssAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_16():
+ /*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_32():
+ /*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Unlike most opcodes, this one is allowed to branch to itself, so
+ * our "backward branch" test must be "<=0" instead of "<0". Because
+ * we need the V bit set, we'll use an adds to convert from Dalvik
+ * offset to byte offset.
+ */
+ /* goto/32 +AAAAAAAA */
+ FETCH r0, 1 @ r0<- aaaa (lo)
+ FETCH r3, 2 @ r1<- AAAA (hi)
+ orrs rINST, r0, r3, lsl #16 @ rINST<- AAAAaaaa
+ b MterpCommonTakenBranch
+
+%def op_if_eq():
+% bincmp(condition="eq")
+
+%def op_if_eqz():
+% zcmp(condition="eq")
+
+%def op_if_ge():
+% bincmp(condition="ge")
+
+%def op_if_gez():
+% zcmp(condition="ge")
+
+%def op_if_gt():
+% bincmp(condition="gt")
+
+%def op_if_gtz():
+% zcmp(condition="gt")
+
+%def op_if_le():
+% bincmp(condition="le")
+
+%def op_if_lez():
+% zcmp(condition="le")
+
+%def op_if_lt():
+% bincmp(condition="lt")
+
+%def op_if_ltz():
+% zcmp(condition="lt")
+
+%def op_if_ne():
+% bincmp(condition="ne")
+
+%def op_if_nez():
+% zcmp(condition="ne")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+ /*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBB */
+ FETCH r0, 1 @ r0<- bbbb (lo)
+ FETCH r1, 2 @ r1<- BBBB (hi)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb
+ GET_VREG r1, r3 @ r1<- vAA
+ add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2
+ bl $func @ r0<- code-unit branch offset
+ movs rINST, r0
+ b MterpCommonTakenBranch
+
+%def op_return():
+ /*
+ * Return a 32-bit value.
+ *
+ * for: return, return-object
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ blne MterpSuspendCheck @ (self)
+ mov r2, rINST, lsr #8 @ r2<- AA
+ GET_VREG r0, r2 @ r0<- vAA
+ mov r1, #0
+ b MterpReturn
+
+%def op_return_object():
+% op_return()
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ blne MterpSuspendCheck @ (self)
+ mov r0, #0
+ mov r1, #0
+ b MterpReturn
+
+%def op_return_void_no_barrier():
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ blne MterpSuspendCheck @ (self)
+ mov r0, #0
+ mov r1, #0
+ b MterpReturn
+
+%def op_return_wide():
+ /*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ blne MterpSuspendCheck @ (self)
+ mov r2, rINST, lsr #8 @ r2<- AA
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[AA]
+ ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1
+ b MterpReturn
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+ /*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC
+ mov r2, rINST, lsr #8 @ r2<- AA
+ GET_VREG r1, r2 @ r1<- vAA (exception object)
+ cmp r1, #0 @ null object?
+ beq common_errNullObject @ yes, throw an NPE instead
+ str r1, [rSELF, #THREAD_EXCEPTION_OFFSET] @ thread->exception<- obj
+ b MterpException
diff --git a/runtime/interpreter/mterp/arm/entry.S b/runtime/interpreter/mterp/arm/entry.S
deleted file mode 100644
index d17802b..0000000
--- a/runtime/interpreter/mterp/arm/entry.S
+++ /dev/null
@@ -1,77 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Interpreter entry point.
- */
-
- .text
- .align 2
-
-/*
- * On entry:
- * r0 Thread* self/
- * r1 insns_
- * r2 ShadowFrame
- * r3 JValue* result_register
- *
- */
-
-ENTRY ExecuteMterpImpl
- stmfd sp!, {r3-r10,fp,lr} @ save 10 regs, (r3 just to align 64)
- .cfi_adjust_cfa_offset 40
- .cfi_rel_offset r3, 0
- .cfi_rel_offset r4, 4
- .cfi_rel_offset r5, 8
- .cfi_rel_offset r6, 12
- .cfi_rel_offset r7, 16
- .cfi_rel_offset r8, 20
- .cfi_rel_offset r9, 24
- .cfi_rel_offset r10, 28
- .cfi_rel_offset fp, 32
- .cfi_rel_offset lr, 36
-
- /* Remember the return register */
- str r3, [r2, #SHADOWFRAME_RESULT_REGISTER_OFFSET]
-
- /* Remember the dex instruction pointer */
- str r1, [r2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET]
-
- /* set up "named" registers */
- mov rSELF, r0
- ldr r0, [r2, #SHADOWFRAME_NUMBER_OF_VREGS_OFFSET]
- add rFP, r2, #SHADOWFRAME_VREGS_OFFSET @ point to vregs.
- VREG_INDEX_TO_ADDR rREFS, r0 @ point to reference array in shadow frame
- ldr r0, [r2, #SHADOWFRAME_DEX_PC_OFFSET] @ Get starting dex_pc.
- add rPC, r1, r0, lsl #1 @ Create direct pointer to 1st dex opcode
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
- EXPORT_PC
-
- /* Starting ibase */
- ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
-
- /* Set up for backwards branches & osr profiling */
- ldr r0, [rFP, #OFF_FP_METHOD]
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rSELF
- bl MterpSetUpHotnessCountdown
- mov rPROFILE, r0 @ Starting hotness countdown to rPROFILE
-
- /* start executing the instruction at rPC */
- FETCH_INST @ load rINST from rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/arm/fallback.S b/runtime/interpreter/mterp/arm/fallback.S
deleted file mode 100644
index 3685700..0000000
--- a/runtime/interpreter/mterp/arm/fallback.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- b MterpFallback
-
diff --git a/runtime/interpreter/mterp/arm/fbinop.S b/runtime/interpreter/mterp/arm/fbinop.S
deleted file mode 100644
index 0f75f89..0000000
--- a/runtime/interpreter/mterp/arm/fbinop.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def fbinop(instr=""):
- /*
- * Generic 32-bit floating-point operation. Provide an "instr" line that
- * specifies an instruction that performs "s2 = s0 op s1". Because we
- * use the "softfp" ABI, this must be an instruction, not a function call.
- *
- * For: add-float, sub-float, mul-float, div-float
- */
- /* floatop 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
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- flds s1, [r3] @ s1<- vCC
- flds s0, [r2] @ s0<- vBB
-
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $instr @ s2<- op
- GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vAA
- fsts s2, [r9] @ vAA<- s2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/fbinop2addr.S b/runtime/interpreter/mterp/arm/fbinop2addr.S
deleted file mode 100644
index a5162a1..0000000
--- a/runtime/interpreter/mterp/arm/fbinop2addr.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def fbinop2addr(instr=""):
- /*
- * Generic 32-bit floating point "/2addr" binary operation. Provide
- * an "instr" line that specifies an instruction that performs
- * "s2 = s0 op s1".
- *
- * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
- */
- /* binop/2addr vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- flds s1, [r3] @ s1<- vB
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- flds s0, [r9] @ s0<- vA
- $instr @ s2<- op
- GET_INST_OPCODE ip @ extract opcode from rINST
- fsts s2, [r9] @ vAA<- s2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/fbinopWide.S b/runtime/interpreter/mterp/arm/fbinopWide.S
deleted file mode 100644
index e283fee..0000000
--- a/runtime/interpreter/mterp/arm/fbinopWide.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def fbinopWide(instr=""):
- /*
- * Generic 64-bit double-precision floating point binary operation.
- * Provide an "instr" line that specifies an instruction that performs
- * "d2 = d0 op d1".
- *
- * for: add-double, sub-double, mul-double, div-double
- */
- /* doubleop 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
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- fldd d1, [r3] @ d1<- vCC
- fldd d0, [r2] @ d0<- vBB
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $instr @ s2<- op
- CLEAR_SHADOW_PAIR r9, ip, lr @ Zero shadow regs
- GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vAA
- fstd d2, [r9] @ vAA<- d2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/fbinopWide2addr.S b/runtime/interpreter/mterp/arm/fbinopWide2addr.S
deleted file mode 100644
index 639a783..0000000
--- a/runtime/interpreter/mterp/arm/fbinopWide2addr.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def fbinopWide2addr(instr=""):
- /*
- * Generic 64-bit floating point "/2addr" binary operation. Provide
- * an "instr" line that specifies an instruction that performs
- * "d2 = d0 op d1".
- *
- * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
- * div-double/2addr
- */
- /* binop/2addr vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
- CLEAR_SHADOW_PAIR r9, ip, r0 @ Zero out shadow regs
- fldd d1, [r3] @ d1<- vB
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- fldd d0, [r9] @ d0<- vA
- $instr @ d2<- op
- GET_INST_OPCODE ip @ extract opcode from rINST
- fstd d2, [r9] @ vAA<- d2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/field.S b/runtime/interpreter/mterp/arm/field.S
deleted file mode 100644
index 82e1638..0000000
--- a/runtime/interpreter/mterp/arm/field.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def field(helper=""):
- /*
- * General field read / write (iget-* iput-* sget-* sput-*).
- */
- .extern $helper
- mov r0, rPC @ arg0: Instruction* inst
- mov r1, rINST @ arg1: uint16_t inst_data
- add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
- mov r3, rSELF @ arg3: Thread* self
- PREFETCH_INST 2 @ prefetch next opcode
- bl $helper
- cmp r0, #0
- beq MterpPossibleException
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/floating_point.S b/runtime/interpreter/mterp/arm/floating_point.S
new file mode 100644
index 0000000..583010a
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/floating_point.S
@@ -0,0 +1,482 @@
+%def fbinop(instr=""):
+ /*
+ * Generic 32-bit floating-point operation. Provide an "instr" line that
+ * specifies an instruction that performs "s2 = s0 op s1". Because we
+ * use the "softfp" ABI, this must be an instruction, not a function call.
+ *
+ * For: add-float, sub-float, mul-float, div-float
+ */
+ /* floatop 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
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ flds s1, [r3] @ s1<- vCC
+ flds s0, [r2] @ s0<- vBB
+
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $instr @ s2<- op
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vAA
+ fsts s2, [r9] @ vAA<- s2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def fbinop2addr(instr=""):
+ /*
+ * Generic 32-bit floating point "/2addr" binary operation. Provide
+ * an "instr" line that specifies an instruction that performs
+ * "s2 = s0 op s1".
+ *
+ * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
+ */
+ /* binop/2addr vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
+ flds s1, [r3] @ s1<- vB
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ flds s0, [r9] @ s0<- vA
+ $instr @ s2<- op
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fsts s2, [r9] @ vAA<- s2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def fbinopWide(instr=""):
+ /*
+ * Generic 64-bit double-precision floating point binary operation.
+ * Provide an "instr" line that specifies an instruction that performs
+ * "d2 = d0 op d1".
+ *
+ * for: add-double, sub-double, mul-double, div-double
+ */
+ /* doubleop 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
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ fldd d1, [r3] @ d1<- vCC
+ fldd d0, [r2] @ d0<- vBB
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $instr @ s2<- op
+ CLEAR_SHADOW_PAIR r9, ip, lr @ Zero shadow regs
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vAA
+ fstd d2, [r9] @ vAA<- d2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def fbinopWide2addr(instr=""):
+ /*
+ * Generic 64-bit floating point "/2addr" binary operation. Provide
+ * an "instr" line that specifies an instruction that performs
+ * "d2 = d0 op d1".
+ *
+ * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
+ * div-double/2addr
+ */
+ /* binop/2addr vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
+ CLEAR_SHADOW_PAIR r9, ip, r0 @ Zero out shadow regs
+ fldd d1, [r3] @ d1<- vB
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ fldd d0, [r9] @ d0<- vA
+ $instr @ d2<- op
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fstd d2, [r9] @ vAA<- d2
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def funop(instr=""):
+ /*
+ * Generic 32-bit unary floating-point operation. Provide an "instr"
+ * line that specifies an instruction that performs "s1 = op s0".
+ *
+ * for: int-to-float, float-to-int
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
+ flds s0, [r3] @ s0<- vB
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $instr @ s1<- op
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
+ fsts s1, [r9] @ vA<- s1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def funopNarrower(instr=""):
+ /*
+ * Generic 64bit-to-32bit unary floating point operation. Provide an
+ * "instr" line that specifies an instruction that performs "s0 = op d0".
+ *
+ * For: double-to-int, double-to-float
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
+ fldd d0, [r3] @ d0<- vB
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $instr @ s0<- op
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
+ fsts s0, [r9] @ vA<- s0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def funopWider(instr=""):
+ /*
+ * Generic 32bit-to-64bit floating point unary operation. Provide an
+ * "instr" line that specifies an instruction that performs "d0 = op s0".
+ *
+ * For: int-to-double, float-to-double
+ */
+ /* unop vA, vB */
+ mov r3, rINST, lsr #12 @ r3<- B
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
+ flds s0, [r3] @ s0<- vB
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ $instr @ d0<- op
+ CLEAR_SHADOW_PAIR r9, ip, lr @ Zero shadow regs
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
+ fstd d0, [r9] @ vA<- d0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_add_double():
+% fbinopWide(instr="faddd d2, d0, d1")
+
+%def op_add_double_2addr():
+% fbinopWide2addr(instr="faddd d2, d0, d1")
+
+%def op_add_float():
+% fbinop(instr="fadds s2, s0, s1")
+
+%def op_add_float_2addr():
+% fbinop2addr(instr="fadds s2, s0, s1")
+
+%def op_cmpg_double():
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x < y) {
+ * return -1;
+ * } else if (x > y) {
+ * return 1;
+ * } else {
+ * return 1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ fldd d0, [r2] @ d0<- vBB
+ fldd d1, [r3] @ d1<- vCC
+ vcmpe.f64 d0, d1 @ compare (vBB, vCC)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mov r0, #1 @ r0<- 1 (default)
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fmstat @ export status flags
+ mvnmi r0, #0 @ (less than) r1<- -1
+ moveq r0, #0 @ (equal) r1<- 0
+ SET_VREG r0, r9 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_cmpg_float():
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x < y) {
+ * return -1;
+ * } else if (x > y) {
+ * return 1;
+ * } else {
+ * return 1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ flds s0, [r2] @ s0<- vBB
+ flds s1, [r3] @ s1<- vCC
+ vcmpe.f32 s0, s1 @ compare (vBB, vCC)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mov r0, #1 @ r0<- 1 (default)
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fmstat @ export status flags
+ mvnmi r0, #0 @ (less than) r1<- -1
+ moveq r0, #0 @ (equal) r1<- 0
+ SET_VREG r0, r9 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_cmpl_double():
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x > y) {
+ * return 1;
+ * } else if (x < y) {
+ * return -1;
+ * } else {
+ * return -1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ fldd d0, [r2] @ d0<- vBB
+ fldd d1, [r3] @ d1<- vCC
+ vcmpe.f64 d0, d1 @ compare (vBB, vCC)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mvn r0, #0 @ r0<- -1 (default)
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fmstat @ export status flags
+ movgt r0, #1 @ (greater than) r1<- 1
+ moveq r0, #0 @ (equal) r1<- 0
+ SET_VREG r0, r9 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_cmpl_float():
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x > y) {
+ * return 1;
+ * } else if (x < y) {
+ * return -1;
+ * } else {
+ * return -1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ FETCH r0, 1 @ r0<- CCBB
+ mov r9, rINST, lsr #8 @ r9<- AA
+ and r2, r0, #255 @ r2<- BB
+ mov r3, r0, lsr #8 @ r3<- CC
+ VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
+ flds s0, [r2] @ s0<- vBB
+ flds s1, [r3] @ s1<- vCC
+ vcmpe.f32 s0, s1 @ compare (vBB, vCC)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ mvn r0, #0 @ r0<- -1 (default)
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ fmstat @ export status flags
+ movgt r0, #1 @ (greater than) r1<- 1
+ moveq r0, #0 @ (equal) r1<- 0
+ SET_VREG r0, r9 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_div_double():
+% fbinopWide(instr="fdivd d2, d0, d1")
+
+%def op_div_double_2addr():
+% fbinopWide2addr(instr="fdivd d2, d0, d1")
+
+%def op_div_float():
+% fbinop(instr="fdivs s2, s0, s1")
+
+%def op_div_float_2addr():
+% fbinop2addr(instr="fdivs s2, s0, s1")
+
+%def op_double_to_float():
+% funopNarrower(instr="vcvt.f32.f64 s0, d0")
+
+%def op_double_to_int():
+% funopNarrower(instr="ftosizd s0, d0")
+
+%def op_double_to_long():
+% unopWide(instr="bl d2l_doconv")
+
+%def op_double_to_long_sister_code():
+/*
+ * Convert the double in r0/r1 to a long in r0/r1.
+ *
+ * We have to clip values to long min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us.
+ */
+d2l_doconv:
+ ubfx r2, r1, #20, #11 @ grab the exponent
+ movw r3, #0x43e
+ cmp r2, r3 @ MINLONG < x > MAXLONG?
+ bhs d2l_special_cases
+ b __aeabi_d2lz @ tail call to convert double to long
+d2l_special_cases:
+ movw r3, #0x7ff
+ cmp r2, r3
+ beq d2l_maybeNaN @ NaN?
+d2l_notNaN:
+ adds r1, r1, r1 @ sign bit to carry
+ mov r0, #0xffffffff @ assume maxlong for lsw
+ mov r1, #0x7fffffff @ assume maxlong for msw
+ adc r0, r0, #0
+ adc r1, r1, #0 @ convert maxlong to minlong if exp negative
+ bx lr @ return
+d2l_maybeNaN:
+ orrs r3, r0, r1, lsl #12
+ beq d2l_notNaN @ if fraction is non-zero, it's a NaN
+ mov r0, #0
+ mov r1, #0
+ bx lr @ return 0 for NaN
+
+%def op_float_to_double():
+% funopWider(instr="vcvt.f64.f32 d0, s0")
+
+%def op_float_to_int():
+% funop(instr="ftosizs s1, s0")
+
+%def op_float_to_long():
+% unopWider(instr="bl f2l_doconv")
+
+%def op_float_to_long_sister_code():
+/*
+ * Convert the float in r0 to a long in r0/r1.
+ *
+ * We have to clip values to long min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us.
+ */
+f2l_doconv:
+ ubfx r2, r0, #23, #8 @ grab the exponent
+ cmp r2, #0xbe @ MININT < x > MAXINT?
+ bhs f2l_special_cases
+ b __aeabi_f2lz @ tail call to convert float to long
+f2l_special_cases:
+ cmp r2, #0xff @ NaN or infinity?
+ beq f2l_maybeNaN
+f2l_notNaN:
+ adds r0, r0, r0 @ sign bit to carry
+ mov r0, #0xffffffff @ assume maxlong for lsw
+ mov r1, #0x7fffffff @ assume maxlong for msw
+ adc r0, r0, #0
+ adc r1, r1, #0 @ convert maxlong to minlong if exp negative
+ bx lr @ return
+f2l_maybeNaN:
+ lsls r3, r0, #9
+ beq f2l_notNaN @ if fraction is non-zero, it's a NaN
+ mov r0, #0
+ mov r1, #0
+ bx lr @ return 0 for NaN
+
+%def op_int_to_double():
+% funopWider(instr="fsitod d0, s0")
+
+%def op_int_to_float():
+% funop(instr="fsitos s1, s0")
+
+%def op_long_to_double():
+ /*
+ * Specialised 64-bit floating point operation.
+ *
+ * Note: The result will be returned in d2.
+ *
+ * For: long-to-double
+ */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
+ vldr d0, [r3] @ d0<- vAA
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+
+ vcvt.f64.s32 d1, s1 @ d1<- (double)(vAAh)
+ vcvt.f64.u32 d2, s0 @ d2<- (double)(vAAl)
+ vldr d3, constval$opcode
+ vmla.f64 d2, d1, d3 @ d2<- vAAh*2^32 + vAAl
+
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ vstr.64 d2, [r9] @ vAA<- d2
+ GOTO_OPCODE ip @ jump to next instruction
+
+ /* literal pool helper */
+constval${opcode}:
+ .8byte 0x41f0000000000000
+
+%def op_long_to_float():
+% unopNarrower(instr="bl __aeabi_l2f")
+
+%def op_mul_double():
+% fbinopWide(instr="fmuld d2, d0, d1")
+
+%def op_mul_double_2addr():
+% fbinopWide2addr(instr="fmuld d2, d0, d1")
+
+%def op_mul_float():
+% fbinop(instr="fmuls s2, s0, s1")
+
+%def op_mul_float_2addr():
+% fbinop2addr(instr="fmuls s2, s0, s1")
+
+%def op_neg_double():
+% unopWide(instr="add r1, r1, #0x80000000")
+
+%def op_neg_float():
+% unop(instr="add r0, r0, #0x80000000")
+
+%def op_rem_double():
+/* EABI doesn't define a double remainder function, but libm does */
+% binopWide(instr="bl fmod")
+
+%def op_rem_double_2addr():
+/* EABI doesn't define a double remainder function, but libm does */
+% binopWide2addr(instr="bl fmod")
+
+%def op_rem_float():
+/* EABI doesn't define a float remainder function, but libm does */
+% binop(instr="bl fmodf")
+
+%def op_rem_float_2addr():
+/* EABI doesn't define a float remainder function, but libm does */
+% binop2addr(instr="bl fmodf")
+
+%def op_sub_double():
+% fbinopWide(instr="fsubd d2, d0, d1")
+
+%def op_sub_double_2addr():
+% fbinopWide2addr(instr="fsubd d2, d0, d1")
+
+%def op_sub_float():
+% fbinop(instr="fsubs s2, s0, s1")
+
+%def op_sub_float_2addr():
+% fbinop2addr(instr="fsubs s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S
deleted file mode 100644
index 275584e..0000000
--- a/runtime/interpreter/mterp/arm/footer.S
+++ /dev/null
@@ -1,298 +0,0 @@
-%def footer():
-/*
- * ===========================================================================
- * Common subroutines and data
- * ===========================================================================
- */
-
- .text
- .align 2
-
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-common_errDivideByZero:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogDivideByZeroException
-#endif
- b MterpCommonFallback
-
-common_errArrayIndex:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogArrayIndexException
-#endif
- b MterpCommonFallback
-
-common_errNegativeArraySize:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNegativeArraySizeException
-#endif
- b MterpCommonFallback
-
-common_errNoSuchMethod:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNoSuchMethodException
-#endif
- b MterpCommonFallback
-
-common_errNullObject:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNullObjectException
-#endif
- b MterpCommonFallback
-
-common_exceptionThrown:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogExceptionThrownException
-#endif
- b MterpCommonFallback
-
-MterpSuspendFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- ldr r2, [rSELF, #THREAD_FLAGS_OFFSET]
- bl MterpLogSuspendFallback
-#endif
- b MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- ldr r0, [rSELF, #THREAD_EXCEPTION_OFFSET]
- cmp r0, #0 @ Exception pending?
- beq MterpFallback @ If not, fall back to reference interpreter.
- /* intentional fallthrough - handle pending exception. */
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
-MterpException:
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpHandleException @ (self, shadow_frame)
- cmp r0, #0
- beq MterpExceptionReturn @ no local catch, back to caller.
- ldr r0, [rFP, #OFF_FP_DEX_INSTRUCTIONS]
- ldr r1, [rFP, #OFF_FP_DEX_PC]
- ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
- add rPC, r0, r1, lsl #1 @ generate new dex_pc_ptr
- /* Do we need to switch interpreters? */
- bl MterpShouldSwitchInterpreters
- cmp r0, #0
- bne MterpFallback
- /* resume execution at catch block */
- EXPORT_PC
- FETCH_INST
- GET_INST_OPCODE ip
- GOTO_OPCODE ip
- /* NOTE: no fallthrough */
-
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * rINST <= signed offset
- * rPROFILE <= signed hotness countdown (expanded to 32 bits)
- * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- *
- */
-MterpCommonTakenBranchNoFlags:
- cmp rINST, #0
-MterpCommonTakenBranch:
- bgt .L_forward_branch @ don't add forward branches to hotness
-/*
- * We need to subtract 1 from positive values and we should not see 0 here,
- * so we may use the result of the comparison with -1.
- */
-#if JIT_CHECK_OSR != -1
-# error "JIT_CHECK_OSR must be -1."
-#endif
- cmp rPROFILE, #JIT_CHECK_OSR
- beq .L_osr_check
- subsgt rPROFILE, #1
- beq .L_add_batch @ counted down to zero - report
-.L_resume_backward_branch:
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- REFRESH_IBASE
- add r2, rINST, rINST @ r2<- byte offset
- FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
- ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- bne .L_suspend_request_pending
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-.L_suspend_request_pending:
- EXPORT_PC
- mov r0, rSELF
- bl MterpSuspendCheck @ (self)
- cmp r0, #0
- bne MterpFallback
- REFRESH_IBASE @ might have changed during suspend
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-.L_no_count_backwards:
- cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
- bne .L_resume_backward_branch
-.L_osr_check:
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rINST
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
- cmp r0, #0
- bne MterpOnStackReplacement
- b .L_resume_backward_branch
-
-.L_forward_branch:
- cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
- beq .L_check_osr_forward
-.L_resume_forward_branch:
- add r2, rINST, rINST @ r2<- byte offset
- FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-.L_check_osr_forward:
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rINST
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
- cmp r0, #0
- bne MterpOnStackReplacement
- b .L_resume_forward_branch
-
-.L_add_batch:
- add r1, rFP, #OFF_FP_SHADOWFRAME
- strh rPROFILE, [r1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
- ldr r0, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpAddHotnessBatch @ (method, shadow_frame, self)
- mov rPROFILE, r0 @ restore new hotness countdown to rPROFILE
- b .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, #2
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
- cmp r0, #0
- bne MterpOnStackReplacement
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rINST
- bl MterpLogOSR
-#endif
- mov r0, #1 @ Signal normal return
- b MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
-MterpFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- bl MterpLogFallback
-#endif
-MterpCommonFallback:
- mov r0, #0 @ signal retry with reference interpreter.
- b MterpDone
-
-/*
- * We pushed some registers on the stack in ExecuteMterpImpl, then saved
- * SP and LR. Here we restore SP, restore the registers, and then restore
- * LR to PC.
- *
- * On entry:
- * uint32_t* rFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- mov r0, #1 @ signal return to caller.
- b MterpDone
-MterpReturn:
- ldr r2, [rFP, #OFF_FP_RESULT_REGISTER]
- str r0, [r2]
- str r1, [r2, #4]
- mov r0, #1 @ signal return to caller.
-MterpDone:
-/*
- * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- cmp rPROFILE, #0
- bgt MterpProfileActive @ if > 0, we may have some counts to report.
- ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return
-
-MterpProfileActive:
- mov rINST, r0 @ stash return value
- /* Report cached hotness counts */
- ldr r0, [rFP, #OFF_FP_METHOD]
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rSELF
- strh rPROFILE, [r1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
- bl MterpAddHotnessBatch @ (method, shadow_frame, self)
- mov r0, rINST @ restore return value
- ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return
-
- END ExecuteMterpImpl
-
diff --git a/runtime/interpreter/mterp/arm/funop.S b/runtime/interpreter/mterp/arm/funop.S
deleted file mode 100644
index c4f2231..0000000
--- a/runtime/interpreter/mterp/arm/funop.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def funop(instr=""):
- /*
- * Generic 32-bit unary floating-point operation. Provide an "instr"
- * line that specifies an instruction that performs "s1 = op s0".
- *
- * for: int-to-float, float-to-int
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
- flds s0, [r3] @ s0<- vB
- ubfx r9, rINST, #8, #4 @ r9<- A
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $instr @ s1<- op
- GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- fsts s1, [r9] @ vA<- s1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/funopNarrower.S b/runtime/interpreter/mterp/arm/funopNarrower.S
deleted file mode 100644
index ce5e82c..0000000
--- a/runtime/interpreter/mterp/arm/funopNarrower.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def funopNarrower(instr=""):
- /*
- * Generic 64bit-to-32bit unary floating point operation. Provide an
- * "instr" line that specifies an instruction that performs "s0 = op d0".
- *
- * For: double-to-int, double-to-float
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
- fldd d0, [r3] @ d0<- vB
- ubfx r9, rINST, #8, #4 @ r9<- A
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $instr @ s0<- op
- GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- fsts s0, [r9] @ vA<- s0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/funopWider.S b/runtime/interpreter/mterp/arm/funopWider.S
deleted file mode 100644
index 8df362f..0000000
--- a/runtime/interpreter/mterp/arm/funopWider.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def funopWider(instr=""):
- /*
- * Generic 32bit-to-64bit floating point unary operation. Provide an
- * "instr" line that specifies an instruction that performs "d0 = op s0".
- *
- * For: int-to-double, float-to-double
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB
- flds s0, [r3] @ s0<- vB
- ubfx r9, rINST, #8, #4 @ r9<- A
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $instr @ d0<- op
- CLEAR_SHADOW_PAIR r9, ip, lr @ Zero shadow regs
- GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- fstd d0, [r9] @ vA<- d0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/header.S b/runtime/interpreter/mterp/arm/header.S
deleted file mode 100644
index 03f330a..0000000
--- a/runtime/interpreter/mterp/arm/header.S
+++ /dev/null
@@ -1,313 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- Art assembly interpreter notes:
-
- First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
- handle invoke, allows higher-level code to create frame & shadow frame.
-
- Once that's working, support direct entry code & eliminate shadow frame (and
- excess locals allocation.
-
- Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
- base of the vreg array within the shadow frame. Access the other fields,
- dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
- the shadow frame mechanism of double-storing object references - via rFP &
- number_of_vregs_.
-
- */
-
-/*
-ARM EABI general notes:
-
-r0-r3 hold first 4 args to a method; they are not preserved across method calls
-r4-r8 are available for general use
-r9 is given special treatment in some situations, but not for us
-r10 (sl) seems to be generally available
-r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
-r12 (ip) is scratch -- not preserved across method calls
-r13 (sp) should be managed carefully in case a signal arrives
-r14 (lr) must be preserved
-r15 (pc) can be tinkered with directly
-
-r0 holds returns of <= 4 bytes
-r0-r1 hold returns of 8 bytes, low word in r0
-
-Callee must save/restore r4+ (except r12) if it modifies them. If VFP
-is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved,
-s0-s15 (d0-d7, q0-a3) do not need to be.
-
-Stack is "full descending". Only the arguments that don't fit in the first 4
-registers are placed on the stack. "sp" points at the first stacked argument
-(i.e. the 5th arg).
-
-VFP: single-precision results in s0, double-precision results in d0.
-
-In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
-64-bit quantities (long long, double) must be 64-bit aligned.
-*/
-
-/*
-Mterp and ARM notes:
-
-The following registers have fixed assignments:
-
- reg nick purpose
- r4 rPC interpreted program counter, used for fetching instructions
- r5 rFP interpreted frame pointer, used for accessing locals and args
- r6 rSELF self (Thread) pointer
- r7 rINST first 16-bit code unit of current instruction
- r8 rIBASE interpreted instruction base pointer, used for computed goto
- r10 rPROFILE branch profiling countdown
- r11 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
-
-Macros are provided for common operations. Each macro MUST emit only
-one instruction to make instruction-counting easier. They MUST NOT alter
-unspecified registers or condition codes.
-*/
-
-/*
- * This is a #include, not a %include, because we want the C pre-processor
- * to expand the macros into assembler assignment statements.
- */
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-#define MTERP_PROFILE_BRANCHES 1
-#define MTERP_LOGGING 0
-
-/* During bringup, we'll use the shadow frame model instead of rFP */
-/* single-purpose registers, given names for clarity */
-#define rPC r4
-#define CFI_DEX 4 // DWARF register number of the register holding dex-pc (xPC).
-#define CFI_TMP 0 // DWARF register number of the first argument register (r0).
-#define rFP r5
-#define rSELF r6
-#define rINST r7
-#define rIBASE r8
-#define rPROFILE r10
-#define rREFS r11
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_SHADOWFRAME OFF_FP(0)
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-.macro EXPORT_PC
- str rPC, [rFP, #OFF_FP_DEX_PC_PTR]
-.endm
-
-.macro EXPORT_DEX_PC tmp
- ldr \tmp, [rFP, #OFF_FP_DEX_INSTRUCTIONS]
- str rPC, [rFP, #OFF_FP_DEX_PC_PTR]
- sub \tmp, rPC, \tmp
- asr \tmp, #1
- str \tmp, [rFP, #OFF_FP_DEX_PC]
-.endm
-
-/*
- * Fetch the next instruction from rPC into rINST. Does not advance rPC.
- */
-.macro FETCH_INST
- ldrh rINST, [rPC]
-.endm
-
-/*
- * Fetch the next instruction from the specified offset. Advances rPC
- * to point to the next instruction. "_count" is in 16-bit code units.
- *
- * Because of the limited size of immediate constants on ARM, this is only
- * suitable for small forward movements (i.e. don't try to implement "goto"
- * with this).
- *
- * This must come AFTER anything that can throw an exception, or the
- * exception catch may miss. (This also implies that it must come after
- * EXPORT_PC.)
- */
-.macro FETCH_ADVANCE_INST count
- ldrh rINST, [rPC, #((\count)*2)]!
-.endm
-
-/*
- * The operation performed here is similar to FETCH_ADVANCE_INST, except the
- * src and dest registers are parameterized (not hard-wired to rPC and rINST).
- */
-.macro PREFETCH_ADVANCE_INST dreg, sreg, count
- ldrh \dreg, [\sreg, #((\count)*2)]!
-.endm
-
-/*
- * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
- * rINST ahead of possible exception point. Be sure to manually advance rPC
- * later.
- */
-.macro PREFETCH_INST count
- ldrh rINST, [rPC, #((\count)*2)]
-.endm
-
-/* Advance rPC by some number of code units. */
-.macro ADVANCE count
- add rPC, #((\count)*2)
-.endm
-
-/*
- * Fetch the next instruction from an offset specified by _reg. Updates
- * rPC to point to the next instruction. "_reg" must specify the distance
- * in bytes, *not* 16-bit code units, and may be a signed value.
- *
- * We want to write "ldrh rINST, [rPC, _reg, lsl #1]!", but some of the
- * bits that hold the shift distance are used for the half/byte/sign flags.
- * In some cases we can pre-double _reg for free, so we require a byte offset
- * here.
- */
-.macro FETCH_ADVANCE_INST_RB reg
- ldrh rINST, [rPC, \reg]!
-.endm
-
-/*
- * Fetch a half-word code unit from an offset past the current PC. The
- * "_count" value is in 16-bit code units. Does not advance rPC.
- *
- * The "_S" variant works the same but treats the value as signed.
- */
-.macro FETCH reg, count
- ldrh \reg, [rPC, #((\count)*2)]
-.endm
-
-.macro FETCH_S reg, count
- ldrsh \reg, [rPC, #((\count)*2)]
-.endm
-
-/*
- * Fetch one byte from an offset past the current PC. Pass in the same
- * "_count" as you would for FETCH, and an additional 0/1 indicating which
- * byte of the halfword you want (lo/hi).
- */
-.macro FETCH_B reg, count, byte
- ldrb \reg, [rPC, #((\count)*2+(\byte))]
-.endm
-
-/*
- * Put the instruction's opcode field into the specified register.
- */
-.macro GET_INST_OPCODE reg
- and \reg, rINST, #255
-.endm
-
-/*
- * Put the prefetched instruction's opcode field into the specified register.
- */
-.macro GET_PREFETCHED_OPCODE oreg, ireg
- and \oreg, \ireg, #255
-.endm
-
-/*
- * Begin executing the opcode in _reg. Because this only jumps within the
- * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork.
- */
-.macro GOTO_OPCODE reg
- add pc, rIBASE, \reg, lsl #${handler_size_bits}
-.endm
-.macro GOTO_OPCODE_BASE base,reg
- add pc, \base, \reg, lsl #${handler_size_bits}
-.endm
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- */
-.macro GET_VREG reg, vreg
- ldr \reg, [rFP, \vreg, lsl #2]
-.endm
-.macro SET_VREG reg, vreg
- str \reg, [rFP, \vreg, lsl #2]
- mov \reg, #0
- str \reg, [rREFS, \vreg, lsl #2]
-.endm
-.macro SET_VREG_OBJECT reg, vreg, tmpreg
- str \reg, [rFP, \vreg, lsl #2]
- str \reg, [rREFS, \vreg, lsl #2]
-.endm
-.macro SET_VREG_SHADOW reg, vreg
- str \reg, [rREFS, \vreg, lsl #2]
-.endm
-
-/*
- * Clear the corresponding shadow regs for a vreg pair
- */
-.macro CLEAR_SHADOW_PAIR vreg, tmp1, tmp2
- mov \tmp1, #0
- add \tmp2, \vreg, #1
- SET_VREG_SHADOW \tmp1, \vreg
- SET_VREG_SHADOW \tmp1, \tmp2
-.endm
-
-/*
- * Convert a virtual register index into an address.
- */
-.macro VREG_INDEX_TO_ADDR reg, vreg
- add \reg, rFP, \vreg, lsl #2 /* WARNING/FIXME: handle shadow frame vreg zero if store */
-.endm
-
-/*
- * Refresh handler table.
- */
-.macro REFRESH_IBASE
- ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
-.endm
-
-/*
- * cfi support macros.
- */
-.macro ENTRY name
- .arm
- .type \name, #function
- .hidden \name // Hide this as a global symbol, so we do not incur plt calls.
- .global \name
- /* Cache alignment for function entry */
- .balign 16
-\name:
- .cfi_startproc
- .fnstart
-.endm
-
-.macro END name
- .fnend
- .cfi_endproc
- .size \name, .-\name
-.endm
diff --git a/runtime/interpreter/mterp/arm/instruction_end.S b/runtime/interpreter/mterp/arm/instruction_end.S
deleted file mode 100644
index cf30a9b..0000000
--- a/runtime/interpreter/mterp/arm/instruction_end.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end():
-
- .type artMterpAsmInstructionEnd, #object
- .hidden artMterpAsmInstructionEnd
- .global artMterpAsmInstructionEnd
-artMterpAsmInstructionEnd:
diff --git a/runtime/interpreter/mterp/arm/instruction_end_alt.S b/runtime/interpreter/mterp/arm/instruction_end_alt.S
deleted file mode 100644
index 9509a63..0000000
--- a/runtime/interpreter/mterp/arm/instruction_end_alt.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_alt():
-
- .type artMterpAsmAltInstructionEnd, #object
- .hidden artMterpAsmAltInstructionEnd
- .global artMterpAsmAltInstructionEnd
-artMterpAsmAltInstructionEnd:
diff --git a/runtime/interpreter/mterp/arm/instruction_end_sister.S b/runtime/interpreter/mterp/arm/instruction_end_sister.S
deleted file mode 100644
index 18f1dbb..0000000
--- a/runtime/interpreter/mterp/arm/instruction_end_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_sister():
-
- .type artMterpAsmSisterEnd, #object
- .hidden artMterpAsmSisterEnd
- .global artMterpAsmSisterEnd
-artMterpAsmSisterEnd:
diff --git a/runtime/interpreter/mterp/arm/instruction_start.S b/runtime/interpreter/mterp/arm/instruction_start.S
deleted file mode 100644
index 457dcf9..0000000
--- a/runtime/interpreter/mterp/arm/instruction_start.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start():
-
- .type artMterpAsmInstructionStart, #object
- .hidden artMterpAsmInstructionStart
- .global artMterpAsmInstructionStart
-artMterpAsmInstructionStart = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/arm/instruction_start_alt.S b/runtime/interpreter/mterp/arm/instruction_start_alt.S
deleted file mode 100644
index 40d2bf5..0000000
--- a/runtime/interpreter/mterp/arm/instruction_start_alt.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start_alt():
-
- .type artMterpAsmAltInstructionStart, #object
- .hidden artMterpAsmAltInstructionStart
- .global artMterpAsmAltInstructionStart
-artMterpAsmAltInstructionStart = .L_ALT_op_nop
- .text
diff --git a/runtime/interpreter/mterp/arm/instruction_start_sister.S b/runtime/interpreter/mterp/arm/instruction_start_sister.S
deleted file mode 100644
index 2bf2463..0000000
--- a/runtime/interpreter/mterp/arm/instruction_start_sister.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def instruction_start_sister():
-
- .type artMterpAsmSisterStart, #object
- .hidden artMterpAsmSisterStart
- .global artMterpAsmSisterStart
- .text
- .balign 4
-artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/arm/invoke.S b/runtime/interpreter/mterp/arm/invoke.S
index 812852e..8693d3b 100644
--- a/runtime/interpreter/mterp/arm/invoke.S
+++ b/runtime/interpreter/mterp/arm/invoke.S
@@ -20,3 +20,102 @@
GET_INST_OPCODE ip
GOTO_OPCODE ip
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ EXPORT_PC
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rPC
+ mov r3, rINST
+ bl $helper
+ cmp r0, #0
+ beq MterpException
+ FETCH_ADVANCE_INST 4
+ bl MterpShouldSwitchInterpreters
+ cmp r0, #0
+ bne MterpFallback
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+ /*
+ * Handle an invoke-custom invocation.
+ *
+ * for: invoke-custom, invoke-custom/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, call_site@BBBB */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, call_site@BBBB */
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+ /*
+ * Handle an interface method call.
+ *
+ * for: invoke-interface, invoke-interface/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+ /*
+ * Handle a "super" method call.
+ *
+ * for: invoke-super, invoke-super/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+ /*
+ * Handle a virtual method call.
+ *
+ * for: invoke-virtual, invoke-virtual/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/arm/invoke_polymorphic.S b/runtime/interpreter/mterp/arm/invoke_polymorphic.S
deleted file mode 100644
index b473616..0000000
--- a/runtime/interpreter/mterp/arm/invoke_polymorphic.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- EXPORT_PC
- mov r0, rSELF
- add r1, rFP, #OFF_FP_SHADOWFRAME
- mov r2, rPC
- mov r3, rINST
- bl $helper
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 4
- bl MterpShouldSwitchInterpreters
- cmp r0, #0
- bne MterpFallback
- GET_INST_OPCODE ip
- GOTO_OPCODE ip
diff --git a/runtime/interpreter/mterp/arm/main.S b/runtime/interpreter/mterp/arm/main.S
new file mode 100644
index 0000000..73d45c0
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/main.S
@@ -0,0 +1,756 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ Art assembly interpreter notes:
+
+ First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
+ handle invoke, allows higher-level code to create frame & shadow frame.
+
+ Once that's working, support direct entry code & eliminate shadow frame (and
+ excess locals allocation.
+
+ Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
+ base of the vreg array within the shadow frame. Access the other fields,
+ dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
+ the shadow frame mechanism of double-storing object references - via rFP &
+ number_of_vregs_.
+
+ */
+
+/*
+ARM EABI general notes:
+
+r0-r3 hold first 4 args to a method; they are not preserved across method calls
+r4-r8 are available for general use
+r9 is given special treatment in some situations, but not for us
+r10 (sl) seems to be generally available
+r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
+r12 (ip) is scratch -- not preserved across method calls
+r13 (sp) should be managed carefully in case a signal arrives
+r14 (lr) must be preserved
+r15 (pc) can be tinkered with directly
+
+r0 holds returns of <= 4 bytes
+r0-r1 hold returns of 8 bytes, low word in r0
+
+Callee must save/restore r4+ (except r12) if it modifies them. If VFP
+is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved,
+s0-s15 (d0-d7, q0-a3) do not need to be.
+
+Stack is "full descending". Only the arguments that don't fit in the first 4
+registers are placed on the stack. "sp" points at the first stacked argument
+(i.e. the 5th arg).
+
+VFP: single-precision results in s0, double-precision results in d0.
+
+In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
+64-bit quantities (long long, double) must be 64-bit aligned.
+*/
+
+/*
+Mterp and ARM notes:
+
+The following registers have fixed assignments:
+
+ reg nick purpose
+ r4 rPC interpreted program counter, used for fetching instructions
+ r5 rFP interpreted frame pointer, used for accessing locals and args
+ r6 rSELF self (Thread) pointer
+ r7 rINST first 16-bit code unit of current instruction
+ r8 rIBASE interpreted instruction base pointer, used for computed goto
+ r10 rPROFILE branch profiling countdown
+ r11 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
+
+Macros are provided for common operations. Each macro MUST emit only
+one instruction to make instruction-counting easier. They MUST NOT alter
+unspecified registers or condition codes.
+*/
+
+/*
+ * This is a #include, not a %include, because we want the C pre-processor
+ * to expand the macros into assembler assignment statements.
+ */
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
+/* During bringup, we'll use the shadow frame model instead of rFP */
+/* single-purpose registers, given names for clarity */
+#define rPC r4
+#define CFI_DEX 4 // DWARF register number of the register holding dex-pc (xPC).
+#define CFI_TMP 0 // DWARF register number of the first argument register (r0).
+#define rFP r5
+#define rSELF r6
+#define rINST r7
+#define rIBASE r8
+#define rPROFILE r10
+#define rREFS r11
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_SHADOWFRAME OFF_FP(0)
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+.macro EXPORT_PC
+ str rPC, [rFP, #OFF_FP_DEX_PC_PTR]
+.endm
+
+.macro EXPORT_DEX_PC tmp
+ ldr \tmp, [rFP, #OFF_FP_DEX_INSTRUCTIONS]
+ str rPC, [rFP, #OFF_FP_DEX_PC_PTR]
+ sub \tmp, rPC, \tmp
+ asr \tmp, #1
+ str \tmp, [rFP, #OFF_FP_DEX_PC]
+.endm
+
+/*
+ * Fetch the next instruction from rPC into rINST. Does not advance rPC.
+ */
+.macro FETCH_INST
+ ldrh rINST, [rPC]
+.endm
+
+/*
+ * Fetch the next instruction from the specified offset. Advances rPC
+ * to point to the next instruction. "_count" is in 16-bit code units.
+ *
+ * Because of the limited size of immediate constants on ARM, this is only
+ * suitable for small forward movements (i.e. don't try to implement "goto"
+ * with this).
+ *
+ * This must come AFTER anything that can throw an exception, or the
+ * exception catch may miss. (This also implies that it must come after
+ * EXPORT_PC.)
+ */
+.macro FETCH_ADVANCE_INST count
+ ldrh rINST, [rPC, #((\count)*2)]!
+.endm
+
+/*
+ * The operation performed here is similar to FETCH_ADVANCE_INST, except the
+ * src and dest registers are parameterized (not hard-wired to rPC and rINST).
+ */
+.macro PREFETCH_ADVANCE_INST dreg, sreg, count
+ ldrh \dreg, [\sreg, #((\count)*2)]!
+.endm
+
+/*
+ * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
+ * rINST ahead of possible exception point. Be sure to manually advance rPC
+ * later.
+ */
+.macro PREFETCH_INST count
+ ldrh rINST, [rPC, #((\count)*2)]
+.endm
+
+/* Advance rPC by some number of code units. */
+.macro ADVANCE count
+ add rPC, #((\count)*2)
+.endm
+
+/*
+ * Fetch the next instruction from an offset specified by _reg. Updates
+ * rPC to point to the next instruction. "_reg" must specify the distance
+ * in bytes, *not* 16-bit code units, and may be a signed value.
+ *
+ * We want to write "ldrh rINST, [rPC, _reg, lsl #1]!", but some of the
+ * bits that hold the shift distance are used for the half/byte/sign flags.
+ * In some cases we can pre-double _reg for free, so we require a byte offset
+ * here.
+ */
+.macro FETCH_ADVANCE_INST_RB reg
+ ldrh rINST, [rPC, \reg]!
+.endm
+
+/*
+ * Fetch a half-word code unit from an offset past the current PC. The
+ * "_count" value is in 16-bit code units. Does not advance rPC.
+ *
+ * The "_S" variant works the same but treats the value as signed.
+ */
+.macro FETCH reg, count
+ ldrh \reg, [rPC, #((\count)*2)]
+.endm
+
+.macro FETCH_S reg, count
+ ldrsh \reg, [rPC, #((\count)*2)]
+.endm
+
+/*
+ * Fetch one byte from an offset past the current PC. Pass in the same
+ * "_count" as you would for FETCH, and an additional 0/1 indicating which
+ * byte of the halfword you want (lo/hi).
+ */
+.macro FETCH_B reg, count, byte
+ ldrb \reg, [rPC, #((\count)*2+(\byte))]
+.endm
+
+/*
+ * Put the instruction's opcode field into the specified register.
+ */
+.macro GET_INST_OPCODE reg
+ and \reg, rINST, #255
+.endm
+
+/*
+ * Put the prefetched instruction's opcode field into the specified register.
+ */
+.macro GET_PREFETCHED_OPCODE oreg, ireg
+ and \oreg, \ireg, #255
+.endm
+
+/*
+ * Begin executing the opcode in _reg. Because this only jumps within the
+ * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork.
+ */
+.macro GOTO_OPCODE reg
+ add pc, rIBASE, \reg, lsl #${handler_size_bits}
+.endm
+.macro GOTO_OPCODE_BASE base,reg
+ add pc, \base, \reg, lsl #${handler_size_bits}
+.endm
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ */
+.macro GET_VREG reg, vreg
+ ldr \reg, [rFP, \vreg, lsl #2]
+.endm
+.macro SET_VREG reg, vreg
+ str \reg, [rFP, \vreg, lsl #2]
+ mov \reg, #0
+ str \reg, [rREFS, \vreg, lsl #2]
+.endm
+.macro SET_VREG_OBJECT reg, vreg, tmpreg
+ str \reg, [rFP, \vreg, lsl #2]
+ str \reg, [rREFS, \vreg, lsl #2]
+.endm
+.macro SET_VREG_SHADOW reg, vreg
+ str \reg, [rREFS, \vreg, lsl #2]
+.endm
+
+/*
+ * Clear the corresponding shadow regs for a vreg pair
+ */
+.macro CLEAR_SHADOW_PAIR vreg, tmp1, tmp2
+ mov \tmp1, #0
+ add \tmp2, \vreg, #1
+ SET_VREG_SHADOW \tmp1, \vreg
+ SET_VREG_SHADOW \tmp1, \tmp2
+.endm
+
+/*
+ * Convert a virtual register index into an address.
+ */
+.macro VREG_INDEX_TO_ADDR reg, vreg
+ add \reg, rFP, \vreg, lsl #2 /* WARNING/FIXME: handle shadow frame vreg zero if store */
+.endm
+
+/*
+ * Refresh handler table.
+ */
+.macro REFRESH_IBASE
+ ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
+.endm
+
+/*
+ * cfi support macros.
+ */
+.macro ENTRY name
+ .arm
+ .type \name, #function
+ .hidden \name // Hide this as a global symbol, so we do not incur plt calls.
+ .global \name
+ /* Cache alignment for function entry */
+ .balign 16
+\name:
+ .cfi_startproc
+ .fnstart
+.endm
+
+.macro END name
+ .fnend
+ .cfi_endproc
+ .size \name, .-\name
+.endm
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Interpreter entry point.
+ */
+
+ .text
+ .align 2
+
+/*
+ * On entry:
+ * r0 Thread* self/
+ * r1 insns_
+ * r2 ShadowFrame
+ * r3 JValue* result_register
+ *
+ */
+
+ENTRY ExecuteMterpImpl
+ stmfd sp!, {r3-r10,fp,lr} @ save 10 regs, (r3 just to align 64)
+ .cfi_adjust_cfa_offset 40
+ .cfi_rel_offset r3, 0
+ .cfi_rel_offset r4, 4
+ .cfi_rel_offset r5, 8
+ .cfi_rel_offset r6, 12
+ .cfi_rel_offset r7, 16
+ .cfi_rel_offset r8, 20
+ .cfi_rel_offset r9, 24
+ .cfi_rel_offset r10, 28
+ .cfi_rel_offset fp, 32
+ .cfi_rel_offset lr, 36
+
+ /* Remember the return register */
+ str r3, [r2, #SHADOWFRAME_RESULT_REGISTER_OFFSET]
+
+ /* Remember the dex instruction pointer */
+ str r1, [r2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET]
+
+ /* set up "named" registers */
+ mov rSELF, r0
+ ldr r0, [r2, #SHADOWFRAME_NUMBER_OF_VREGS_OFFSET]
+ add rFP, r2, #SHADOWFRAME_VREGS_OFFSET @ point to vregs.
+ VREG_INDEX_TO_ADDR rREFS, r0 @ point to reference array in shadow frame
+ ldr r0, [r2, #SHADOWFRAME_DEX_PC_OFFSET] @ Get starting dex_pc.
+ add rPC, r1, r0, lsl #1 @ Create direct pointer to 1st dex opcode
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+ EXPORT_PC
+
+ /* Starting ibase */
+ ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
+
+ /* Set up for backwards branches & osr profiling */
+ ldr r0, [rFP, #OFF_FP_METHOD]
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rSELF
+ bl MterpSetUpHotnessCountdown
+ mov rPROFILE, r0 @ Starting hotness countdown to rPROFILE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST @ load rINST from rPC
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Note that the call to MterpCheckBefore is done as a tail call.
+ */
+ .extern MterpCheckBefore
+ ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh IBASE.
+ adr lr, .L_ALT_${opcode}
+ sub lr, lr, #(.L_ALT_${opcode} - .L_${opcode}) @ Addr of primary handler.
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rPC
+ b MterpCheckBefore @ (self, shadow_frame, dex_pc_ptr) @ Tail call.
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ b MterpFallback
+
+
+%def footer():
+/*
+ * ===========================================================================
+ * Common subroutines and data
+ * ===========================================================================
+ */
+
+ .text
+ .align 2
+
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+common_errDivideByZero:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogDivideByZeroException
+#endif
+ b MterpCommonFallback
+
+common_errArrayIndex:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogArrayIndexException
+#endif
+ b MterpCommonFallback
+
+common_errNegativeArraySize:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNegativeArraySizeException
+#endif
+ b MterpCommonFallback
+
+common_errNoSuchMethod:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNoSuchMethodException
+#endif
+ b MterpCommonFallback
+
+common_errNullObject:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNullObjectException
+#endif
+ b MterpCommonFallback
+
+common_exceptionThrown:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogExceptionThrownException
+#endif
+ b MterpCommonFallback
+
+MterpSuspendFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ ldr r2, [rSELF, #THREAD_FLAGS_OFFSET]
+ bl MterpLogSuspendFallback
+#endif
+ b MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ ldr r0, [rSELF, #THREAD_EXCEPTION_OFFSET]
+ cmp r0, #0 @ Exception pending?
+ beq MterpFallback @ If not, fall back to reference interpreter.
+ /* intentional fallthrough - handle pending exception. */
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+MterpException:
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpHandleException @ (self, shadow_frame)
+ cmp r0, #0
+ beq MterpExceptionReturn @ no local catch, back to caller.
+ ldr r0, [rFP, #OFF_FP_DEX_INSTRUCTIONS]
+ ldr r1, [rFP, #OFF_FP_DEX_PC]
+ ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]
+ add rPC, r0, r1, lsl #1 @ generate new dex_pc_ptr
+ /* Do we need to switch interpreters? */
+ bl MterpShouldSwitchInterpreters
+ cmp r0, #0
+ bne MterpFallback
+ /* resume execution at catch block */
+ EXPORT_PC
+ FETCH_INST
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip
+ /* NOTE: no fallthrough */
+
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * rINST <= signed offset
+ * rPROFILE <= signed hotness countdown (expanded to 32 bits)
+ * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ *
+ */
+MterpCommonTakenBranchNoFlags:
+ cmp rINST, #0
+MterpCommonTakenBranch:
+ bgt .L_forward_branch @ don't add forward branches to hotness
+/*
+ * We need to subtract 1 from positive values and we should not see 0 here,
+ * so we may use the result of the comparison with -1.
+ */
+#if JIT_CHECK_OSR != -1
+# error "JIT_CHECK_OSR must be -1."
+#endif
+ cmp rPROFILE, #JIT_CHECK_OSR
+ beq .L_osr_check
+ subsgt rPROFILE, #1
+ beq .L_add_batch @ counted down to zero - report
+.L_resume_backward_branch:
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ REFRESH_IBASE
+ add r2, rINST, rINST @ r2<- byte offset
+ FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
+ ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ bne .L_suspend_request_pending
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+.L_suspend_request_pending:
+ EXPORT_PC
+ mov r0, rSELF
+ bl MterpSuspendCheck @ (self)
+ cmp r0, #0
+ bne MterpFallback
+ REFRESH_IBASE @ might have changed during suspend
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+.L_no_count_backwards:
+ cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
+ bne .L_resume_backward_branch
+.L_osr_check:
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement
+ b .L_resume_backward_branch
+
+.L_forward_branch:
+ cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
+ beq .L_check_osr_forward
+.L_resume_forward_branch:
+ add r2, rINST, rINST @ r2<- byte offset
+ FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+.L_check_osr_forward:
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement
+ b .L_resume_forward_branch
+
+.L_add_batch:
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ strh rPROFILE, [r1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
+ ldr r0, [rFP, #OFF_FP_METHOD]
+ mov r2, rSELF
+ bl MterpAddHotnessBatch @ (method, shadow_frame, self)
+ mov rPROFILE, r0 @ restore new hotness countdown to rPROFILE
+ b .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, #2
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpLogOSR
+#endif
+ mov r0, #1 @ Signal normal return
+ b MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+MterpFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogFallback
+#endif
+MterpCommonFallback:
+ mov r0, #0 @ signal retry with reference interpreter.
+ b MterpDone
+
+/*
+ * We pushed some registers on the stack in ExecuteMterpImpl, then saved
+ * SP and LR. Here we restore SP, restore the registers, and then restore
+ * LR to PC.
+ *
+ * On entry:
+ * uint32_t* rFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ mov r0, #1 @ signal return to caller.
+ b MterpDone
+MterpReturn:
+ ldr r2, [rFP, #OFF_FP_RESULT_REGISTER]
+ str r0, [r2]
+ str r1, [r2, #4]
+ mov r0, #1 @ signal return to caller.
+MterpDone:
+/*
+ * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ cmp rPROFILE, #0
+ bgt MterpProfileActive @ if > 0, we may have some counts to report.
+ ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return
+
+MterpProfileActive:
+ mov rINST, r0 @ stash return value
+ /* Report cached hotness counts */
+ ldr r0, [rFP, #OFF_FP_METHOD]
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rSELF
+ strh rPROFILE, [r1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
+ bl MterpAddHotnessBatch @ (method, shadow_frame, self)
+ mov r0, rINST @ restore return value
+ ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return
+
+ END ExecuteMterpImpl
+
+
+%def instruction_end():
+
+ .type artMterpAsmInstructionEnd, #object
+ .hidden artMterpAsmInstructionEnd
+ .global artMterpAsmInstructionEnd
+artMterpAsmInstructionEnd:
+
+%def instruction_end_alt():
+
+ .type artMterpAsmAltInstructionEnd, #object
+ .hidden artMterpAsmAltInstructionEnd
+ .global artMterpAsmAltInstructionEnd
+artMterpAsmAltInstructionEnd:
+
+%def instruction_end_sister():
+
+ .type artMterpAsmSisterEnd, #object
+ .hidden artMterpAsmSisterEnd
+ .global artMterpAsmSisterEnd
+artMterpAsmSisterEnd:
+
+%def instruction_start():
+
+ .type artMterpAsmInstructionStart, #object
+ .hidden artMterpAsmInstructionStart
+ .global artMterpAsmInstructionStart
+artMterpAsmInstructionStart = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ .type artMterpAsmAltInstructionStart, #object
+ .hidden artMterpAsmAltInstructionStart
+ .global artMterpAsmAltInstructionStart
+artMterpAsmAltInstructionStart = .L_ALT_op_nop
+ .text
+
+%def instruction_start_sister():
+
+ .type artMterpAsmSisterStart, #object
+ .hidden artMterpAsmSisterStart
+ .global artMterpAsmSisterStart
+ .text
+ .balign 4
+artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/arm/object.S b/runtime/interpreter/mterp/arm/object.S
new file mode 100644
index 0000000..af1ece2
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/object.S
@@ -0,0 +1,275 @@
+%def field(helper=""):
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl $helper
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_check_cast():
+ /*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class@BBBB */
+ EXPORT_PC
+ FETCH r0, 1 @ r0<- BBBB
+ mov r1, rINST, lsr #8 @ r1<- AA
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
+ ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
+ mov r3, rSELF @ r3<- self
+ bl MterpCheckCast @ (index, &obj, method, self)
+ PREFETCH_INST 2
+ cmp r0, #0
+ bne MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="ldrb")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="ldrsb")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="ldrh")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset@CCCC */
+ mov r2, rINST, lsr #12 @ r2<- B
+ FETCH r1, 1 @ r1<- field byte offset
+ EXPORT_PC
+ GET_VREG r0, r2 @ r0<- object we're operating on
+ bl artIGetObjectFromMterp @ (obj, offset)
+ ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
+ ubfx r2, rINST, #8, #4 @ r2<- A
+ PREFETCH_INST 2
+ cmp r3, #0
+ bne MterpPossibleException @ bail out
+ SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
+ ADVANCE 2 @ advance rPC
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iget_quick(load="ldr"):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
+ /* op vA, vB, offset@CCCC */
+ mov r2, rINST, lsr #12 @ r2<- B
+ FETCH r1, 1 @ r1<- field byte offset
+ GET_VREG r3, r2 @ r3<- object we're operating on
+ ubfx r2, rINST, #8, #4 @ r2<- A
+ cmp r3, #0 @ check object for null
+ beq common_errNullObject @ object was null
+ $load r0, [r3, r1] @ r0<- obj.field
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ SET_VREG r0, r2 @ fp[A]<- r0
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="ldrsh")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+ /* iget-wide-quick vA, vB, offset@CCCC */
+ mov r2, rINST, lsr #12 @ r2<- B
+ FETCH ip, 1 @ ip<- field byte offset
+ GET_VREG r3, r2 @ r3<- object we're operating on
+ ubfx r2, rINST, #8, #4 @ r2<- A
+ cmp r3, #0 @ check object for null
+ beq common_errNullObject @ object was null
+ ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned)
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
+ CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r3, {r0-r1} @ fp[A]<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_instance_of():
+ /*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class@CCCC */
+ EXPORT_PC
+ FETCH r0, 1 @ r0<- CCCC
+ mov r1, rINST, lsr #12 @ r1<- B
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
+ ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
+ mov r3, rSELF @ r3<- self
+ bl MterpInstanceOf @ (index, &obj, method, self)
+ ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
+ ubfx r9, rINST, #8, #4 @ r9<- A
+ PREFETCH_INST 2
+ cmp r1, #0 @ exception pending?
+ bne MterpException
+ ADVANCE 2 @ advance rPC
+ SET_VREG r0, r9 @ vA<- r0
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(store="strb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(store="strb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(store="strh")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ EXPORT_PC
+ add r0, rFP, #OFF_FP_SHADOWFRAME
+ mov r1, rPC
+ mov r2, rINST
+ bl MterpIputObjectQuick
+ cmp r0, #0
+ beq MterpException
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iput_quick(store="str"):
+ /* For: iput-quick, iput-object-quick */
+ /* op vA, vB, offset@CCCC */
+ mov r2, rINST, lsr #12 @ r2<- B
+ FETCH r1, 1 @ r1<- field byte offset
+ GET_VREG r3, r2 @ r3<- fp[B], the object pointer
+ ubfx r2, rINST, #8, #4 @ r2<- A
+ cmp r3, #0 @ check object for null
+ beq common_errNullObject @ object was null
+ GET_VREG r0, r2 @ r0<- fp[A]
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ $store r0, [r3, r1] @ obj.field<- r0
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(store="strh")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset@CCCC */
+ mov r2, rINST, lsr #12 @ r2<- B
+ FETCH r3, 1 @ r3<- field byte offset
+ GET_VREG r2, r2 @ r2<- fp[B], the object pointer
+ ubfx r0, rINST, #8, #4 @ r0<- A
+ cmp r2, #0 @ check object for null
+ beq common_errNullObject @ object was null
+ VREG_INDEX_TO_ADDR r0, r0 @ r0<- &fp[A]
+ ldmia r0, {r0-r1} @ r0/r1<- fp[A]/fp[A+1]
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ strd r0, [r2, r3] @ obj.field<- r0/r1
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_new_instance():
+ /*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class@BBBB */
+ EXPORT_PC
+ add r0, rFP, #OFF_FP_SHADOWFRAME
+ mov r1, rSELF
+ mov r2, rINST
+ bl MterpNewInstance @ (shadow_frame, self, inst_data)
+ cmp r0, #0
+ beq MterpPossibleException
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/arm/op_add_double.S b/runtime/interpreter/mterp/arm/op_add_double.S
deleted file mode 100644
index 17aabcd..0000000
--- a/runtime/interpreter/mterp/arm/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% fbinopWide(instr="faddd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_add_double_2addr.S b/runtime/interpreter/mterp/arm/op_add_double_2addr.S
deleted file mode 100644
index 97d1757..0000000
--- a/runtime/interpreter/mterp/arm/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% fbinopWide2addr(instr="faddd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_add_float.S b/runtime/interpreter/mterp/arm/op_add_float.S
deleted file mode 100644
index 9ca8cad..0000000
--- a/runtime/interpreter/mterp/arm/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% fbinop(instr="fadds s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_add_float_2addr.S b/runtime/interpreter/mterp/arm/op_add_float_2addr.S
deleted file mode 100644
index abe1989..0000000
--- a/runtime/interpreter/mterp/arm/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% fbinop2addr(instr="fadds s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_add_int.S b/runtime/interpreter/mterp/arm/op_add_int.S
deleted file mode 100644
index e18601c..0000000
--- a/runtime/interpreter/mterp/arm/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="add r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_add_int_2addr.S b/runtime/interpreter/mterp/arm/op_add_int_2addr.S
deleted file mode 100644
index 10ea943..0000000
--- a/runtime/interpreter/mterp/arm/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="add r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_add_int_lit16.S b/runtime/interpreter/mterp/arm/op_add_int_lit16.S
deleted file mode 100644
index 63febf2..0000000
--- a/runtime/interpreter/mterp/arm/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="add r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_add_int_lit8.S b/runtime/interpreter/mterp/arm/op_add_int_lit8.S
deleted file mode 100644
index 4393e668..0000000
--- a/runtime/interpreter/mterp/arm/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(extract="", instr="add r0, r0, r3, asr #8")
diff --git a/runtime/interpreter/mterp/arm/op_add_long.S b/runtime/interpreter/mterp/arm/op_add_long.S
deleted file mode 100644
index 88994d4..0000000
--- a/runtime/interpreter/mterp/arm/op_add_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long():
-% binopWide(preinstr="adds r0, r0, r2", instr="adc r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_add_long_2addr.S b/runtime/interpreter/mterp/arm/op_add_long_2addr.S
deleted file mode 100644
index bfe7447..0000000
--- a/runtime/interpreter/mterp/arm/op_add_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long_2addr():
-% binopWide2addr(preinstr="adds r0, r0, r2", instr="adc r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_aget.S b/runtime/interpreter/mterp/arm/op_aget.S
deleted file mode 100644
index bf265b4..0000000
--- a/runtime/interpreter/mterp/arm/op_aget.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
- * instructions. We use a pair of FETCH_Bs instead.
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short
- *
- * NOTE: assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B r2, 1, 0 @ r2<- BB
- mov r9, rINST, lsr #8 @ r9<- AA
- FETCH_B r3, 1, 1 @ r3<- CC
- GET_VREG r0, r2 @ r0<- vBB (array object)
- GET_VREG r1, r3 @ r1<- vCC (requested index)
- cmp r0, #0 @ null array object?
- beq common_errNullObject @ yes, bail
- ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
- add r0, r0, r1, lsl #$shift @ r0<- arrayObj + index*width
- cmp r1, r3 @ compare unsigned index, length
- bcs common_errArrayIndex @ index >= length, bail
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $load r2, [r0, #$data_offset] @ r2<- vBB[vCC]
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG r2, r9 @ vAA<- r2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_aget_boolean.S b/runtime/interpreter/mterp/arm/op_aget_boolean.S
deleted file mode 100644
index d6e0a1b..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aget_byte.S b/runtime/interpreter/mterp/arm/op_aget_byte.S
deleted file mode 100644
index 6c9f1b7..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aget_char.S b/runtime/interpreter/mterp/arm/op_aget_char.S
deleted file mode 100644
index c5812e3..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aget_object.S b/runtime/interpreter/mterp/arm/op_aget_object.S
deleted file mode 100644
index 3b25086..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_object.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aget_object():
- /*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- FETCH_B r2, 1, 0 @ r2<- BB
- mov r9, rINST, lsr #8 @ r9<- AA
- FETCH_B r3, 1, 1 @ r3<- CC
- EXPORT_PC
- GET_VREG r0, r2 @ r0<- vBB (array object)
- GET_VREG r1, r3 @ r1<- vCC (requested index)
- bl artAGetObjectFromMterp @ (array, index)
- ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
- PREFETCH_INST 2
- cmp r1, #0
- bne MterpException
- SET_VREG_OBJECT r0, r9
- ADVANCE 2
- GET_INST_OPCODE ip
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_aget_short.S b/runtime/interpreter/mterp/arm/op_aget_short.S
deleted file mode 100644
index 9727560..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aget_wide.S b/runtime/interpreter/mterp/arm/op_aget_wide.S
deleted file mode 100644
index 28437e7..0000000
--- a/runtime/interpreter/mterp/arm/op_aget_wide.S
+++ /dev/null
@@ -1,26 +0,0 @@
-%def op_aget_wide():
- /*
- * Array get, 64 bits. vAA <- vBB[vCC].
- *
- * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
- */
- /* aget-wide vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG r0, r2 @ r0<- vBB (array object)
- GET_VREG r1, r3 @ r1<- vCC (requested index)
- cmp r0, #0 @ null array object?
- beq common_errNullObject @ yes, bail
- ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
- add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width
- cmp r1, r3 @ compare unsigned index, length
- bcs common_errArrayIndex @ index >= length, bail
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- ldrd r2, [r0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] @ r2/r3<- vBB[vCC]
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_and_int.S b/runtime/interpreter/mterp/arm/op_and_int.S
deleted file mode 100644
index ac0ae66..0000000
--- a/runtime/interpreter/mterp/arm/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="and r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_and_int_2addr.S b/runtime/interpreter/mterp/arm/op_and_int_2addr.S
deleted file mode 100644
index 28a668a..0000000
--- a/runtime/interpreter/mterp/arm/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="and r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_and_int_lit16.S b/runtime/interpreter/mterp/arm/op_and_int_lit16.S
deleted file mode 100644
index 4b9a4c9..0000000
--- a/runtime/interpreter/mterp/arm/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="and r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_and_int_lit8.S b/runtime/interpreter/mterp/arm/op_and_int_lit8.S
deleted file mode 100644
index b26bfe4..0000000
--- a/runtime/interpreter/mterp/arm/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(extract="", instr="and r0, r0, r3, asr #8")
diff --git a/runtime/interpreter/mterp/arm/op_and_long.S b/runtime/interpreter/mterp/arm/op_and_long.S
deleted file mode 100644
index 3af7897..0000000
--- a/runtime/interpreter/mterp/arm/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(preinstr="and r0, r0, r2", instr="and r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_and_long_2addr.S b/runtime/interpreter/mterp/arm/op_and_long_2addr.S
deleted file mode 100644
index 78e5d88..0000000
--- a/runtime/interpreter/mterp/arm/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(preinstr="and r0, r0, r2", instr="and r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_aput.S b/runtime/interpreter/mterp/arm/op_aput.S
deleted file mode 100644
index 7b5da54..0000000
--- a/runtime/interpreter/mterp/arm/op_aput.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
- * instructions. We use a pair of FETCH_Bs instead.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short
- *
- * NOTE: this assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B r2, 1, 0 @ r2<- BB
- mov r9, rINST, lsr #8 @ r9<- AA
- FETCH_B r3, 1, 1 @ r3<- CC
- GET_VREG r0, r2 @ r0<- vBB (array object)
- GET_VREG r1, r3 @ r1<- vCC (requested index)
- cmp r0, #0 @ null array object?
- beq common_errNullObject @ yes, bail
- ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
- add r0, r0, r1, lsl #$shift @ r0<- arrayObj + index*width
- cmp r1, r3 @ compare unsigned index, length
- bcs common_errArrayIndex @ index >= length, bail
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_VREG r2, r9 @ r2<- vAA
- GET_INST_OPCODE ip @ extract opcode from rINST
- $store r2, [r0, #$data_offset] @ vBB[vCC]<- r2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_aput_boolean.S b/runtime/interpreter/mterp/arm/op_aput_boolean.S
deleted file mode 100644
index 467cc4b..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aput_byte.S b/runtime/interpreter/mterp/arm/op_aput_byte.S
deleted file mode 100644
index 2b4c0ba..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aput_char.S b/runtime/interpreter/mterp/arm/op_aput_char.S
deleted file mode 100644
index cb7dcba..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aput_object.S b/runtime/interpreter/mterp/arm/op_aput_object.S
deleted file mode 100644
index 83b7e5a..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_object.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_aput_object():
- /*
- * Store an object into an array. vBB[vCC] <- vAA.
- */
- /* op vAA, vBB, vCC */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- bl MterpAputObject
- cmp r0, #0
- beq MterpPossibleException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_aput_short.S b/runtime/interpreter/mterp/arm/op_aput_short.S
deleted file mode 100644
index f624163..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm/op_aput_wide.S b/runtime/interpreter/mterp/arm/op_aput_wide.S
deleted file mode 100644
index 769522a..0000000
--- a/runtime/interpreter/mterp/arm/op_aput_wide.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def op_aput_wide():
- /*
- * Array put, 64 bits. vBB[vCC] <- vAA.
- *
- * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
- */
- /* aput-wide vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG r0, r2 @ r0<- vBB (array object)
- GET_VREG r1, r3 @ r1<- vCC (requested index)
- cmp r0, #0 @ null array object?
- beq common_errNullObject @ yes, bail
- ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- arrayObj->length
- add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width
- cmp r1, r3 @ compare unsigned index, length
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- bcs common_errArrayIndex @ index >= length, bail
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1
- GET_INST_OPCODE ip @ extract opcode from rINST
- strd r2, [r0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] @ r2/r3<- vBB[vCC]
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_array_length.S b/runtime/interpreter/mterp/arm/op_array_length.S
deleted file mode 100644
index 3ec24b8..0000000
--- a/runtime/interpreter/mterp/arm/op_array_length.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_array_length():
- /*
- * Return the length of an array.
- */
- mov r1, rINST, lsr #12 @ r1<- B
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r0, r1 @ r0<- vB (object ref)
- cmp r0, #0 @ is object null?
- beq common_errNullObject @ yup, fail
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET] @ r3<- array length
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG r3, r2 @ vB<- length
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_check_cast.S b/runtime/interpreter/mterp/arm/op_check_cast.S
deleted file mode 100644
index a56451b..0000000
--- a/runtime/interpreter/mterp/arm/op_check_cast.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_check_cast():
- /*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
- mov r3, rSELF @ r3<- self
- bl MterpCheckCast @ (index, &obj, method, self)
- PREFETCH_INST 2
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_cmp_long.S b/runtime/interpreter/mterp/arm/op_cmp_long.S
deleted file mode 100644
index 2f87716..0000000
--- a/runtime/interpreter/mterp/arm/op_cmp_long.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def op_cmp_long():
- /*
- * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
- * register based on the results of the comparison.
- */
- /* cmp-long vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
- ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
- ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
- cmp r0, r2
- sbcs ip, r1, r3 @ Sets correct CCs for checking LT (but not EQ/NE)
- mov ip, #0
- mvnlt ip, #0 @ -1
- cmpeq r0, r2 @ For correct EQ/NE, we may need to repeat the first CMP
- orrne ip, #1
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- SET_VREG ip, r9 @ vAA<- ip
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_cmpg_double.S b/runtime/interpreter/mterp/arm/op_cmpg_double.S
deleted file mode 100644
index a166d16..0000000
--- a/runtime/interpreter/mterp/arm/op_cmpg_double.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def op_cmpg_double():
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x < y) {
- * return -1;
- * } else if (x > y) {
- * return 1;
- * } else {
- * return 1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- fldd d0, [r2] @ d0<- vBB
- fldd d1, [r3] @ d1<- vCC
- vcmpe.f64 d0, d1 @ compare (vBB, vCC)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mov r0, #1 @ r0<- 1 (default)
- GET_INST_OPCODE ip @ extract opcode from rINST
- fmstat @ export status flags
- mvnmi r0, #0 @ (less than) r1<- -1
- moveq r0, #0 @ (equal) r1<- 0
- SET_VREG r0, r9 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_cmpg_float.S b/runtime/interpreter/mterp/arm/op_cmpg_float.S
deleted file mode 100644
index e14f4ec..0000000
--- a/runtime/interpreter/mterp/arm/op_cmpg_float.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def op_cmpg_float():
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x < y) {
- * return -1;
- * } else if (x > y) {
- * return 1;
- * } else {
- * return 1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- flds s0, [r2] @ s0<- vBB
- flds s1, [r3] @ s1<- vCC
- vcmpe.f32 s0, s1 @ compare (vBB, vCC)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mov r0, #1 @ r0<- 1 (default)
- GET_INST_OPCODE ip @ extract opcode from rINST
- fmstat @ export status flags
- mvnmi r0, #0 @ (less than) r1<- -1
- moveq r0, #0 @ (equal) r1<- 0
- SET_VREG r0, r9 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_cmpl_double.S b/runtime/interpreter/mterp/arm/op_cmpl_double.S
deleted file mode 100644
index 44c827a..0000000
--- a/runtime/interpreter/mterp/arm/op_cmpl_double.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def op_cmpl_double():
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x > y) {
- * return 1;
- * } else if (x < y) {
- * return -1;
- * } else {
- * return -1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- fldd d0, [r2] @ d0<- vBB
- fldd d1, [r3] @ d1<- vCC
- vcmpe.f64 d0, d1 @ compare (vBB, vCC)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mvn r0, #0 @ r0<- -1 (default)
- GET_INST_OPCODE ip @ extract opcode from rINST
- fmstat @ export status flags
- movgt r0, #1 @ (greater than) r1<- 1
- moveq r0, #0 @ (equal) r1<- 0
- SET_VREG r0, r9 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_cmpl_float.S b/runtime/interpreter/mterp/arm/op_cmpl_float.S
deleted file mode 100644
index c202663..0000000
--- a/runtime/interpreter/mterp/arm/op_cmpl_float.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def op_cmpl_float():
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x > y) {
- * return 1;
- * } else if (x < y) {
- * return -1;
- * } else {
- * return -1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC
- flds s0, [r2] @ s0<- vBB
- flds s1, [r3] @ s1<- vCC
- vcmpe.f32 s0, s1 @ compare (vBB, vCC)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mvn r0, #0 @ r0<- -1 (default)
- GET_INST_OPCODE ip @ extract opcode from rINST
- fmstat @ export status flags
- movgt r0, #1 @ (greater than) r1<- 1
- moveq r0, #0 @ (equal) r1<- 0
- SET_VREG r0, r9 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const.S b/runtime/interpreter/mterp/arm/op_const.S
deleted file mode 100644
index e5ef50e..0000000
--- a/runtime/interpreter/mterp/arm/op_const.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const():
- /* const vAA, #+BBBBbbbb */
- mov r3, rINST, lsr #8 @ r3<- AA
- FETCH r0, 1 @ r0<- bbbb (low)
- FETCH r1, 2 @ r1<- BBBB (high)
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG r0, r3 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_16.S b/runtime/interpreter/mterp/arm/op_const_16.S
deleted file mode 100644
index 3bb89d0..0000000
--- a/runtime/interpreter/mterp/arm/op_const_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, #+BBBB */
- FETCH_S r0, 1 @ r0<- ssssBBBB (sign-extended)
- mov r3, rINST, lsr #8 @ r3<- AA
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- SET_VREG r0, r3 @ vAA<- r0
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_4.S b/runtime/interpreter/mterp/arm/op_const_4.S
deleted file mode 100644
index bfb4246..0000000
--- a/runtime/interpreter/mterp/arm/op_const_4.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_4():
- /* const/4 vA, #+B */
- sbfx r1, rINST, #12, #4 @ r1<- sssssssB (sign-extended)
- ubfx r0, rINST, #8, #4 @ r0<- A
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ ip<- opcode from rINST
- SET_VREG r1, r0 @ fp[A]<- r1
- GOTO_OPCODE ip @ execute next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_class.S b/runtime/interpreter/mterp/arm/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/arm/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/arm/op_const_high16.S b/runtime/interpreter/mterp/arm/op_const_high16.S
deleted file mode 100644
index 7f20e11..0000000
--- a/runtime/interpreter/mterp/arm/op_const_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, #+BBBB0000 */
- FETCH r0, 1 @ r0<- 0000BBBB (zero-extended)
- mov r3, rINST, lsr #8 @ r3<- AA
- mov r0, r0, lsl #16 @ r0<- BBBB0000
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- SET_VREG r0, r3 @ vAA<- r0
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_method_handle.S b/runtime/interpreter/mterp/arm/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/arm/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/arm/op_const_method_type.S b/runtime/interpreter/mterp/arm/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/arm/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/arm/op_const_string.S b/runtime/interpreter/mterp/arm/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/arm/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/arm/op_const_string_jumbo.S b/runtime/interpreter/mterp/arm/op_const_string_jumbo.S
deleted file mode 100644
index 29c9854..0000000
--- a/runtime/interpreter/mterp/arm/op_const_string_jumbo.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, String@BBBBBBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- bbbb (low)
- FETCH r2, 2 @ r2<- BBBB (high)
- mov r1, rINST, lsr #8 @ r1<- AA
- orr r0, r0, r2, lsl #16 @ r1<- BBBBbbbb
- add r2, rFP, #OFF_FP_SHADOWFRAME
- mov r3, rSELF
- bl MterpConstString @ (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 3 @ advance rPC
- cmp r0, #0 @ fail?
- bne MterpPossibleException @ let reference interpreter deal with it.
- ADVANCE 3 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_wide.S b/runtime/interpreter/mterp/arm/op_const_wide.S
deleted file mode 100644
index 40bac6d..0000000
--- a/runtime/interpreter/mterp/arm/op_const_wide.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
- FETCH r0, 1 @ r0<- bbbb (low)
- FETCH r1, 2 @ r1<- BBBB (low middle)
- FETCH r2, 3 @ r2<- hhhh (high middle)
- orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word)
- FETCH r3, 4 @ r3<- HHHH (high)
- mov r9, rINST, lsr #8 @ r9<- AA
- orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word)
- CLEAR_SHADOW_PAIR r9, r2, r3 @ Zero out the shadow regs
- FETCH_ADVANCE_INST 5 @ advance rPC, load rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_wide_16.S b/runtime/interpreter/mterp/arm/op_const_wide_16.S
deleted file mode 100644
index 7d334c9..0000000
--- a/runtime/interpreter/mterp/arm/op_const_wide_16.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, #+BBBB */
- FETCH_S r0, 1 @ r0<- ssssBBBB (sign-extended)
- mov r3, rINST, lsr #8 @ r3<- AA
- mov r1, r0, asr #31 @ r1<- ssssssss
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r3, r2, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r3, {r0-r1} @ vAA<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_wide_32.S b/runtime/interpreter/mterp/arm/op_const_wide_32.S
deleted file mode 100644
index eeb5fa5..0000000
--- a/runtime/interpreter/mterp/arm/op_const_wide_32.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, #+BBBBbbbb */
- FETCH r0, 1 @ r0<- 0000bbbb (low)
- mov r3, rINST, lsr #8 @ r3<- AA
- FETCH_S r2, 2 @ r2<- ssssBBBB (high)
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb
- CLEAR_SHADOW_PAIR r3, r2, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
- mov r1, r0, asr #31 @ r1<- ssssssss
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r3, {r0-r1} @ vAA<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_const_wide_high16.S b/runtime/interpreter/mterp/arm/op_const_wide_high16.S
deleted file mode 100644
index 57ce024..0000000
--- a/runtime/interpreter/mterp/arm/op_const_wide_high16.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, #+BBBB000000000000 */
- FETCH r1, 1 @ r1<- 0000BBBB (zero-extended)
- mov r3, rINST, lsr #8 @ r3<- AA
- mov r0, #0 @ r0<- 00000000
- mov r1, r1, lsl #16 @ r1<- BBBB0000
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r3, r0, r2 @ Zero shadow regs
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r3, {r0-r1} @ vAA<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_div_double.S b/runtime/interpreter/mterp/arm/op_div_double.S
deleted file mode 100644
index d909694..0000000
--- a/runtime/interpreter/mterp/arm/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% fbinopWide(instr="fdivd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_div_double_2addr.S b/runtime/interpreter/mterp/arm/op_div_double_2addr.S
deleted file mode 100644
index 499c87b..0000000
--- a/runtime/interpreter/mterp/arm/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% fbinopWide2addr(instr="fdivd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_div_float.S b/runtime/interpreter/mterp/arm/op_div_float.S
deleted file mode 100644
index 1136909..0000000
--- a/runtime/interpreter/mterp/arm/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% fbinop(instr="fdivs s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_div_float_2addr.S b/runtime/interpreter/mterp/arm/op_div_float_2addr.S
deleted file mode 100644
index 5198bc7..0000000
--- a/runtime/interpreter/mterp/arm/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% fbinop2addr(instr="fdivs s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_div_int.S b/runtime/interpreter/mterp/arm/op_div_int.S
deleted file mode 100644
index 211ac77..0000000
--- a/runtime/interpreter/mterp/arm/op_div_int.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_div_int():
- /*
- * 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/runtime/interpreter/mterp/arm/op_div_int_2addr.S b/runtime/interpreter/mterp/arm/op_div_int_2addr.S
deleted file mode 100644
index 968a499..0000000
--- a/runtime/interpreter/mterp/arm/op_div_int_2addr.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_div_int_2addr():
- /*
- * 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/runtime/interpreter/mterp/arm/op_div_int_lit16.S b/runtime/interpreter/mterp/arm/op_div_int_lit16.S
deleted file mode 100644
index f1e2126..0000000
--- a/runtime/interpreter/mterp/arm/op_div_int_lit16.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_div_int_lit16():
- /*
- * 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/runtime/interpreter/mterp/arm/op_div_int_lit8.S b/runtime/interpreter/mterp/arm/op_div_int_lit8.S
deleted file mode 100644
index e0d88f8..0000000
--- a/runtime/interpreter/mterp/arm/op_div_int_lit8.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_div_int_lit8():
- /*
- * 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/runtime/interpreter/mterp/arm/op_div_long.S b/runtime/interpreter/mterp/arm/op_div_long.S
deleted file mode 100644
index 7423f5b..0000000
--- a/runtime/interpreter/mterp/arm/op_div_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long():
-% binopWide(instr="bl __aeabi_ldivmod", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm/op_div_long_2addr.S b/runtime/interpreter/mterp/arm/op_div_long_2addr.S
deleted file mode 100644
index fed8b8f..0000000
--- a/runtime/interpreter/mterp/arm/op_div_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long_2addr():
-% binopWide2addr(instr="bl __aeabi_ldivmod", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm/op_double_to_float.S b/runtime/interpreter/mterp/arm/op_double_to_float.S
deleted file mode 100644
index dcd575e..0000000
--- a/runtime/interpreter/mterp/arm/op_double_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_float():
-% funopNarrower(instr="vcvt.f32.f64 s0, d0")
diff --git a/runtime/interpreter/mterp/arm/op_double_to_int.S b/runtime/interpreter/mterp/arm/op_double_to_int.S
deleted file mode 100644
index e11daad..0000000
--- a/runtime/interpreter/mterp/arm/op_double_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_int():
-% funopNarrower(instr="ftosizd s0, d0")
diff --git a/runtime/interpreter/mterp/arm/op_double_to_long.S b/runtime/interpreter/mterp/arm/op_double_to_long.S
deleted file mode 100644
index c475704..0000000
--- a/runtime/interpreter/mterp/arm/op_double_to_long.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def op_double_to_long():
-% unopWide(instr="bl d2l_doconv")
-
-%def op_double_to_long_sister_code():
-/*
- * Convert the double in r0/r1 to a long in r0/r1.
- *
- * We have to clip values to long min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
- */
-d2l_doconv:
- ubfx r2, r1, #20, #11 @ grab the exponent
- movw r3, #0x43e
- cmp r2, r3 @ MINLONG < x > MAXLONG?
- bhs d2l_special_cases
- b __aeabi_d2lz @ tail call to convert double to long
-d2l_special_cases:
- movw r3, #0x7ff
- cmp r2, r3
- beq d2l_maybeNaN @ NaN?
-d2l_notNaN:
- adds r1, r1, r1 @ sign bit to carry
- mov r0, #0xffffffff @ assume maxlong for lsw
- mov r1, #0x7fffffff @ assume maxlong for msw
- adc r0, r0, #0
- adc r1, r1, #0 @ convert maxlong to minlong if exp negative
- bx lr @ return
-d2l_maybeNaN:
- orrs r3, r0, r1, lsl #12
- beq d2l_notNaN @ if fraction is non-zero, it's a NaN
- mov r0, #0
- mov r1, #0
- bx lr @ return 0 for NaN
diff --git a/runtime/interpreter/mterp/arm/op_fill_array_data.S b/runtime/interpreter/mterp/arm/op_fill_array_data.S
deleted file mode 100644
index ea0d397..0000000
--- a/runtime/interpreter/mterp/arm/op_fill_array_data.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- bbbb (lo)
- FETCH r1, 2 @ r1<- BBBB (hi)
- mov r3, rINST, lsr #8 @ r3<- AA
- orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb
- GET_VREG r0, r3 @ r0<- vAA (array object)
- add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.)
- bl MterpFillArrayData @ (obj, payload)
- cmp r0, #0 @ 0 means an exception is thrown
- beq MterpPossibleException @ exception?
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_filled_new_array.S b/runtime/interpreter/mterp/arm/op_filled_new_array.S
deleted file mode 100644
index fb1c3c5..0000000
--- a/runtime/interpreter/mterp/arm/op_filled_new_array.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
- /*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
- .extern $helper
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rSELF
- bl $helper
- cmp r0, #0
- beq MterpPossibleException
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_filled_new_array_range.S b/runtime/interpreter/mterp/arm/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/arm/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/arm/op_float_to_double.S b/runtime/interpreter/mterp/arm/op_float_to_double.S
deleted file mode 100644
index 760466e..0000000
--- a/runtime/interpreter/mterp/arm/op_float_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_double():
-% funopWider(instr="vcvt.f64.f32 d0, s0")
diff --git a/runtime/interpreter/mterp/arm/op_float_to_int.S b/runtime/interpreter/mterp/arm/op_float_to_int.S
deleted file mode 100644
index 77837ba..0000000
--- a/runtime/interpreter/mterp/arm/op_float_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_int():
-% funop(instr="ftosizs s1, s0")
diff --git a/runtime/interpreter/mterp/arm/op_float_to_long.S b/runtime/interpreter/mterp/arm/op_float_to_long.S
deleted file mode 100644
index 482b18e..0000000
--- a/runtime/interpreter/mterp/arm/op_float_to_long.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_float_to_long():
-% unopWider(instr="bl f2l_doconv")
-
-%def op_float_to_long_sister_code():
-/*
- * Convert the float in r0 to a long in r0/r1.
- *
- * We have to clip values to long min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
- */
-f2l_doconv:
- ubfx r2, r0, #23, #8 @ grab the exponent
- cmp r2, #0xbe @ MININT < x > MAXINT?
- bhs f2l_special_cases
- b __aeabi_f2lz @ tail call to convert float to long
-f2l_special_cases:
- cmp r2, #0xff @ NaN or infinity?
- beq f2l_maybeNaN
-f2l_notNaN:
- adds r0, r0, r0 @ sign bit to carry
- mov r0, #0xffffffff @ assume maxlong for lsw
- mov r1, #0x7fffffff @ assume maxlong for msw
- adc r0, r0, #0
- adc r1, r1, #0 @ convert maxlong to minlong if exp negative
- bx lr @ return
-f2l_maybeNaN:
- lsls r3, r0, #9
- beq f2l_notNaN @ if fraction is non-zero, it's a NaN
- mov r0, #0
- mov r1, #0
- bx lr @ return 0 for NaN
diff --git a/runtime/interpreter/mterp/arm/op_goto.S b/runtime/interpreter/mterp/arm/op_goto.S
deleted file mode 100644
index 832a989..0000000
--- a/runtime/interpreter/mterp/arm/op_goto.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto():
- /*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- sbfx rINST, rINST, #8, #8 @ rINST<- ssssssAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm/op_goto_16.S b/runtime/interpreter/mterp/arm/op_goto_16.S
deleted file mode 100644
index 4324a8d..0000000
--- a/runtime/interpreter/mterp/arm/op_goto_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto_16():
- /*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm/op_goto_32.S b/runtime/interpreter/mterp/arm/op_goto_32.S
deleted file mode 100644
index b01d2fa..0000000
--- a/runtime/interpreter/mterp/arm/op_goto_32.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_goto_32():
- /*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Unlike most opcodes, this one is allowed to branch to itself, so
- * our "backward branch" test must be "<=0" instead of "<0". Because
- * we need the V bit set, we'll use an adds to convert from Dalvik
- * offset to byte offset.
- */
- /* goto/32 +AAAAAAAA */
- FETCH r0, 1 @ r0<- aaaa (lo)
- FETCH r3, 2 @ r1<- AAAA (hi)
- orrs rINST, r0, r3, lsl #16 @ rINST<- AAAAaaaa
- b MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/arm/op_if_eq.S b/runtime/interpreter/mterp/arm/op_if_eq.S
deleted file mode 100644
index da58674..0000000
--- a/runtime/interpreter/mterp/arm/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(condition="eq")
diff --git a/runtime/interpreter/mterp/arm/op_if_eqz.S b/runtime/interpreter/mterp/arm/op_if_eqz.S
deleted file mode 100644
index 0639664..0000000
--- a/runtime/interpreter/mterp/arm/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(condition="eq")
diff --git a/runtime/interpreter/mterp/arm/op_if_ge.S b/runtime/interpreter/mterp/arm/op_if_ge.S
deleted file mode 100644
index 5b6ed2f..0000000
--- a/runtime/interpreter/mterp/arm/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(condition="ge")
diff --git a/runtime/interpreter/mterp/arm/op_if_gez.S b/runtime/interpreter/mterp/arm/op_if_gez.S
deleted file mode 100644
index ea6cda7..0000000
--- a/runtime/interpreter/mterp/arm/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(condition="ge")
diff --git a/runtime/interpreter/mterp/arm/op_if_gt.S b/runtime/interpreter/mterp/arm/op_if_gt.S
deleted file mode 100644
index 201decf..0000000
--- a/runtime/interpreter/mterp/arm/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(condition="gt")
diff --git a/runtime/interpreter/mterp/arm/op_if_gtz.S b/runtime/interpreter/mterp/arm/op_if_gtz.S
deleted file mode 100644
index 1fdbb6e..0000000
--- a/runtime/interpreter/mterp/arm/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(condition="gt")
diff --git a/runtime/interpreter/mterp/arm/op_if_le.S b/runtime/interpreter/mterp/arm/op_if_le.S
deleted file mode 100644
index e6024f2..0000000
--- a/runtime/interpreter/mterp/arm/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(condition="le")
diff --git a/runtime/interpreter/mterp/arm/op_if_lez.S b/runtime/interpreter/mterp/arm/op_if_lez.S
deleted file mode 100644
index 62c0d2c..0000000
--- a/runtime/interpreter/mterp/arm/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(condition="le")
diff --git a/runtime/interpreter/mterp/arm/op_if_lt.S b/runtime/interpreter/mterp/arm/op_if_lt.S
deleted file mode 100644
index 4ef22fd..0000000
--- a/runtime/interpreter/mterp/arm/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(condition="lt")
diff --git a/runtime/interpreter/mterp/arm/op_if_ltz.S b/runtime/interpreter/mterp/arm/op_if_ltz.S
deleted file mode 100644
index 84b2d0b..0000000
--- a/runtime/interpreter/mterp/arm/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(condition="lt")
diff --git a/runtime/interpreter/mterp/arm/op_if_ne.S b/runtime/interpreter/mterp/arm/op_if_ne.S
deleted file mode 100644
index ec3a688..0000000
--- a/runtime/interpreter/mterp/arm/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(condition="ne")
diff --git a/runtime/interpreter/mterp/arm/op_if_nez.S b/runtime/interpreter/mterp/arm/op_if_nez.S
deleted file mode 100644
index 7009c3a..0000000
--- a/runtime/interpreter/mterp/arm/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(condition="ne")
diff --git a/runtime/interpreter/mterp/arm/op_iget.S b/runtime/interpreter/mterp/arm/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/arm/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm/op_iget_boolean.S b/runtime/interpreter/mterp/arm/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/arm/op_iget_boolean_quick.S b/runtime/interpreter/mterp/arm/op_iget_boolean_quick.S
deleted file mode 100644
index 7ac9fce..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="ldrb")
diff --git a/runtime/interpreter/mterp/arm/op_iget_byte.S b/runtime/interpreter/mterp/arm/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/arm/op_iget_byte_quick.S b/runtime/interpreter/mterp/arm/op_iget_byte_quick.S
deleted file mode 100644
index bbccaff..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="ldrsb")
diff --git a/runtime/interpreter/mterp/arm/op_iget_char.S b/runtime/interpreter/mterp/arm/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/arm/op_iget_char_quick.S b/runtime/interpreter/mterp/arm/op_iget_char_quick.S
deleted file mode 100644
index 71a9276..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="ldrh")
diff --git a/runtime/interpreter/mterp/arm/op_iget_object.S b/runtime/interpreter/mterp/arm/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/arm/op_iget_object_quick.S b/runtime/interpreter/mterp/arm/op_iget_object_quick.S
deleted file mode 100644
index 72b04b8..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_object_quick.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset@CCCC */
- mov r2, rINST, lsr #12 @ r2<- B
- FETCH r1, 1 @ r1<- field byte offset
- EXPORT_PC
- GET_VREG r0, r2 @ r0<- object we're operating on
- bl artIGetObjectFromMterp @ (obj, offset)
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iget_quick.S b/runtime/interpreter/mterp/arm/op_iget_quick.S
deleted file mode 100644
index 9894498..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iget_quick(load="ldr"):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
- /* op vA, vB, offset@CCCC */
- mov r2, rINST, lsr #12 @ r2<- B
- FETCH r1, 1 @ r1<- field byte offset
- GET_VREG r3, r2 @ r3<- object we're operating on
- ubfx r2, rINST, #8, #4 @ r2<- A
- cmp r3, #0 @ check object for null
- beq common_errNullObject @ object was null
- $load r0, [r3, r1] @ r0<- obj.field
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- SET_VREG r0, r2 @ fp[A]<- r0
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iget_short.S b/runtime/interpreter/mterp/arm/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/arm/op_iget_short_quick.S b/runtime/interpreter/mterp/arm/op_iget_short_quick.S
deleted file mode 100644
index 5dbdc4f..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="ldrsh")
diff --git a/runtime/interpreter/mterp/arm/op_iget_wide.S b/runtime/interpreter/mterp/arm/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/arm/op_iget_wide_quick.S b/runtime/interpreter/mterp/arm/op_iget_wide_quick.S
deleted file mode 100644
index e247fb2..0000000
--- a/runtime/interpreter/mterp/arm/op_iget_wide_quick.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_iget_wide_quick():
- /* iget-wide-quick vA, vB, offset@CCCC */
- mov r2, rINST, lsr #12 @ r2<- B
- FETCH ip, 1 @ ip<- field byte offset
- GET_VREG r3, r2 @ r3<- object we're operating on
- ubfx r2, rINST, #8, #4 @ r2<- A
- cmp r3, #0 @ check object for null
- beq common_errNullObject @ object was null
- ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
- CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r3, {r0-r1} @ fp[A]<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_instance_of.S b/runtime/interpreter/mterp/arm/op_instance_of.S
deleted file mode 100644
index 020b4c5..0000000
--- a/runtime/interpreter/mterp/arm/op_instance_of.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def op_instance_of():
- /*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class@CCCC */
- EXPORT_PC
- FETCH r0, 1 @ r0<- CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
- mov r3, rSELF @ r3<- self
- bl MterpInstanceOf @ (index, &obj, method, self)
- ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r9, rINST, #8, #4 @ r9<- A
- PREFETCH_INST 2
- cmp r1, #0 @ exception pending?
- bne MterpException
- ADVANCE 2 @ advance rPC
- SET_VREG r0, r9 @ vA<- r0
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_int_to_byte.S b/runtime/interpreter/mterp/arm/op_int_to_byte.S
deleted file mode 100644
index 3229b5e..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="sxtb r0, r0")
diff --git a/runtime/interpreter/mterp/arm/op_int_to_char.S b/runtime/interpreter/mterp/arm/op_int_to_char.S
deleted file mode 100644
index 9ce13b8..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(instr="uxth r0, r0")
diff --git a/runtime/interpreter/mterp/arm/op_int_to_double.S b/runtime/interpreter/mterp/arm/op_int_to_double.S
deleted file mode 100644
index cc8065a..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_double():
-% funopWider(instr="fsitod d0, s0")
diff --git a/runtime/interpreter/mterp/arm/op_int_to_float.S b/runtime/interpreter/mterp/arm/op_int_to_float.S
deleted file mode 100644
index b19f3f3..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_float():
-% funop(instr="fsitos s1, s0")
diff --git a/runtime/interpreter/mterp/arm/op_int_to_long.S b/runtime/interpreter/mterp/arm/op_int_to_long.S
deleted file mode 100644
index 8d67899..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_long():
-% unopWider(instr="mov r1, r0, asr #31")
diff --git a/runtime/interpreter/mterp/arm/op_int_to_short.S b/runtime/interpreter/mterp/arm/op_int_to_short.S
deleted file mode 100644
index 2332460..0000000
--- a/runtime/interpreter/mterp/arm/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="sxth r0, r0")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_custom.S b/runtime/interpreter/mterp/arm/op_invoke_custom.S
deleted file mode 100644
index 0bd29b4..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_custom.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
- /*
- * Handle an invoke-custom invocation.
- *
- * for: invoke-custom, invoke-custom/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, call_site@BBBB */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, call_site@BBBB */
diff --git a/runtime/interpreter/mterp/arm/op_invoke_custom_range.S b/runtime/interpreter/mterp/arm/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_direct.S b/runtime/interpreter/mterp/arm/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_direct_range.S b/runtime/interpreter/mterp/arm/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_interface.S b/runtime/interpreter/mterp/arm/op_invoke_interface.S
deleted file mode 100644
index b064126..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_interface.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
- /*
- * Handle an interface method call.
- *
- * for: invoke-interface, invoke-interface/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm/op_invoke_interface_range.S b/runtime/interpreter/mterp/arm/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_polymorphic.S b/runtime/interpreter/mterp/arm/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/arm/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_static.S b/runtime/interpreter/mterp/arm/op_invoke_static.S
deleted file mode 100644
index 3e38d36..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_static.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
-
diff --git a/runtime/interpreter/mterp/arm/op_invoke_static_range.S b/runtime/interpreter/mterp/arm/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_super.S b/runtime/interpreter/mterp/arm/op_invoke_super.S
deleted file mode 100644
index 3c34c99..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_super.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
- /*
- * Handle a "super" method call.
- *
- * for: invoke-super, invoke-super/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm/op_invoke_super_range.S b/runtime/interpreter/mterp/arm/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_virtual.S b/runtime/interpreter/mterp/arm/op_invoke_virtual.S
deleted file mode 100644
index 249177b..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_virtual.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
- /*
- * Handle a virtual method call.
- *
- * for: invoke-virtual, invoke-virtual/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/arm/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_virtual_range.S b/runtime/interpreter/mterp/arm/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/arm/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/arm/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/arm/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/arm/op_iput.S b/runtime/interpreter/mterp/arm/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/arm/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm/op_iput_boolean.S b/runtime/interpreter/mterp/arm/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/arm/op_iput_boolean_quick.S b/runtime/interpreter/mterp/arm/op_iput_boolean_quick.S
deleted file mode 100644
index fd077a7..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(store="strb")
diff --git a/runtime/interpreter/mterp/arm/op_iput_byte.S b/runtime/interpreter/mterp/arm/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/arm/op_iput_byte_quick.S b/runtime/interpreter/mterp/arm/op_iput_byte_quick.S
deleted file mode 100644
index 30238cf..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(store="strb")
diff --git a/runtime/interpreter/mterp/arm/op_iput_char.S b/runtime/interpreter/mterp/arm/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/arm/op_iput_char_quick.S b/runtime/interpreter/mterp/arm/op_iput_char_quick.S
deleted file mode 100644
index 0deff56..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(store="strh")
diff --git a/runtime/interpreter/mterp/arm/op_iput_object.S b/runtime/interpreter/mterp/arm/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/arm/op_iput_object_quick.S b/runtime/interpreter/mterp/arm/op_iput_object_quick.S
deleted file mode 100644
index be90b84..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_object_quick.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_iput_object_quick():
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- bl MterpIputObjectQuick
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iput_quick.S b/runtime/interpreter/mterp/arm/op_iput_quick.S
deleted file mode 100644
index f84c098..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iput_quick(store="str"):
- /* For: iput-quick, iput-object-quick */
- /* op vA, vB, offset@CCCC */
- mov r2, rINST, lsr #12 @ r2<- B
- FETCH r1, 1 @ r1<- field byte offset
- GET_VREG r3, r2 @ r3<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- cmp r3, #0 @ check object for null
- beq common_errNullObject @ object was null
- GET_VREG r0, r2 @ r0<- fp[A]
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- $store r0, [r3, r1] @ obj.field<- r0
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iput_short.S b/runtime/interpreter/mterp/arm/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/arm/op_iput_short_quick.S b/runtime/interpreter/mterp/arm/op_iput_short_quick.S
deleted file mode 100644
index 6a1b651..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(store="strh")
diff --git a/runtime/interpreter/mterp/arm/op_iput_wide.S b/runtime/interpreter/mterp/arm/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/arm/op_iput_wide_quick.S b/runtime/interpreter/mterp/arm/op_iput_wide_quick.S
deleted file mode 100644
index 8408f0a..0000000
--- a/runtime/interpreter/mterp/arm/op_iput_wide_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset@CCCC */
- mov r2, rINST, lsr #12 @ r2<- B
- FETCH r3, 1 @ r3<- field byte offset
- GET_VREG r2, r2 @ r2<- fp[B], the object pointer
- ubfx r0, rINST, #8, #4 @ r0<- A
- cmp r2, #0 @ check object for null
- beq common_errNullObject @ object was null
- VREG_INDEX_TO_ADDR r0, r0 @ r0<- &fp[A]
- ldmia r0, {r0-r1} @ r0/r1<- fp[A]/fp[A+1]
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- strd r0, [r2, r3] @ obj.field<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_long_to_double.S b/runtime/interpreter/mterp/arm/op_long_to_double.S
deleted file mode 100644
index 3228c70..0000000
--- a/runtime/interpreter/mterp/arm/op_long_to_double.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_long_to_double():
- /*
- * Specialised 64-bit floating point operation.
- *
- * Note: The result will be returned in d2.
- *
- * For: long-to-double
- */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
- vldr d0, [r3] @ d0<- vAA
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
-
- vcvt.f64.s32 d1, s1 @ d1<- (double)(vAAh)
- vcvt.f64.u32 d2, s0 @ d2<- (double)(vAAl)
- vldr d3, constval$opcode
- vmla.f64 d2, d1, d3 @ d2<- vAAh*2^32 + vAAl
-
- GET_INST_OPCODE ip @ extract opcode from rINST
- vstr.64 d2, [r9] @ vAA<- d2
- GOTO_OPCODE ip @ jump to next instruction
-
- /* literal pool helper */
-constval${opcode}:
- .8byte 0x41f0000000000000
diff --git a/runtime/interpreter/mterp/arm/op_long_to_float.S b/runtime/interpreter/mterp/arm/op_long_to_float.S
deleted file mode 100644
index c021975..0000000
--- a/runtime/interpreter/mterp/arm/op_long_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_float():
-% unopNarrower(instr="bl __aeabi_l2f")
diff --git a/runtime/interpreter/mterp/arm/op_long_to_int.S b/runtime/interpreter/mterp/arm/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/arm/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/arm/op_monitor_enter.S b/runtime/interpreter/mterp/arm/op_monitor_enter.S
deleted file mode 100644
index afe293c..0000000
--- a/runtime/interpreter/mterp/arm/op_monitor_enter.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_monitor_enter():
- /*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- EXPORT_PC
- mov r2, rINST, lsr #8 @ r2<- AA
- GET_VREG r0, r2 @ r0<- vAA (object)
- mov r1, rSELF @ r1<- self
- bl artLockObjectFromCode
- cmp r0, #0
- bne MterpException
- FETCH_ADVANCE_INST 1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_monitor_exit.S b/runtime/interpreter/mterp/arm/op_monitor_exit.S
deleted file mode 100644
index ddfa774..0000000
--- a/runtime/interpreter/mterp/arm/op_monitor_exit.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_monitor_exit():
- /*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- EXPORT_PC
- mov r2, rINST, lsr #8 @ r2<- AA
- GET_VREG r0, r2 @ r0<- vAA (object)
- mov r1, rSELF @ r0<- self
- bl artUnlockObjectFromCode @ r0<- success for unlock(self, obj)
- cmp r0, #0 @ failed?
- bne MterpException
- FETCH_ADVANCE_INST 1 @ before throw: advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move.S b/runtime/interpreter/mterp/arm/op_move.S
deleted file mode 100644
index 7dd893f..0000000
--- a/runtime/interpreter/mterp/arm/op_move.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- mov r1, rINST, lsr #12 @ r1<- B from 15:12
- ubfx r0, rINST, #8, #4 @ r0<- A from 11:8
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- GET_VREG r2, r1 @ r2<- fp[B]
- GET_INST_OPCODE ip @ ip<- opcode from rINST
- .if $is_object
- SET_VREG_OBJECT r2, r0 @ fp[A]<- r2
- .else
- SET_VREG r2, r0 @ fp[A]<- r2
- .endif
- GOTO_OPCODE ip @ execute next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_16.S b/runtime/interpreter/mterp/arm/op_move_16.S
deleted file mode 100644
index 86601aa..0000000
--- a/runtime/interpreter/mterp/arm/op_move_16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- FETCH r1, 2 @ r1<- BBBB
- FETCH r0, 1 @ r0<- AAAA
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- GET_VREG r2, r1 @ r2<- fp[BBBB]
- GET_INST_OPCODE ip @ extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT r2, r0 @ fp[AAAA]<- r2
- .else
- SET_VREG r2, r0 @ fp[AAAA]<- r2
- .endif
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_exception.S b/runtime/interpreter/mterp/arm/op_move_exception.S
deleted file mode 100644
index 9136228..0000000
--- a/runtime/interpreter/mterp/arm/op_move_exception.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- mov r2, rINST, lsr #8 @ r2<- AA
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r1, #0 @ r1<- 0
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- SET_VREG_OBJECT r3, r2 @ fp[AA]<- exception obj
- GET_INST_OPCODE ip @ extract opcode from rINST
- str r1, [rSELF, #THREAD_EXCEPTION_OFFSET] @ clear exception
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_from16.S b/runtime/interpreter/mterp/arm/op_move_from16.S
deleted file mode 100644
index 113909c..0000000
--- a/runtime/interpreter/mterp/arm/op_move_from16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- FETCH r1, 1 @ r1<- BBBB
- mov r0, rINST, lsr #8 @ r0<- AA
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_VREG r2, r1 @ r2<- fp[BBBB]
- GET_INST_OPCODE ip @ extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT r2, r0 @ fp[AA]<- r2
- .else
- SET_VREG r2, r0 @ fp[AA]<- r2
- .endif
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_object.S b/runtime/interpreter/mterp/arm/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/arm/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/arm/op_move_object_16.S b/runtime/interpreter/mterp/arm/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/arm/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/arm/op_move_object_from16.S b/runtime/interpreter/mterp/arm/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/arm/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/arm/op_move_result.S b/runtime/interpreter/mterp/arm/op_move_result.S
deleted file mode 100644
index eee23f6..0000000
--- a/runtime/interpreter/mterp/arm/op_move_result.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- mov r2, rINST, lsr #8 @ r2<- AA
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- ldr r0, [rFP, #OFF_FP_RESULT_REGISTER] @ get pointer to result JType.
- ldr r0, [r0] @ r0 <- result.i.
- GET_INST_OPCODE ip @ extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT r0, r2, r1 @ fp[AA]<- r0
- .else
- SET_VREG r0, r2 @ fp[AA]<- r0
- .endif
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_result_object.S b/runtime/interpreter/mterp/arm/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/arm/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/arm/op_move_result_wide.S b/runtime/interpreter/mterp/arm/op_move_result_wide.S
deleted file mode 100644
index 8b4e980..0000000
--- a/runtime/interpreter/mterp/arm/op_move_result_wide.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_move_result_wide():
- /* move-result-wide vAA */
- mov rINST, rINST, lsr #8 @ rINST<- AA
- ldr r3, [rFP, #OFF_FP_RESULT_REGISTER]
- VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[AA]
- ldmia r3, {r0-r1} @ r0/r1<- retval.j
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- stmia r2, {r0-r1} @ fp[AA]<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_wide.S b/runtime/interpreter/mterp/arm/op_move_wide.S
deleted file mode 100644
index 800f7f6..0000000
--- a/runtime/interpreter/mterp/arm/op_move_wide.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx rINST, rINST, #8, #4 @ rINST<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
- VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[A]
- ldmia r3, {r0-r1} @ r0/r1<- fp[B]
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r2, {r0-r1} @ fp[A]<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_wide_16.S b/runtime/interpreter/mterp/arm/op_move_wide_16.S
deleted file mode 100644
index ef4f0a8..0000000
--- a/runtime/interpreter/mterp/arm/op_move_wide_16.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- FETCH r3, 2 @ r3<- BBBB
- FETCH r2, 1 @ r2<- AAAA
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BBBB]
- VREG_INDEX_TO_ADDR lr, r2 @ r2<- &fp[AAAA]
- ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB]
- FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r2, r3, ip @ Zero out the shadow regs
- stmia lr, {r0-r1} @ fp[AAAA]<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_move_wide_from16.S b/runtime/interpreter/mterp/arm/op_move_wide_from16.S
deleted file mode 100644
index aae5aa3..0000000
--- a/runtime/interpreter/mterp/arm/op_move_wide_from16.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- FETCH r3, 1 @ r3<- BBBB
- mov rINST, rINST, lsr #8 @ rINST<- AA
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BBBB]
- VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[AA]
- ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB]
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r2, {r0-r1} @ fp[AA]<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_mul_double.S b/runtime/interpreter/mterp/arm/op_mul_double.S
deleted file mode 100644
index 72948c2..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% fbinopWide(instr="fmuld d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_mul_double_2addr.S b/runtime/interpreter/mterp/arm/op_mul_double_2addr.S
deleted file mode 100644
index afa7fcf..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% fbinopWide2addr(instr="fmuld d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_mul_float.S b/runtime/interpreter/mterp/arm/op_mul_float.S
deleted file mode 100644
index ecb3717..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% fbinop(instr="fmuls s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_mul_float_2addr.S b/runtime/interpreter/mterp/arm/op_mul_float_2addr.S
deleted file mode 100644
index d084b11..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% fbinop2addr(instr="fmuls s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_mul_int.S b/runtime/interpreter/mterp/arm/op_mul_int.S
deleted file mode 100644
index 8a7daf2..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int():
-/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
-% binop(instr="mul r0, r1, r0")
diff --git a/runtime/interpreter/mterp/arm/op_mul_int_2addr.S b/runtime/interpreter/mterp/arm/op_mul_int_2addr.S
deleted file mode 100644
index 98bfb7a..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_int_2addr.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_2addr():
-/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
-% binop2addr(instr="mul r0, r1, r0")
diff --git a/runtime/interpreter/mterp/arm/op_mul_int_lit16.S b/runtime/interpreter/mterp/arm/op_mul_int_lit16.S
deleted file mode 100644
index ab3f3612..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_int_lit16.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_lit16():
-/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
-% binopLit16(instr="mul r0, r1, r0")
diff --git a/runtime/interpreter/mterp/arm/op_mul_int_lit8.S b/runtime/interpreter/mterp/arm/op_mul_int_lit8.S
deleted file mode 100644
index 6cc5b89..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_int_lit8.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_lit8():
-/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
-% binopLit8(instr="mul r0, r1, r0")
diff --git a/runtime/interpreter/mterp/arm/op_mul_long.S b/runtime/interpreter/mterp/arm/op_mul_long.S
deleted file mode 100644
index c9f2e67..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_long.S
+++ /dev/null
@@ -1,38 +0,0 @@
-%def op_mul_long():
- /*
- * Signed 64-bit integer multiply.
- *
- * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
- * WX
- * x YZ
- * --------
- * ZW ZX
- * YW YX
- *
- * The low word of the result holds ZX, the high word holds
- * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because
- * it doesn't fit in the low 64 bits.
- *
- * Unlike most ARM math operations, multiply instructions have
- * restrictions on using the same register more than once (Rd and Rm
- * cannot be the same).
- */
- /* mul-long vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- and r2, r0, #255 @ r2<- BB
- mov r3, r0, lsr #8 @ r3<- CC
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[BB]
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[CC]
- ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1
- ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1
- mul ip, r2, r1 @ ip<- ZxW
- umull r1, lr, r2, r0 @ r1/lr <- ZxX
- mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
- mov r0, rINST, lsr #8 @ r0<- AA
- add r2, r2, lr @ r2<- lr + low(ZxW + (YxX))
- CLEAR_SHADOW_PAIR r0, lr, ip @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r0, r0 @ r0<- &fp[AA]
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r0, {r1-r2 } @ vAA/vAA+1<- r1/r2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_mul_long_2addr.S b/runtime/interpreter/mterp/arm/op_mul_long_2addr.S
deleted file mode 100644
index 2fd9f5c..0000000
--- a/runtime/interpreter/mterp/arm/op_mul_long_2addr.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def op_mul_long_2addr():
- /*
- * Signed 64-bit integer multiply, "/2addr" version.
- *
- * See op_mul_long for an explanation.
- *
- * We get a little tight on registers, so to avoid looking up &fp[A]
- * again we stuff it into rINST.
- */
- /* mul-long/2addr vA, vB */
- mov r1, rINST, lsr #12 @ r1<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- VREG_INDEX_TO_ADDR r1, r1 @ r1<- &fp[B]
- VREG_INDEX_TO_ADDR rINST, r9 @ rINST<- &fp[A]
- ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1
- ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1
- mul ip, r2, r1 @ ip<- ZxW
- umull r1, lr, r2, r0 @ r1/lr <- ZxX
- mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
- mov r0, rINST @ r0<- &fp[A] (free up rINST)
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- add r2, r2, lr @ r2<- r2 + low(ZxW + (YxX))
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r0, {r1-r2} @ vAA/vAA+1<- r1/r2
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_neg_double.S b/runtime/interpreter/mterp/arm/op_neg_double.S
deleted file mode 100644
index df73341..0000000
--- a/runtime/interpreter/mterp/arm/op_neg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_double():
-% unopWide(instr="add r1, r1, #0x80000000")
diff --git a/runtime/interpreter/mterp/arm/op_neg_float.S b/runtime/interpreter/mterp/arm/op_neg_float.S
deleted file mode 100644
index 4ed178f..0000000
--- a/runtime/interpreter/mterp/arm/op_neg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_float():
-% unop(instr="add r0, r0, #0x80000000")
diff --git a/runtime/interpreter/mterp/arm/op_neg_int.S b/runtime/interpreter/mterp/arm/op_neg_int.S
deleted file mode 100644
index 08b72a1..0000000
--- a/runtime/interpreter/mterp/arm/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr="rsb r0, r0, #0")
diff --git a/runtime/interpreter/mterp/arm/op_neg_long.S b/runtime/interpreter/mterp/arm/op_neg_long.S
deleted file mode 100644
index 716c6dc..0000000
--- a/runtime/interpreter/mterp/arm/op_neg_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_long():
-% unopWide(preinstr="rsbs r0, r0, #0", instr="rsc r1, r1, #0")
diff --git a/runtime/interpreter/mterp/arm/op_new_array.S b/runtime/interpreter/mterp/arm/op_new_array.S
deleted file mode 100644
index 04b5fa4..0000000
--- a/runtime/interpreter/mterp/arm/op_new_array.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_new_array():
- /*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class@CCCC */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpNewArray
- cmp r0, #0
- beq MterpPossibleException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_new_instance.S b/runtime/interpreter/mterp/arm/op_new_instance.S
deleted file mode 100644
index 447a6cf..0000000
--- a/runtime/interpreter/mterp/arm/op_new_instance.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_new_instance():
- /*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class@BBBB */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rSELF
- mov r2, rINST
- bl MterpNewInstance @ (shadow_frame, self, inst_data)
- cmp r0, #0
- beq MterpPossibleException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_nop.S b/runtime/interpreter/mterp/arm/op_nop.S
deleted file mode 100644
index 8bfd1a3..0000000
--- a/runtime/interpreter/mterp/arm/op_nop.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_nop():
- FETCH_ADVANCE_INST 1 @ advance to next instr, load rINST
- GET_INST_OPCODE ip @ ip<- opcode from rINST
- GOTO_OPCODE ip @ execute it
diff --git a/runtime/interpreter/mterp/arm/op_not_int.S b/runtime/interpreter/mterp/arm/op_not_int.S
deleted file mode 100644
index 90c4eed..0000000
--- a/runtime/interpreter/mterp/arm/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr="mvn r0, r0")
diff --git a/runtime/interpreter/mterp/arm/op_not_long.S b/runtime/interpreter/mterp/arm/op_not_long.S
deleted file mode 100644
index 29104f2..0000000
--- a/runtime/interpreter/mterp/arm/op_not_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_long():
-% unopWide(preinstr="mvn r0, r0", instr="mvn r1, r1")
diff --git a/runtime/interpreter/mterp/arm/op_or_int.S b/runtime/interpreter/mterp/arm/op_or_int.S
deleted file mode 100644
index 6992d2a..0000000
--- a/runtime/interpreter/mterp/arm/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="orr r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_or_int_2addr.S b/runtime/interpreter/mterp/arm/op_or_int_2addr.S
deleted file mode 100644
index 805ca09..0000000
--- a/runtime/interpreter/mterp/arm/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="orr r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_or_int_lit16.S b/runtime/interpreter/mterp/arm/op_or_int_lit16.S
deleted file mode 100644
index 03bf4ed..0000000
--- a/runtime/interpreter/mterp/arm/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="orr r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_or_int_lit8.S b/runtime/interpreter/mterp/arm/op_or_int_lit8.S
deleted file mode 100644
index a29d73f..0000000
--- a/runtime/interpreter/mterp/arm/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(extract="", instr="orr r0, r0, r3, asr #8")
diff --git a/runtime/interpreter/mterp/arm/op_or_long.S b/runtime/interpreter/mterp/arm/op_or_long.S
deleted file mode 100644
index 3278700..0000000
--- a/runtime/interpreter/mterp/arm/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(preinstr="orr r0, r0, r2", instr="orr r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_or_long_2addr.S b/runtime/interpreter/mterp/arm/op_or_long_2addr.S
deleted file mode 100644
index 56ce5e6..0000000
--- a/runtime/interpreter/mterp/arm/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(preinstr="orr r0, r0, r2", instr="orr r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_packed_switch.S b/runtime/interpreter/mterp/arm/op_packed_switch.S
deleted file mode 100644
index 26af19d..0000000
--- a/runtime/interpreter/mterp/arm/op_packed_switch.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
- /*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBB */
- FETCH r0, 1 @ r0<- bbbb (lo)
- FETCH r1, 2 @ r1<- BBBB (hi)
- mov r3, rINST, lsr #8 @ r3<- AA
- orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb
- GET_VREG r1, r3 @ r1<- vAA
- add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2
- bl $func @ r0<- code-unit branch offset
- movs rINST, r0
- b MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/arm/op_rem_double.S b/runtime/interpreter/mterp/arm/op_rem_double.S
deleted file mode 100644
index 1e1e680..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_double.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_double():
-/* EABI doesn't define a double remainder function, but libm does */
-% binopWide(instr="bl fmod")
diff --git a/runtime/interpreter/mterp/arm/op_rem_double_2addr.S b/runtime/interpreter/mterp/arm/op_rem_double_2addr.S
deleted file mode 100644
index 8db1cde..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_double_2addr.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_double_2addr():
-/* EABI doesn't define a double remainder function, but libm does */
-% binopWide2addr(instr="bl fmod")
diff --git a/runtime/interpreter/mterp/arm/op_rem_float.S b/runtime/interpreter/mterp/arm/op_rem_float.S
deleted file mode 100644
index 5362e0a..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_float.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_float():
-/* EABI doesn't define a float remainder function, but libm does */
-% binop(instr="bl fmodf")
diff --git a/runtime/interpreter/mterp/arm/op_rem_float_2addr.S b/runtime/interpreter/mterp/arm/op_rem_float_2addr.S
deleted file mode 100644
index 90ff391..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_float_2addr.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_float_2addr():
-/* EABI doesn't define a float remainder function, but libm does */
-% binop2addr(instr="bl fmodf")
diff --git a/runtime/interpreter/mterp/arm/op_rem_int.S b/runtime/interpreter/mterp/arm/op_rem_int.S
deleted file mode 100644
index 068870e..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_int.S
+++ /dev/null
@@ -1,33 +0,0 @@
-%def op_rem_int():
- /*
- * 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/runtime/interpreter/mterp/arm/op_rem_int_2addr.S b/runtime/interpreter/mterp/arm/op_rem_int_2addr.S
deleted file mode 100644
index 22ade95..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_int_2addr.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_rem_int_2addr():
- /*
- * 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/runtime/interpreter/mterp/arm/op_rem_int_lit16.S b/runtime/interpreter/mterp/arm/op_rem_int_lit16.S
deleted file mode 100644
index 0605663..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_int_lit16.S
+++ /dev/null
@@ -1,31 +0,0 @@
-%def op_rem_int_lit16():
- /*
- * 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/runtime/interpreter/mterp/arm/op_rem_int_lit8.S b/runtime/interpreter/mterp/arm/op_rem_int_lit8.S
deleted file mode 100644
index 9b6867b..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_int_lit8.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_rem_int_lit8():
- /*
- * 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/runtime/interpreter/mterp/arm/op_rem_long.S b/runtime/interpreter/mterp/arm/op_rem_long.S
deleted file mode 100644
index a44827f..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_long.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_long():
-/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
-% binopWide(instr="bl __aeabi_ldivmod", result0="r2", result1="r3", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm/op_rem_long_2addr.S b/runtime/interpreter/mterp/arm/op_rem_long_2addr.S
deleted file mode 100644
index cf34964..0000000
--- a/runtime/interpreter/mterp/arm/op_rem_long_2addr.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_long_2addr():
-/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
-% binopWide2addr(instr="bl __aeabi_ldivmod", result0="r2", result1="r3", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm/op_return.S b/runtime/interpreter/mterp/arm/op_return.S
deleted file mode 100644
index fe35ec9..0000000
--- a/runtime/interpreter/mterp/arm/op_return.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_return():
- /*
- * Return a 32-bit value.
- *
- * for: return, return-object
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- mov r0, rSELF
- ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- blne MterpSuspendCheck @ (self)
- mov r2, rINST, lsr #8 @ r2<- AA
- GET_VREG r0, r2 @ r0<- vAA
- mov r1, #0
- b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_return_object.S b/runtime/interpreter/mterp/arm/op_return_object.S
deleted file mode 100644
index 2eeec0b..0000000
--- a/runtime/interpreter/mterp/arm/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return()
diff --git a/runtime/interpreter/mterp/arm/op_return_void.S b/runtime/interpreter/mterp/arm/op_return_void.S
deleted file mode 100644
index 2418c6a..0000000
--- a/runtime/interpreter/mterp/arm/op_return_void.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- mov r0, rSELF
- ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- blne MterpSuspendCheck @ (self)
- mov r0, #0
- mov r1, #0
- b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S b/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S
deleted file mode 100644
index fa4cc0a..0000000
--- a/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_return_void_no_barrier():
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- mov r0, rSELF
- ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- blne MterpSuspendCheck @ (self)
- mov r0, #0
- mov r1, #0
- b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_return_wide.S b/runtime/interpreter/mterp/arm/op_return_wide.S
deleted file mode 100644
index a2a3be4..0000000
--- a/runtime/interpreter/mterp/arm/op_return_wide.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_return_wide():
- /*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- mov r0, rSELF
- ands lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- blne MterpSuspendCheck @ (self)
- mov r2, rINST, lsr #8 @ r2<- AA
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[AA]
- ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1
- b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_rsub_int.S b/runtime/interpreter/mterp/arm/op_rsub_int.S
deleted file mode 100644
index 5d41f6d..0000000
--- a/runtime/interpreter/mterp/arm/op_rsub_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rsub_int():
-/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
-% binopLit16(instr="rsb r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_rsub_int_lit8.S b/runtime/interpreter/mterp/arm/op_rsub_int_lit8.S
deleted file mode 100644
index 5ce759d..0000000
--- a/runtime/interpreter/mterp/arm/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(extract="", instr="rsb r0, r0, r3, asr #8")
diff --git a/runtime/interpreter/mterp/arm/op_sget.S b/runtime/interpreter/mterp/arm/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/arm/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm/op_sget_boolean.S b/runtime/interpreter/mterp/arm/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/arm/op_sget_byte.S b/runtime/interpreter/mterp/arm/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/arm/op_sget_char.S b/runtime/interpreter/mterp/arm/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/arm/op_sget_object.S b/runtime/interpreter/mterp/arm/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/arm/op_sget_short.S b/runtime/interpreter/mterp/arm/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/arm/op_sget_wide.S b/runtime/interpreter/mterp/arm/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/arm/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/arm/op_shl_int.S b/runtime/interpreter/mterp/arm/op_shl_int.S
deleted file mode 100644
index 948a520..0000000
--- a/runtime/interpreter/mterp/arm/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, asl r1")
diff --git a/runtime/interpreter/mterp/arm/op_shl_int_2addr.S b/runtime/interpreter/mterp/arm/op_shl_int_2addr.S
deleted file mode 100644
index 89b16da..0000000
--- a/runtime/interpreter/mterp/arm/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, asl r1")
diff --git a/runtime/interpreter/mterp/arm/op_shl_int_lit8.S b/runtime/interpreter/mterp/arm/op_shl_int_lit8.S
deleted file mode 100644
index d6f81e7..0000000
--- a/runtime/interpreter/mterp/arm/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, asl r1")
diff --git a/runtime/interpreter/mterp/arm/op_shl_long.S b/runtime/interpreter/mterp/arm/op_shl_long.S
deleted file mode 100644
index d11fee2..0000000
--- a/runtime/interpreter/mterp/arm/op_shl_long.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_shl_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* shl-long vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r3, r0, #255 @ r3<- BB
- mov r0, r0, lsr #8 @ r0<- CC
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
- GET_VREG r2, r0 @ r2<- vCC
- ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- and r2, r2, #63 @ r2<- r2 & 0x3f
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- mov r1, r1, asl r2 @ r1<- r1 << r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mov r0, r0, asl r2 @ r0<- r0 << r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_shl_long_2addr.S b/runtime/interpreter/mterp/arm/op_shl_long_2addr.S
deleted file mode 100644
index e636d2e..0000000
--- a/runtime/interpreter/mterp/arm/op_shl_long_2addr.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_shl_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shl-long/2addr vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- GET_VREG r2, r3 @ r2<- vB
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
- and r2, r2, #63 @ r2<- r2 & 0x3f
- ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
- mov r1, r1, asl r2 @ r1<- r1 << r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
- mov r0, r0, asl r2 @ r0<- r0 << r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_shr_int.S b/runtime/interpreter/mterp/arm/op_shr_int.S
deleted file mode 100644
index 4d94d1f..0000000
--- a/runtime/interpreter/mterp/arm/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, asr r1")
diff --git a/runtime/interpreter/mterp/arm/op_shr_int_2addr.S b/runtime/interpreter/mterp/arm/op_shr_int_2addr.S
deleted file mode 100644
index 786b409..0000000
--- a/runtime/interpreter/mterp/arm/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, asr r1")
diff --git a/runtime/interpreter/mterp/arm/op_shr_int_lit8.S b/runtime/interpreter/mterp/arm/op_shr_int_lit8.S
deleted file mode 100644
index f5550b1..0000000
--- a/runtime/interpreter/mterp/arm/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, asr r1")
diff --git a/runtime/interpreter/mterp/arm/op_shr_long.S b/runtime/interpreter/mterp/arm/op_shr_long.S
deleted file mode 100644
index eec8d32..0000000
--- a/runtime/interpreter/mterp/arm/op_shr_long.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_shr_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* shr-long vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r3, r0, #255 @ r3<- BB
- mov r0, r0, lsr #8 @ r0<- CC
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
- GET_VREG r2, r0 @ r2<- vCC
- ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- and r2, r2, #63 @ r0<- r0 & 0x3f
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- mov r0, r0, lsr r2 @ r0<- r2 >> r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mov r1, r1, asr r2 @ r1<- r1 >> r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_shr_long_2addr.S b/runtime/interpreter/mterp/arm/op_shr_long_2addr.S
deleted file mode 100644
index ac40d36..0000000
--- a/runtime/interpreter/mterp/arm/op_shr_long_2addr.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_shr_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shr-long/2addr vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- GET_VREG r2, r3 @ r2<- vB
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
- and r2, r2, #63 @ r2<- r2 & 0x3f
- ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
- mov r0, r0, lsr r2 @ r0<- r2 >> r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
- mov r1, r1, asr r2 @ r1<- r1 >> r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_sparse_switch.S b/runtime/interpreter/mterp/arm/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/arm/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/arm/op_sput.S b/runtime/interpreter/mterp/arm/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/arm/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm/op_sput_boolean.S b/runtime/interpreter/mterp/arm/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/arm/op_sput_byte.S b/runtime/interpreter/mterp/arm/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/arm/op_sput_char.S b/runtime/interpreter/mterp/arm/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/arm/op_sput_object.S b/runtime/interpreter/mterp/arm/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/arm/op_sput_short.S b/runtime/interpreter/mterp/arm/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/arm/op_sput_wide.S b/runtime/interpreter/mterp/arm/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/arm/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/arm/op_sub_double.S b/runtime/interpreter/mterp/arm/op_sub_double.S
deleted file mode 100644
index 418f930..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% fbinopWide(instr="fsubd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_double_2addr.S b/runtime/interpreter/mterp/arm/op_sub_double_2addr.S
deleted file mode 100644
index 2bd0370..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% fbinopWide2addr(instr="fsubd d2, d0, d1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_float.S b/runtime/interpreter/mterp/arm/op_sub_float.S
deleted file mode 100644
index c0b09ff..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% fbinop(instr="fsubs s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_float_2addr.S b/runtime/interpreter/mterp/arm/op_sub_float_2addr.S
deleted file mode 100644
index c5ffec7..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% fbinop2addr(instr="fsubs s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_int.S b/runtime/interpreter/mterp/arm/op_sub_int.S
deleted file mode 100644
index 0932989..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="sub r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_int_2addr.S b/runtime/interpreter/mterp/arm/op_sub_int_2addr.S
deleted file mode 100644
index c6fa2e4..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="sub r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_sub_long.S b/runtime/interpreter/mterp/arm/op_sub_long.S
deleted file mode 100644
index 85d9a9f..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long():
-% binopWide(preinstr="subs r0, r0, r2", instr="sbc r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_sub_long_2addr.S b/runtime/interpreter/mterp/arm/op_sub_long_2addr.S
deleted file mode 100644
index 8a782aa..0000000
--- a/runtime/interpreter/mterp/arm/op_sub_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long_2addr():
-% binopWide2addr(preinstr="subs r0, r0, r2", instr="sbc r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_throw.S b/runtime/interpreter/mterp/arm/op_throw.S
deleted file mode 100644
index 0d3fe37..0000000
--- a/runtime/interpreter/mterp/arm/op_throw.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_throw():
- /*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC
- mov r2, rINST, lsr #8 @ r2<- AA
- GET_VREG r1, r2 @ r1<- vAA (exception object)
- cmp r1, #0 @ null object?
- beq common_errNullObject @ yes, throw an NPE instead
- str r1, [rSELF, #THREAD_EXCEPTION_OFFSET] @ thread->exception<- obj
- b MterpException
diff --git a/runtime/interpreter/mterp/arm/op_unused_3e.S b/runtime/interpreter/mterp/arm/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_3f.S b/runtime/interpreter/mterp/arm/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_40.S b/runtime/interpreter/mterp/arm/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_41.S b/runtime/interpreter/mterp/arm/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_42.S b/runtime/interpreter/mterp/arm/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_43.S b/runtime/interpreter/mterp/arm/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_73.S b/runtime/interpreter/mterp/arm/op_unused_73.S
deleted file mode 100644
index e3267a3..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_73.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_73():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_79.S b/runtime/interpreter/mterp/arm/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_7a.S b/runtime/interpreter/mterp/arm/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f3.S b/runtime/interpreter/mterp/arm/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f4.S b/runtime/interpreter/mterp/arm/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f5.S b/runtime/interpreter/mterp/arm/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f6.S b/runtime/interpreter/mterp/arm/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f7.S b/runtime/interpreter/mterp/arm/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f8.S b/runtime/interpreter/mterp/arm/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_f9.S b/runtime/interpreter/mterp/arm/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_fc.S b/runtime/interpreter/mterp/arm/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_unused_fd.S b/runtime/interpreter/mterp/arm/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/arm/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/arm/op_ushr_int.S b/runtime/interpreter/mterp/arm/op_ushr_int.S
deleted file mode 100644
index 7716beb..0000000
--- a/runtime/interpreter/mterp/arm/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop(preinstr="and r1, r1, #31", instr="mov r0, r0, lsr r1")
diff --git a/runtime/interpreter/mterp/arm/op_ushr_int_2addr.S b/runtime/interpreter/mterp/arm/op_ushr_int_2addr.S
deleted file mode 100644
index 8e435a7..0000000
--- a/runtime/interpreter/mterp/arm/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% binop2addr(preinstr="and r1, r1, #31", instr="mov r0, r0, lsr r1")
diff --git a/runtime/interpreter/mterp/arm/op_ushr_int_lit8.S b/runtime/interpreter/mterp/arm/op_ushr_int_lit8.S
deleted file mode 100644
index 40783de..0000000
--- a/runtime/interpreter/mterp/arm/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(extract="ubfx r1, r3, #8, #5", instr="mov r0, r0, lsr r1")
diff --git a/runtime/interpreter/mterp/arm/op_ushr_long.S b/runtime/interpreter/mterp/arm/op_ushr_long.S
deleted file mode 100644
index 2ab31ff..0000000
--- a/runtime/interpreter/mterp/arm/op_ushr_long.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_ushr_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* ushr-long vAA, vBB, vCC */
- FETCH r0, 1 @ r0<- CCBB
- mov r9, rINST, lsr #8 @ r9<- AA
- and r3, r0, #255 @ r3<- BB
- mov r0, r0, lsr #8 @ r0<- CC
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BB]
- GET_VREG r2, r0 @ r2<- vCC
- ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- and r2, r2, #63 @ r0<- r0 & 0x3f
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
- mov r0, r0, lsr r2 @ r0<- r2 >> r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- mov r1, r1, lsr r2 @ r1<- r1 >>> r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_ushr_long_2addr.S b/runtime/interpreter/mterp/arm/op_ushr_long_2addr.S
deleted file mode 100644
index e86161b..0000000
--- a/runtime/interpreter/mterp/arm/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_ushr_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* ushr-long/2addr vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- GET_VREG r2, r3 @ r2<- vB
- CLEAR_SHADOW_PAIR r9, lr, ip @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[A]
- and r2, r2, #63 @ r2<- r2 & 0x3f
- ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1
- mov r0, r0, lsr r2 @ r0<- r2 >> r2
- rsb r3, r2, #32 @ r3<- 32 - r2
- orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
- subs ip, r2, #32 @ ip<- r2 - 32
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
- mov r1, r1, lsr r2 @ r1<- r1 >>> r2
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_xor_int.S b/runtime/interpreter/mterp/arm/op_xor_int.S
deleted file mode 100644
index 89a6450..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="eor r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_xor_int_2addr.S b/runtime/interpreter/mterp/arm/op_xor_int_2addr.S
deleted file mode 100644
index af7e85e..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="eor r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_xor_int_lit16.S b/runtime/interpreter/mterp/arm/op_xor_int_lit16.S
deleted file mode 100644
index a970e01..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="eor r0, r0, r1")
diff --git a/runtime/interpreter/mterp/arm/op_xor_int_lit8.S b/runtime/interpreter/mterp/arm/op_xor_int_lit8.S
deleted file mode 100644
index 2241f31..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(extract="", instr="eor r0, r0, r3, asr #8")
diff --git a/runtime/interpreter/mterp/arm/op_xor_long.S b/runtime/interpreter/mterp/arm/op_xor_long.S
deleted file mode 100644
index 3700a4a..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(preinstr="eor r0, r0, r2", instr="eor r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/op_xor_long_2addr.S b/runtime/interpreter/mterp/arm/op_xor_long_2addr.S
deleted file mode 100644
index 6558a4e..0000000
--- a/runtime/interpreter/mterp/arm/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(preinstr="eor r0, r0, r2", instr="eor r1, r1, r3")
diff --git a/runtime/interpreter/mterp/arm/other.S b/runtime/interpreter/mterp/arm/other.S
new file mode 100644
index 0000000..340038c
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/other.S
@@ -0,0 +1,379 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC
+ FETCH r0, 1 @ r0<- BBBB
+ mov r1, rINST, lsr #8 @ r1<- AA
+ add r2, rFP, #OFF_FP_SHADOWFRAME
+ mov r3, rSELF
+ bl $helper @ (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 2 @ load rINST
+ cmp r0, #0 @ fail?
+ bne MterpPossibleException @ let reference interpreter deal with it.
+ ADVANCE 2 @ advance rPC
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
+%def op_const():
+ /* const vAA, #+BBBBbbbb */
+ mov r3, rINST, lsr #8 @ r3<- AA
+ FETCH r0, 1 @ r0<- bbbb (low)
+ FETCH r1, 2 @ r1<- BBBB (high)
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ SET_VREG r0, r3 @ vAA<- r0
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_16():
+ /* const/16 vAA, #+BBBB */
+ FETCH_S r0, 1 @ r0<- ssssBBBB (sign-extended)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ SET_VREG r0, r3 @ vAA<- r0
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_4():
+ /* const/4 vA, #+B */
+ sbfx r1, rINST, #12, #4 @ r1<- sssssssB (sign-extended)
+ ubfx r0, rINST, #8, #4 @ r0<- A
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ ip<- opcode from rINST
+ SET_VREG r1, r0 @ fp[A]<- r1
+ GOTO_OPCODE ip @ execute next instruction
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, #+BBBB0000 */
+ FETCH r0, 1 @ r0<- 0000BBBB (zero-extended)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ mov r0, r0, lsl #16 @ r0<- BBBB0000
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ SET_VREG r0, r3 @ vAA<- r0
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, String@BBBBBBBB */
+ EXPORT_PC
+ FETCH r0, 1 @ r0<- bbbb (low)
+ FETCH r2, 2 @ r2<- BBBB (high)
+ mov r1, rINST, lsr #8 @ r1<- AA
+ orr r0, r0, r2, lsl #16 @ r1<- BBBBbbbb
+ add r2, rFP, #OFF_FP_SHADOWFRAME
+ mov r3, rSELF
+ bl MterpConstString @ (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 3 @ advance rPC
+ cmp r0, #0 @ fail?
+ bne MterpPossibleException @ let reference interpreter deal with it.
+ ADVANCE 3 @ advance rPC
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_wide():
+ /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
+ FETCH r0, 1 @ r0<- bbbb (low)
+ FETCH r1, 2 @ r1<- BBBB (low middle)
+ FETCH r2, 3 @ r2<- hhhh (high middle)
+ orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word)
+ FETCH r3, 4 @ r3<- HHHH (high)
+ mov r9, rINST, lsr #8 @ r9<- AA
+ orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word)
+ CLEAR_SHADOW_PAIR r9, r2, r3 @ Zero out the shadow regs
+ FETCH_ADVANCE_INST 5 @ advance rPC, load rINST
+ VREG_INDEX_TO_ADDR r9, r9 @ r9<- &fp[AA]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r9, {r0-r1} @ vAA<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, #+BBBB */
+ FETCH_S r0, 1 @ r0<- ssssBBBB (sign-extended)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ mov r1, r0, asr #31 @ r1<- ssssssss
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ CLEAR_SHADOW_PAIR r3, r2, lr @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r3, {r0-r1} @ vAA<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, #+BBBBbbbb */
+ FETCH r0, 1 @ r0<- 0000bbbb (low)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ FETCH_S r2, 2 @ r2<- ssssBBBB (high)
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb
+ CLEAR_SHADOW_PAIR r3, r2, lr @ Zero out the shadow regs
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
+ mov r1, r0, asr #31 @ r1<- ssssssss
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r3, {r0-r1} @ vAA<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, #+BBBB000000000000 */
+ FETCH r1, 1 @ r1<- 0000BBBB (zero-extended)
+ mov r3, rINST, lsr #8 @ r3<- AA
+ mov r0, #0 @ r0<- 00000000
+ mov r1, r1, lsl #16 @ r1<- BBBB0000
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ CLEAR_SHADOW_PAIR r3, r0, r2 @ Zero shadow regs
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[AA]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r3, {r0-r1} @ vAA<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_monitor_enter():
+ /*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ EXPORT_PC
+ mov r2, rINST, lsr #8 @ r2<- AA
+ GET_VREG r0, r2 @ r0<- vAA (object)
+ mov r1, rSELF @ r1<- self
+ bl artLockObjectFromCode
+ cmp r0, #0
+ bne MterpException
+ FETCH_ADVANCE_INST 1
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_monitor_exit():
+ /*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ EXPORT_PC
+ mov r2, rINST, lsr #8 @ r2<- AA
+ GET_VREG r0, r2 @ r0<- vAA (object)
+ mov r1, rSELF @ r0<- self
+ bl artUnlockObjectFromCode @ r0<- success for unlock(self, obj)
+ cmp r0, #0 @ failed?
+ bne MterpException
+ FETCH_ADVANCE_INST 1 @ before throw: advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ mov r1, rINST, lsr #12 @ r1<- B from 15:12
+ ubfx r0, rINST, #8, #4 @ r0<- A from 11:8
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ GET_VREG r2, r1 @ r2<- fp[B]
+ GET_INST_OPCODE ip @ ip<- opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT r2, r0 @ fp[A]<- r2
+ .else
+ SET_VREG r2, r0 @ fp[A]<- r2
+ .endif
+ GOTO_OPCODE ip @ execute next instruction
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ FETCH r1, 2 @ r1<- BBBB
+ FETCH r0, 1 @ r0<- AAAA
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ GET_VREG r2, r1 @ r2<- fp[BBBB]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT r2, r0 @ fp[AAAA]<- r2
+ .else
+ SET_VREG r2, r0 @ fp[AAAA]<- r2
+ .endif
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_exception():
+ /* move-exception vAA */
+ mov r2, rINST, lsr #8 @ r2<- AA
+ ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
+ mov r1, #0 @ r1<- 0
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ SET_VREG_OBJECT r3, r2 @ fp[AA]<- exception obj
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ str r1, [rSELF, #THREAD_EXCEPTION_OFFSET] @ clear exception
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ FETCH r1, 1 @ r1<- BBBB
+ mov r0, rINST, lsr #8 @ r0<- AA
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_VREG r2, r1 @ r2<- fp[BBBB]
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT r2, r0 @ fp[AA]<- r2
+ .else
+ SET_VREG r2, r0 @ fp[AA]<- r2
+ .endif
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ ldr r0, [rFP, #OFF_FP_RESULT_REGISTER] @ get pointer to result JType.
+ ldr r0, [r0] @ r0 <- result.i.
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT r0, r2, r1 @ fp[AA]<- r0
+ .else
+ SET_VREG r0, r2 @ fp[AA]<- r0
+ .endif
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* move-result-wide vAA */
+ mov rINST, rINST, lsr #8 @ rINST<- AA
+ ldr r3, [rFP, #OFF_FP_RESULT_REGISTER]
+ VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[AA]
+ ldmia r3, {r0-r1} @ r0/r1<- retval.j
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ stmia r2, {r0-r1} @ fp[AA]<- r0/r1
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ mov r3, rINST, lsr #12 @ r3<- B
+ ubfx rINST, rINST, #8, #4 @ rINST<- A
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
+ VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[A]
+ ldmia r3, {r0-r1} @ r0/r1<- fp[B]
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
+ FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r2, {r0-r1} @ fp[A]<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ FETCH r3, 2 @ r3<- BBBB
+ FETCH r2, 1 @ r2<- AAAA
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BBBB]
+ VREG_INDEX_TO_ADDR lr, r2 @ r2<- &fp[AAAA]
+ ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB]
+ FETCH_ADVANCE_INST 3 @ advance rPC, load rINST
+ CLEAR_SHADOW_PAIR r2, r3, ip @ Zero out the shadow regs
+ stmia lr, {r0-r1} @ fp[AAAA]<- r0/r1
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ FETCH r3, 1 @ r3<- BBBB
+ mov rINST, rINST, lsr #8 @ rINST<- AA
+ VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[BBBB]
+ VREG_INDEX_TO_ADDR r2, rINST @ r2<- &fp[AA]
+ ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB]
+ CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero out the shadow regs
+ FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ stmia r2, {r0-r1} @ fp[AA]<- r0/r1
+ GOTO_OPCODE ip @ jump to next instruction
+
+%def op_nop():
+ FETCH_ADVANCE_INST 1 @ advance to next instr, load rINST
+ GET_INST_OPCODE ip @ ip<- opcode from rINST
+ GOTO_OPCODE ip @ execute it
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_73():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/arm/unop.S b/runtime/interpreter/mterp/arm/unop.S
deleted file mode 100644
index a0b0954..0000000
--- a/runtime/interpreter/mterp/arm/unop.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def unop(preinstr="", instr=""):
- /*
- * Generic 32-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op r0".
- * This could be an ARM instruction or a function call.
- *
- * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
- * int-to-byte, int-to-char, int-to-short
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- GET_VREG r0, r3 @ r0<- vB
- $preinstr @ optional op; may set condition codes
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $instr @ r0<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG r0, r9 @ vAA<- r0
- GOTO_OPCODE ip @ jump to next instruction
- /* 8-9 instructions */
diff --git a/runtime/interpreter/mterp/arm/unopNarrower.S b/runtime/interpreter/mterp/arm/unopNarrower.S
deleted file mode 100644
index 4d1bdb9..0000000
--- a/runtime/interpreter/mterp/arm/unopNarrower.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def unopNarrower(preinstr="", instr=""):
- /*
- * Generic 64bit-to-32bit unary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = op r0/r1", where
- * "result" is a 32-bit quantity in r0.
- *
- * For: long-to-float, double-to-int, double-to-float
- *
- * (This would work for long-to-int, but that instruction is actually
- * an exact match for op_move.)
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx r9, rINST, #8, #4 @ r9<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
- ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $preinstr @ optional op; may set condition codes
- $instr @ r0<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- SET_VREG r0, r9 @ vA<- r0
- GOTO_OPCODE ip @ jump to next instruction
- /* 9-10 instructions */
diff --git a/runtime/interpreter/mterp/arm/unopWide.S b/runtime/interpreter/mterp/arm/unopWide.S
deleted file mode 100644
index 658c207..0000000
--- a/runtime/interpreter/mterp/arm/unopWide.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def unopWide(preinstr="", instr=""):
- /*
- * Generic 64-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op r0/r1".
- * This could be an ARM instruction or a function call.
- *
- * For: neg-long, not-long, neg-double, long-to-double, double-to-long
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx rINST, rINST, #8, #4 @ rINST<- A
- VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B]
- VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
- ldmia r3, {r0-r1} @ r0/r1<- vAA
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $preinstr @ optional op; may set condition codes
- $instr @ r0/r1<- op, r2-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vAA<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
- /* 10-11 instructions */
diff --git a/runtime/interpreter/mterp/arm/unopWider.S b/runtime/interpreter/mterp/arm/unopWider.S
deleted file mode 100644
index 8b32927..0000000
--- a/runtime/interpreter/mterp/arm/unopWider.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def unopWider(preinstr="", instr=""):
- /*
- * Generic 32bit-to-64bit unary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = op r0", where
- * "result" is a 64-bit quantity in r0/r1.
- *
- * For: int-to-long, int-to-double, float-to-long, float-to-double
- */
- /* unop vA, vB */
- mov r3, rINST, lsr #12 @ r3<- B
- ubfx rINST, rINST, #8, #4 @ rINST<- A
- GET_VREG r0, r3 @ r0<- vB
- VREG_INDEX_TO_ADDR r9, rINST @ r9<- &fp[A]
- $preinstr @ optional op; may set condition codes
- CLEAR_SHADOW_PAIR rINST, ip, lr @ Zero shadow regs
- FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
- $instr @ r0<- op, r0-r3 changed
- GET_INST_OPCODE ip @ extract opcode from rINST
- stmia r9, {r0-r1} @ vA/vA+1<- r0/r1
- GOTO_OPCODE ip @ jump to next instruction
- /* 9-10 instructions */
diff --git a/runtime/interpreter/mterp/arm/unused.S b/runtime/interpreter/mterp/arm/unused.S
deleted file mode 100644
index 3f37e74..0000000
--- a/runtime/interpreter/mterp/arm/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/arm/zcmp.S b/runtime/interpreter/mterp/arm/zcmp.S
deleted file mode 100644
index 6905a32..0000000
--- a/runtime/interpreter/mterp/arm/zcmp.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def zcmp(condition=""):
- /*
- * Generic one-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- mov r0, rINST, lsr #8 @ r0<- AA
- GET_VREG r0, r0 @ r0<- vAA
- FETCH_S rINST, 1 @ rINST<- branch offset, in code units
- cmp r0, #0 @ compare (vA, 0)
- b${condition} MterpCommonTakenBranchNoFlags
- cmp rPROFILE, #JIT_CHECK_OSR @ possible OSR re-entry?
- beq .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/alt_stub.S b/runtime/interpreter/mterp/arm64/alt_stub.S
deleted file mode 100644
index 3343463..0000000
--- a/runtime/interpreter/mterp/arm64/alt_stub.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Note that the call to MterpCheckBefore is done as a tail call.
- */
- .extern MterpCheckBefore
- ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh IBASE.
- adr lr, artMterpAsmInstructionStart + (${opnum} * 128) // Addr of primary handler.
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xPC
- b MterpCheckBefore // (self, shadow_frame, dex_pc_ptr) Note: tail call.
diff --git a/runtime/interpreter/mterp/arm64/arithmetic.S b/runtime/interpreter/mterp/arm64/arithmetic.S
new file mode 100644
index 0000000..cf9dd86
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/arithmetic.S
@@ -0,0 +1,507 @@
+%def binop(preinstr="", result="w0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = w0 op w1".
+ * This could be an ARM instruction or a function call. (If the result
+ * comes back in a register other than w0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). 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.
+ *
+ * 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 w0, 1 // w0<- CCBB
+ lsr w9, wINST, #8 // w9<- AA
+ lsr w3, w0, #8 // w3<- CC
+ and w2, w0, #255 // w2<- BB
+ GET_VREG w1, w3 // w1<- vCC
+ GET_VREG w0, w2 // w0<- vBB
+ .if $chkzero
+ cbz w1, common_errDivideByZero // is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $preinstr // optional op; may set condition codes
+ $instr // $result<- op, w0-w3 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG $result, w9 // vAA<- $result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 11-14 instructions */
+
+%def binop2addr(preinstr="", result="w0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = w0 op w1".
+ * This could be an ARM instruction or a function call. (If the result
+ * comes back in a register other than w0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). Useful for integer division and modulus.
+ *
+ * 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 */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w9, wINST, #8, #4 // w9<- A
+ GET_VREG w1, w3 // w1<- vB
+ GET_VREG w0, w9 // w0<- vA
+ .if $chkzero
+ cbz w1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ $preinstr // optional op; may set condition codes
+ $instr // $result<- op, w0-w3 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG $result, w9 // vAA<- $result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-13 instructions */
+
+%def binopLit16(preinstr="", result="w0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit16" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = w0 op w1".
+ * This could be an ARM instruction or a function call. (If the result
+ * comes back in a register other than w0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). Useful for integer division and modulus.
+ *
+ * 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 w1, 1 // w1<- ssssCCCC (sign-extended)
+ lsr w2, wINST, #12 // w2<- B
+ ubfx w9, wINST, #8, #4 // w9<- A
+ GET_VREG w0, w2 // w0<- vB
+ .if $chkzero
+ cbz w1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $preinstr
+ $instr // $result<- op, w0-w3 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG $result, w9 // vAA<- $result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-13 instructions */
+
+%def binopLit8(extract="asr w1, w3, #8", preinstr="", result="w0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit8" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = w0 op w1".
+ * This could be an ARM instruction or a function call. (If the result
+ * comes back in a register other than w0, you can override "result".)
+ *
+ * You can override "extract" if the extraction of the literal value
+ * from w3 to w1 is not the default "asr w1, w3, #8". The extraction
+ * can be omitted completely if the shift is embedded in "instr".
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). Useful for integer division and modulus.
+ *
+ * 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 w3, 1 // w3<- ssssCCBB (sign-extended for CC)
+ lsr w9, wINST, #8 // w9<- AA
+ and w2, w3, #255 // w2<- BB
+ GET_VREG w0, w2 // w0<- vBB
+ $extract // optional; typically w1<- ssssssCC (sign extended)
+ .if $chkzero
+ cbz w1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $preinstr // optional op; may set condition codes
+ $instr // $result<- op, w0-w3 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG $result, w9 // vAA<- $result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-12 instructions */
+
+%def binopWide(preinstr="", instr="add x0, x1, x2", result="x0", r1="x1", r2="x2", chkzero="0"):
+ /*
+ * Generic 64-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = x1 op x2".
+ * This could be an ARM instruction or a function call. (If the result
+ * comes back in a register other than x0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). Useful for integer division and modulus.
+ *
+ * For: add-long, sub-long, mul-long, div-long, rem-long, and-long, or-long,
+ * xor-long, add-double, sub-double, mul-double, div-double, rem-double
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w4, wINST, #8 // w4<- AA
+ lsr w2, w0, #8 // w2<- CC
+ and w1, w0, #255 // w1<- BB
+ GET_VREG_WIDE $r2, w2 // w2<- vCC
+ GET_VREG_WIDE $r1, w1 // w1<- vBB
+ .if $chkzero
+ cbz $r2, common_errDivideByZero // is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $preinstr
+ $instr // $result<- op, w0-w4 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG_WIDE $result, w4 // vAA<- $result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 11-14 instructions */
+
+%def binopWide2addr(preinstr="", instr="add x0, x0, x1", r0="x0", r1="x1", chkzero="0"):
+ /*
+ * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "x0 = x0 op x1".
+ * This must not be a function call, as we keep w2 live across it.
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (w1). Useful for integer division and modulus.
+ *
+ * For: add-long/2addr, sub-long/2addr, mul-long/2addr, div-long/2addr,
+ * and-long/2addr, or-long/2addr, xor-long/2addr,
+ * shl-long/2addr, shr-long/2addr, ushr-long/2addr, add-double/2addr,
+ * sub-double/2addr, mul-double/2addr, div-double/2addr, rem-double/2addr
+ */
+ /* binop/2addr vA, vB */
+ lsr w1, wINST, #12 // w1<- B
+ ubfx w2, wINST, #8, #4 // w2<- A
+ GET_VREG_WIDE $r1, w1 // x1<- vB
+ GET_VREG_WIDE $r0, w2 // x0<- vA
+ .if $chkzero
+ cbz $r1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ $preinstr
+ $instr // result<- op
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG_WIDE $r0, w2 // vAA<- result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-13 instructions */
+
+%def shiftWide(opcode="shl"):
+ /*
+ * 64-bit shift operation.
+ *
+ * For: shl-long, shr-long, ushr-long
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w3, wINST, #8 // w3<- AA
+ lsr w2, w0, #8 // w2<- CC
+ GET_VREG w2, w2 // w2<- vCC (shift count)
+ and w1, w0, #255 // w1<- BB
+ GET_VREG_WIDE x1, w1 // x1<- vBB
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $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
+ /* 11-14 instructions */
+
+%def shiftWide2addr(opcode="lsl"):
+ /*
+ * Generic 64-bit shift operation.
+ */
+ /* binop/2addr vA, vB */
+ lsr w1, wINST, #12 // w1<- B
+ ubfx w2, wINST, #8, #4 // w2<- A
+ GET_VREG w1, w1 // x1<- vB
+ GET_VREG_WIDE x0, w2 // x0<- vA
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ $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
+ /* 10-13 instructions */
+
+%def unop(instr=""):
+ /*
+ * Generic 32-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op w0".
+ * This could be an ARM instruction or a function call.
+ *
+ * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
+ * int-to-byte, int-to-char, int-to-short
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ GET_VREG w0, w3 // w0<- vB
+ ubfx w9, wINST, #8, #4 // w9<- A
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ $instr // w0<- op, w0-w3 changed
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG w0, w9 // vAA<- w0
+ GOTO_OPCODE ip // jump to next instruction
+ /* 8-9 instructions */
+
+%def unopWide(instr="sub x0, xzr, x0"):
+ /*
+ * Generic 64-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op x0".
+ *
+ * For: neg-long, not-long
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG_WIDE x0, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ $instr
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE x0, w4
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-11 instructions */
+
+%def op_add_int():
+% binop(instr="add w0, w0, w1")
+
+%def op_add_int_2addr():
+% binop2addr(instr="add w0, w0, w1")
+
+%def op_add_int_lit16():
+% binopLit16(instr="add w0, w0, w1")
+
+%def op_add_int_lit8():
+% binopLit8(extract="", instr="add w0, w0, w3, asr #8")
+
+%def op_add_long():
+% binopWide(instr="add x0, x1, x2")
+
+%def op_add_long_2addr():
+% binopWide2addr(instr="add x0, x0, x1")
+
+%def op_and_int():
+% binop(instr="and w0, w0, w1")
+
+%def op_and_int_2addr():
+% binop2addr(instr="and w0, w0, w1")
+
+%def op_and_int_lit16():
+% binopLit16(instr="and w0, w0, w1")
+
+%def op_and_int_lit8():
+% binopLit8(extract="", instr="and w0, w0, w3, asr #8")
+
+%def op_and_long():
+% binopWide(instr="and x0, x1, x2")
+
+%def op_and_long_2addr():
+% binopWide2addr(instr="and x0, x0, x1")
+
+%def op_cmp_long():
+ FETCH w0, 1 // w0<- CCBB
+ lsr w4, wINST, #8 // w4<- AA
+ and w2, w0, #255 // w2<- BB
+ lsr w3, w0, #8 // w3<- CC
+ GET_VREG_WIDE x1, w2
+ GET_VREG_WIDE x2, w3
+ cmp x1, x2
+ cset w0, ne
+ cneg w0, w0, lt
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ SET_VREG w0, w4
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_div_int():
+% binop(instr="sdiv w0, w0, w1", chkzero="1")
+
+%def op_div_int_2addr():
+% binop2addr(instr="sdiv w0, w0, w1", chkzero="1")
+
+%def op_div_int_lit16():
+% binopLit16(instr="sdiv w0, w0, w1", chkzero="1")
+
+%def op_div_int_lit8():
+% binopLit8(instr="sdiv w0, w0, w1", chkzero="1")
+
+%def op_div_long():
+% binopWide(instr="sdiv x0, x1, x2", chkzero="1")
+
+%def op_div_long_2addr():
+% binopWide2addr(instr="sdiv x0, x0, x1", chkzero="1")
+
+%def op_int_to_byte():
+% unop(instr="sxtb w0, w0")
+
+%def op_int_to_char():
+% unop(instr="uxth w0, w0")
+
+%def op_int_to_long():
+ /* int-to-long vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG_S x0, w3 // x0<- sign_extend(fp[B])
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE x0, w4 // fp[A]<- x0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_int_to_short():
+% unop(instr="sxth w0, w0")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
+% binop(instr="mul w0, w1, w0")
+
+%def op_mul_int_2addr():
+/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
+% binop2addr(instr="mul w0, w1, w0")
+
+%def op_mul_int_lit16():
+/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
+% binopLit16(instr="mul w0, w1, w0")
+
+%def op_mul_int_lit8():
+/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
+% binopLit8(instr="mul w0, w1, w0")
+
+%def op_mul_long():
+% binopWide(instr="mul x0, x1, x2")
+
+%def op_mul_long_2addr():
+% binopWide2addr(instr="mul x0, x0, x1")
+
+%def op_neg_int():
+% unop(instr="sub w0, wzr, w0")
+
+%def op_neg_long():
+% unopWide(instr="sub x0, xzr, x0")
+
+%def op_not_int():
+% unop(instr="mvn w0, w0")
+
+%def op_not_long():
+% unopWide(instr="mvn x0, x0")
+
+%def op_or_int():
+% binop(instr="orr w0, w0, w1")
+
+%def op_or_int_2addr():
+% binop2addr(instr="orr w0, w0, w1")
+
+%def op_or_int_lit16():
+% binopLit16(instr="orr w0, w0, w1")
+
+%def op_or_int_lit8():
+% binopLit8(extract="", instr="orr w0, w0, w3, asr #8")
+
+%def op_or_long():
+% binopWide(instr="orr x0, x1, x2")
+
+%def op_or_long_2addr():
+% binopWide2addr(instr="orr x0, x0, x1")
+
+%def op_rem_int():
+% binop(preinstr="sdiv w2, w0, w1", instr="msub w0, w2, w1, w0", chkzero="1")
+
+%def op_rem_int_2addr():
+% binop2addr(preinstr="sdiv w2, w0, w1", instr="msub w0, w2, w1, w0", chkzero="1")
+
+%def op_rem_int_lit16():
+% binopLit16(preinstr="sdiv w3, w0, w1", instr="msub w0, w3, w1, w0", chkzero="1")
+
+%def op_rem_int_lit8():
+% binopLit8(preinstr="sdiv w3, w0, w1", instr="msub w0, w3, w1, w0", chkzero="1")
+
+%def op_rem_long():
+% binopWide(preinstr="sdiv x3, x1, x2", instr="msub x0, x3, x2, x1", chkzero="1")
+
+%def op_rem_long_2addr():
+% binopWide2addr(preinstr="sdiv x3, x0, x1", instr="msub x0, x3, x1, x0", chkzero="1")
+
+%def op_rsub_int():
+/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
+% binopLit16(instr="sub w0, w1, w0")
+
+%def op_rsub_int_lit8():
+% binopLit8(instr="sub w0, w1, w0")
+
+%def op_shl_int():
+% binop(instr="lsl w0, w0, w1")
+
+%def op_shl_int_2addr():
+% binop2addr(instr="lsl w0, w0, w1")
+
+%def op_shl_int_lit8():
+% binopLit8(extract="ubfx w1, w3, #8, #5", instr="lsl w0, w0, w1")
+
+%def op_shl_long():
+% shiftWide(opcode="lsl")
+
+%def op_shl_long_2addr():
+% shiftWide2addr(opcode="lsl")
+
+%def op_shr_int():
+% binop(instr="asr w0, w0, w1")
+
+%def op_shr_int_2addr():
+% binop2addr(instr="asr w0, w0, w1")
+
+%def op_shr_int_lit8():
+% binopLit8(extract="ubfx w1, w3, #8, #5", instr="asr w0, w0, w1")
+
+%def op_shr_long():
+% shiftWide(opcode="asr")
+
+%def op_shr_long_2addr():
+% shiftWide2addr(opcode="asr")
+
+%def op_sub_int():
+% binop(instr="sub w0, w0, w1")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="sub w0, w0, w1")
+
+%def op_sub_long():
+% binopWide(instr="sub x0, x1, x2")
+
+%def op_sub_long_2addr():
+% binopWide2addr(instr="sub x0, x0, x1")
+
+%def op_ushr_int():
+% binop(instr="lsr w0, w0, w1")
+
+%def op_ushr_int_2addr():
+% binop2addr(instr="lsr w0, w0, w1")
+
+%def op_ushr_int_lit8():
+% binopLit8(extract="ubfx w1, w3, #8, #5", instr="lsr w0, w0, w1")
+
+%def op_ushr_long():
+% shiftWide(opcode="lsr")
+
+%def op_ushr_long_2addr():
+% shiftWide2addr(opcode="lsr")
+
+%def op_xor_int():
+% binop(instr="eor w0, w0, w1")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="eor w0, w0, w1")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="eor w0, w0, w1")
+
+%def op_xor_int_lit8():
+% binopLit8(extract="", instr="eor w0, w0, w3, asr #8")
+
+%def op_xor_long():
+% binopWide(instr="eor x0, x1, x2")
+
+%def op_xor_long_2addr():
+% binopWide2addr(instr="eor x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/array.S b/runtime/interpreter/mterp/arm64/array.S
new file mode 100644
index 0000000..a023d22
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/array.S
@@ -0,0 +1,235 @@
+%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
+ * instructions. We use a pair of FETCH_Bs instead.
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short
+ *
+ * NOTE: assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B w2, 1, 0 // w2<- BB
+ lsr w9, wINST, #8 // w9<- AA
+ FETCH_B w3, 1, 1 // w3<- CC
+ GET_VREG w0, w2 // w0<- vBB (array object)
+ GET_VREG w1, w3 // w1<- vCC (requested index)
+ cbz x0, common_errNullObject // bail if null array object.
+ ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- arrayObj->length
+ 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
+ $load w2, [x0, #$data_offset] // w2<- vBB[vCC]
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG w2, w9 // vAA<- w2
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_aget_boolean():
+% op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+ /*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B w2, 1, 0 // w2<- BB
+ FETCH_B w3, 1, 1 // w3<- CC
+ EXPORT_PC
+ GET_VREG w0, w2 // w0<- vBB (array object)
+ GET_VREG w1, w3 // w1<- vCC (requested index)
+ bl artAGetObjectFromMterp // (array, index)
+ ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
+ lsr w2, wINST, #8 // w9<- AA
+ PREFETCH_INST 2
+ cbnz w1, MterpException
+ SET_VREG_OBJECT w0, w2
+ ADVANCE 2
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_aget_short():
+% op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+ /*
+ * Array get, 64 bits. vAA <- vBB[vCC].
+ *
+ */
+ /* aget-wide vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w4, wINST, #8 // w4<- AA
+ and w2, w0, #255 // w2<- BB
+ lsr w3, w0, #8 // w3<- CC
+ GET_VREG w0, w2 // w0<- vBB (array object)
+ 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
+ cmp w1, w3 // compare unsigned index, length
+ bcs common_errArrayIndex // index >= length, bail
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ ldr x2, [x0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] // x2<- vBB[vCC]
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE x2, w4
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
+ * instructions. We use a pair of FETCH_Bs instead.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short
+ *
+ * NOTE: this assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B w2, 1, 0 // w2<- BB
+ lsr w9, wINST, #8 // w9<- AA
+ FETCH_B w3, 1, 1 // w3<- CC
+ GET_VREG w0, w2 // w0<- vBB (array object)
+ 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
+ cmp w1, w3 // compare unsigned index, length
+ bcs common_errArrayIndex // index >= length, bail
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_VREG w2, w9 // w2<- vAA
+ GET_INST_OPCODE ip // extract opcode from rINST
+ $store w2, [x0, #$data_offset] // vBB[vCC]<- w2
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_aput_boolean():
+% op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+ /*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ */
+ /* op vAA, vBB, vCC */
+ EXPORT_PC
+ add x0, xFP, #OFF_FP_SHADOWFRAME
+ mov x1, xPC
+ mov w2, wINST
+ bl MterpAputObject
+ cbz w0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_aput_short():
+% op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+ /*
+ * Array put, 64 bits. vBB[vCC] <- vAA.
+ *
+ */
+ /* aput-wide vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w4, wINST, #8 // w4<- AA
+ and w2, w0, #255 // w2<- BB
+ lsr w3, w0, #8 // w3<- CC
+ GET_VREG w0, w2 // w0<- vBB (array object)
+ 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
+ cmp w1, w3 // compare unsigned index, length
+ bcs common_errArrayIndex // index >= length, bail
+ GET_VREG_WIDE x1, w4
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ str x1, [x0, #MIRROR_WIDE_ARRAY_DATA_OFFSET]
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_array_length():
+ /*
+ * Return the length of an array.
+ */
+ lsr w1, wINST, #12 // w1<- B
+ ubfx w2, wINST, #8, #4 // w2<- A
+ GET_VREG w0, w1 // w0<- vB (object ref)
+ cbz w0, common_errNullObject // yup, fail
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- array length
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG w3, w2 // vB<- length
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ EXPORT_PC
+ FETCH w0, 1 // x0<- 000000000000bbbb (lo)
+ FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
+ lsr w3, wINST, #8 // w3<- AA
+ orr x1, x0, x1, lsl #16 // x1<- ssssssssBBBBbbbb
+ GET_VREG w0, w3 // w0<- vAA (array object)
+ add x1, xPC, x1, lsl #1 // x1<- PC + ssssssssBBBBbbbb*2 (array data off.)
+ bl MterpFillArrayData // (obj, payload)
+ cbz w0, MterpPossibleException // exception?
+ FETCH_ADVANCE_INST 3 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+ /*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class//CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type//BBBB */
+ .extern $helper
+ EXPORT_PC
+ add x0, xFP, #OFF_FP_SHADOWFRAME
+ mov x1, xPC
+ mov x2, xSELF
+ bl $helper
+ cbz w0, MterpPossibleException
+ FETCH_ADVANCE_INST 3 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+ /*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class//CCCC */
+ EXPORT_PC
+ add x0, xFP, #OFF_FP_SHADOWFRAME
+ mov x1, xPC
+ mov w2, wINST
+ mov x3, xSELF
+ bl MterpNewArray
+ cbz w0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/bincmp.S b/runtime/interpreter/mterp/arm64/bincmp.S
deleted file mode 100644
index 80ffbc5..0000000
--- a/runtime/interpreter/mterp/arm64/bincmp.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def bincmp(condition=""):
- /*
- * Generic two-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- lsr w1, wINST, #12 // w1<- B
- ubfx w0, wINST, #8, #4 // w0<- A
- GET_VREG w3, w1 // w3<- vB
- GET_VREG w2, w0 // w2<- vA
- FETCH_S wINST, 1 // wINST<- branch offset, in code units
- cmp w2, w3 // compare (vA, vB)
- b.${condition} MterpCommonTakenBranchNoFlags
- cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
- b.eq .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/binop.S b/runtime/interpreter/mterp/arm64/binop.S
deleted file mode 100644
index be4db17..0000000
--- a/runtime/interpreter/mterp/arm64/binop.S
+++ /dev/null
@@ -1,33 +0,0 @@
-%def binop(preinstr="", result="w0", chkzero="0", instr=""):
- /*
- * Generic 32-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = w0 op w1".
- * This could be an ARM instruction or a function call. (If the result
- * comes back in a register other than w0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). 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.
- *
- * 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 w0, 1 // w0<- CCBB
- lsr w9, wINST, #8 // w9<- AA
- lsr w3, w0, #8 // w3<- CC
- and w2, w0, #255 // w2<- BB
- GET_VREG w1, w3 // w1<- vCC
- GET_VREG w0, w2 // w0<- vBB
- .if $chkzero
- cbz w1, common_errDivideByZero // is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $preinstr // optional op; may set condition codes
- $instr // $result<- op, w0-w3 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG $result, w9 // vAA<- $result
- GOTO_OPCODE ip // jump to next instruction
- /* 11-14 instructions */
diff --git a/runtime/interpreter/mterp/arm64/binop2addr.S b/runtime/interpreter/mterp/arm64/binop2addr.S
deleted file mode 100644
index 5b46b12..0000000
--- a/runtime/interpreter/mterp/arm64/binop2addr.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binop2addr(preinstr="", result="w0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = w0 op w1".
- * This could be an ARM instruction or a function call. (If the result
- * comes back in a register other than w0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). Useful for integer division and modulus.
- *
- * 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 */
- lsr w3, wINST, #12 // w3<- B
- ubfx w9, wINST, #8, #4 // w9<- A
- GET_VREG w1, w3 // w1<- vB
- GET_VREG w0, w9 // w0<- vA
- .if $chkzero
- cbz w1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- $preinstr // optional op; may set condition codes
- $instr // $result<- op, w0-w3 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG $result, w9 // vAA<- $result
- GOTO_OPCODE ip // jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm64/binopLit16.S b/runtime/interpreter/mterp/arm64/binopLit16.S
deleted file mode 100644
index b8af7d1..0000000
--- a/runtime/interpreter/mterp/arm64/binopLit16.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def binopLit16(preinstr="", result="w0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit16" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = w0 op w1".
- * This could be an ARM instruction or a function call. (If the result
- * comes back in a register other than w0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). Useful for integer division and modulus.
- *
- * 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 w1, 1 // w1<- ssssCCCC (sign-extended)
- lsr w2, wINST, #12 // w2<- B
- ubfx w9, wINST, #8, #4 // w9<- A
- GET_VREG w0, w2 // w0<- vB
- .if $chkzero
- cbz w1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $preinstr
- $instr // $result<- op, w0-w3 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG $result, w9 // vAA<- $result
- GOTO_OPCODE ip // jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm64/binopLit8.S b/runtime/interpreter/mterp/arm64/binopLit8.S
deleted file mode 100644
index e7161a7..0000000
--- a/runtime/interpreter/mterp/arm64/binopLit8.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def binopLit8(extract="asr w1, w3, #8", preinstr="", result="w0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit8" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = w0 op w1".
- * This could be an ARM instruction or a function call. (If the result
- * comes back in a register other than w0, you can override "result".)
- *
- * You can override "extract" if the extraction of the literal value
- * from w3 to w1 is not the default "asr w1, w3, #8". The extraction
- * can be omitted completely if the shift is embedded in "instr".
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). Useful for integer division and modulus.
- *
- * 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 w3, 1 // w3<- ssssCCBB (sign-extended for CC)
- lsr w9, wINST, #8 // w9<- AA
- and w2, w3, #255 // w2<- BB
- GET_VREG w0, w2 // w0<- vBB
- $extract // optional; typically w1<- ssssssCC (sign extended)
- .if $chkzero
- cbz w1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $preinstr // optional op; may set condition codes
- $instr // $result<- op, w0-w3 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG $result, w9 // vAA<- $result
- GOTO_OPCODE ip // jump to next instruction
- /* 10-12 instructions */
diff --git a/runtime/interpreter/mterp/arm64/binopWide.S b/runtime/interpreter/mterp/arm64/binopWide.S
deleted file mode 100644
index 829b530..0000000
--- a/runtime/interpreter/mterp/arm64/binopWide.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binopWide(preinstr="", instr="add x0, x1, x2", result="x0", r1="x1", r2="x2", chkzero="0"):
- /*
- * Generic 64-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = x1 op x2".
- * This could be an ARM instruction or a function call. (If the result
- * comes back in a register other than x0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). Useful for integer division and modulus.
- *
- * For: add-long, sub-long, mul-long, div-long, rem-long, and-long, or-long,
- * xor-long, add-double, sub-double, mul-double, div-double, rem-double
- */
- /* binop vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w4, wINST, #8 // w4<- AA
- lsr w2, w0, #8 // w2<- CC
- and w1, w0, #255 // w1<- BB
- GET_VREG_WIDE $r2, w2 // w2<- vCC
- GET_VREG_WIDE $r1, w1 // w1<- vBB
- .if $chkzero
- cbz $r2, common_errDivideByZero // is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $preinstr
- $instr // $result<- op, w0-w4 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG_WIDE $result, w4 // vAA<- $result
- GOTO_OPCODE ip // jump to next instruction
- /* 11-14 instructions */
diff --git a/runtime/interpreter/mterp/arm64/binopWide2addr.S b/runtime/interpreter/mterp/arm64/binopWide2addr.S
deleted file mode 100644
index dbd6b3b..0000000
--- a/runtime/interpreter/mterp/arm64/binopWide2addr.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def binopWide2addr(preinstr="", instr="add x0, x0, x1", r0="x0", r1="x1", chkzero="0"):
- /*
- * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "x0 = x0 op x1".
- * This must not be a function call, as we keep w2 live across it.
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (w1). Useful for integer division and modulus.
- *
- * For: add-long/2addr, sub-long/2addr, mul-long/2addr, div-long/2addr,
- * and-long/2addr, or-long/2addr, xor-long/2addr,
- * shl-long/2addr, shr-long/2addr, ushr-long/2addr, add-double/2addr,
- * sub-double/2addr, mul-double/2addr, div-double/2addr, rem-double/2addr
- */
- /* binop/2addr vA, vB */
- lsr w1, wINST, #12 // w1<- B
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG_WIDE $r1, w1 // x1<- vB
- GET_VREG_WIDE $r0, w2 // x0<- vA
- .if $chkzero
- cbz $r1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- $preinstr
- $instr // result<- op
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG_WIDE $r0, w2 // vAA<- result
- GOTO_OPCODE ip // jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm64/close_cfi.S b/runtime/interpreter/mterp/arm64/close_cfi.S
deleted file mode 100644
index 8f651b1..0000000
--- a/runtime/interpreter/mterp/arm64/close_cfi.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def close_cfi():
-// Close out the cfi info. We're treating mterp as a single function.
-
-END ExecuteMterpImpl
-
diff --git a/runtime/interpreter/mterp/arm64/const.S b/runtime/interpreter/mterp/arm64/const.S
deleted file mode 100644
index f8477a8..0000000
--- a/runtime/interpreter/mterp/arm64/const.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC
- FETCH w0, 1 // w0<- BBBB
- lsr w1, wINST, #8 // w1<- AA
- add x2, xFP, #OFF_FP_SHADOWFRAME
- mov x3, xSELF
- bl $helper // (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 2 // load rINST
- cbnz w0, MterpPossibleException // let reference interpreter deal with it.
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/control_flow.S b/runtime/interpreter/mterp/arm64/control_flow.S
new file mode 100644
index 0000000..b634c98
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/control_flow.S
@@ -0,0 +1,223 @@
+%def bincmp(condition=""):
+ /*
+ * Generic two-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ lsr w1, wINST, #12 // w1<- B
+ ubfx w0, wINST, #8, #4 // w0<- A
+ GET_VREG w3, w1 // w3<- vB
+ GET_VREG w2, w0 // w2<- vA
+ FETCH_S wINST, 1 // wINST<- branch offset, in code units
+ cmp w2, w3 // compare (vA, vB)
+ b.${condition} MterpCommonTakenBranchNoFlags
+ cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
+ b.eq .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def zcmp(compare="1", branch=""):
+ /*
+ * Generic one-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ lsr w0, wINST, #8 // w0<- AA
+ GET_VREG w2, w0 // w2<- vAA
+ FETCH_S wINST, 1 // w1<- branch offset, in code units
+ .if ${compare}
+ cmp w2, #0 // compare (vA, 0)
+ .endif
+ ${branch} MterpCommonTakenBranchNoFlags
+ cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
+ b.eq .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_goto():
+ /*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ sbfx wINST, wINST, #8, #8 // wINST<- ssssssAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_16():
+ /*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_32():
+ /*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Unlike most opcodes, this one is allowed to branch to itself, so
+ * our "backward branch" test must be "<=0" instead of "<0". Because
+ * we need the V bit set, we'll use an adds to convert from Dalvik
+ * offset to byte offset.
+ */
+ /* goto/32 +AAAAAAAA */
+ FETCH w0, 1 // w0<- aaaa (lo)
+ FETCH w1, 2 // w1<- AAAA (hi)
+ orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa
+ b MterpCommonTakenBranchNoFlags
+
+%def op_if_eq():
+% bincmp(condition="eq")
+
+%def op_if_eqz():
+% zcmp(compare="0", branch="cbz w2,")
+
+%def op_if_ge():
+% bincmp(condition="ge")
+
+%def op_if_gez():
+% zcmp(compare="0", branch="tbz w2, #31,")
+
+%def op_if_gt():
+% bincmp(condition="gt")
+
+%def op_if_gtz():
+% zcmp(branch="b.gt")
+
+%def op_if_le():
+% bincmp(condition="le")
+
+%def op_if_lez():
+% zcmp(branch="b.le")
+
+%def op_if_lt():
+% bincmp(condition="lt")
+
+%def op_if_ltz():
+% zcmp(compare="0", branch="tbnz w2, #31,")
+
+%def op_if_ne():
+% bincmp(condition="ne")
+
+%def op_if_nez():
+% zcmp(compare="0", branch="cbnz w2,")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+ /*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBB */
+ FETCH w0, 1 // x0<- 000000000000bbbb (lo)
+ FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
+ lsr w3, wINST, #8 // w3<- AA
+ orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb
+ GET_VREG w1, w3 // w1<- vAA
+ add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2
+ bl $func // w0<- code-unit branch offset
+ sxtw xINST, w0
+ b MterpCommonTakenBranchNoFlags
+
+%def op_return():
+ /*
+ * Return a 32-bit value.
+ *
+ * for: return, return-object
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ mov x0, xSELF
+ ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne .L${opcode}_check
+.L${opcode}_return:
+ lsr w2, wINST, #8 // r2<- AA
+ GET_VREG w0, w2 // r0<- vAA
+ b MterpReturn
+.L${opcode}_check:
+ bl MterpSuspendCheck // (self)
+ b .L${opcode}_return
+
+%def op_return_object():
+% op_return()
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ mov x0, xSELF
+ ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne .L${opcode}_check
+.L${opcode}_return:
+ mov x0, #0
+ b MterpReturn
+.L${opcode}_check:
+ bl MterpSuspendCheck // (self)
+ b .L${opcode}_return
+
+%def op_return_void_no_barrier():
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ mov x0, xSELF
+ ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne .L${opcode}_check
+.L${opcode}_return:
+ mov x0, #0
+ b MterpReturn
+.L${opcode}_check:
+ bl MterpSuspendCheck // (self)
+ b .L${opcode}_return
+
+%def op_return_wide():
+ /*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ bl MterpThreadFenceForConstructor
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ mov x0, xSELF
+ ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne .L${opcode}_check
+.L${opcode}_return:
+ lsr w2, wINST, #8 // w2<- AA
+ GET_VREG_WIDE x0, w2 // x0<- vAA
+ b MterpReturn
+.L${opcode}_check:
+ bl MterpSuspendCheck // (self)
+ b .L${opcode}_return
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+ /*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC
+ lsr w2, wINST, #8 // r2<- AA
+ GET_VREG w1, w2 // r1<- vAA (exception object)
+ cbz w1, common_errNullObject
+ str x1, [xSELF, #THREAD_EXCEPTION_OFFSET] // thread->exception<- obj
+ b MterpException
diff --git a/runtime/interpreter/mterp/arm64/entry.S b/runtime/interpreter/mterp/arm64/entry.S
deleted file mode 100644
index baf8afc..0000000
--- a/runtime/interpreter/mterp/arm64/entry.S
+++ /dev/null
@@ -1,67 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- .text
-
-/*
- * Interpreter entry point.
- * On entry:
- * x0 Thread* self/
- * x1 insns_
- * x2 ShadowFrame
- * x3 JValue* result_register
- *
- */
-ENTRY ExecuteMterpImpl
- SAVE_TWO_REGS_INCREASE_FRAME xPROFILE, x27, 80
- SAVE_TWO_REGS xIBASE, xREFS, 16
- SAVE_TWO_REGS xSELF, xINST, 32
- SAVE_TWO_REGS xPC, xFP, 48
- SAVE_TWO_REGS fp, lr, 64
- add fp, sp, #64
-
- /* Remember the return register */
- str x3, [x2, #SHADOWFRAME_RESULT_REGISTER_OFFSET]
-
- /* Remember the dex instruction pointer */
- str x1, [x2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET]
-
- /* set up "named" registers */
- 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
- ldr w0, [x2, #SHADOWFRAME_DEX_PC_OFFSET] // Get starting dex_pc.
- add xPC, x1, w0, lsl #1 // Create direct pointer to 1st dex opcode
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
- EXPORT_PC
-
- /* Starting ibase */
- ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
-
- /* Set up for backwards branches & osr profiling */
- ldr x0, [xFP, #OFF_FP_METHOD]
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xSELF
- bl MterpSetUpHotnessCountdown
- mov wPROFILE, w0 // Starting hotness countdown to xPROFILE
-
- /* start executing the instruction at rPC */
- FETCH_INST // load wINST from rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/arm64/fallback.S b/runtime/interpreter/mterp/arm64/fallback.S
deleted file mode 100644
index 3685700..0000000
--- a/runtime/interpreter/mterp/arm64/fallback.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- b MterpFallback
-
diff --git a/runtime/interpreter/mterp/arm64/fbinop.S b/runtime/interpreter/mterp/arm64/fbinop.S
deleted file mode 100644
index e3fb25a..0000000
--- a/runtime/interpreter/mterp/arm64/fbinop.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def fbinop(instr=""):
- /*:
- * Generic 32-bit floating-point operation.
- *
- * For: add-float, sub-float, mul-float, div-float
- * form: <op> s0, s0, s1
- */
- /* floatop vAA, vBB, vCC */
- FETCH w0, 1 // r0<- CCBB
- lsr w1, w0, #8 // r2<- CC
- and w0, w0, #255 // r1<- BB
- GET_VREG s1, w1
- GET_VREG s0, w0
- $instr // s0<- op
- lsr w1, wINST, #8 // r1<- AA
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG s0, w1
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/fbinop2addr.S b/runtime/interpreter/mterp/arm64/fbinop2addr.S
deleted file mode 100644
index 9f235d9..0000000
--- a/runtime/interpreter/mterp/arm64/fbinop2addr.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def fbinop2addr(instr=""):
- /*
- * Generic 32-bit floating point "/2addr" binary operation. Provide
- * an "instr" line that specifies an instruction that performs
- * "s2 = s0 op s1".
- *
- * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
- */
- /* binop/2addr vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w9, wINST, #8, #4 // w9<- A
- GET_VREG s1, w3
- GET_VREG s0, w9
- $instr // s2<- op
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG s2, w9
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/fcmp.S b/runtime/interpreter/mterp/arm64/fcmp.S
deleted file mode 100644
index c0cc33a..0000000
--- a/runtime/interpreter/mterp/arm64/fcmp.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def fcmp(wide="", r1="s1", r2="s2", cond="lt"):
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- */
- /* op vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w4, wINST, #8 // w4<- AA
- and w2, w0, #255 // w2<- BB
- lsr w3, w0, #8 // w3<- CC
- GET_VREG$wide $r1, w2
- GET_VREG$wide $r2, w3
- fcmp $r1, $r2
- cset w0, ne
- cneg w0, w0, $cond
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG w0, w4 // vAA<- w0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/field.S b/runtime/interpreter/mterp/arm64/field.S
deleted file mode 100644
index 8a66992..0000000
--- a/runtime/interpreter/mterp/arm64/field.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def field(helper=""):
- /*
- * General field read / write (iget-* iput-* sget-* sput-*).
- */
- .extern $helper
- mov x0, xPC // arg0: Instruction* inst
- mov x1, xINST // arg1: uint16_t inst_data
- add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
- mov x3, xSELF // arg3: Thread* self
- PREFETCH_INST 2 // prefetch next opcode
- bl $helper
- cbz x0, MterpPossibleException
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/floating_point.S b/runtime/interpreter/mterp/arm64/floating_point.S
new file mode 100644
index 0000000..04ca694
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/floating_point.S
@@ -0,0 +1,269 @@
+%def fbinop(instr=""):
+ /*:
+ * Generic 32-bit floating-point operation.
+ *
+ * For: add-float, sub-float, mul-float, div-float
+ * form: <op> s0, s0, s1
+ */
+ /* floatop vAA, vBB, vCC */
+ FETCH w0, 1 // r0<- CCBB
+ lsr w1, w0, #8 // r2<- CC
+ and w0, w0, #255 // r1<- BB
+ GET_VREG s1, w1
+ GET_VREG s0, w0
+ $instr // s0<- op
+ lsr w1, wINST, #8 // r1<- AA
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG s0, w1
+ GOTO_OPCODE ip // jump to next instruction
+
+%def fbinop2addr(instr=""):
+ /*
+ * Generic 32-bit floating point "/2addr" binary operation. Provide
+ * an "instr" line that specifies an instruction that performs
+ * "s2 = s0 op s1".
+ *
+ * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
+ */
+ /* binop/2addr vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w9, wINST, #8, #4 // w9<- A
+ GET_VREG s1, w3
+ GET_VREG s0, w9
+ $instr // s2<- op
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG s2, w9
+ GOTO_OPCODE ip // jump to next instruction
+
+%def fcmp(wide="", r1="s1", r2="s2", cond="lt"):
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w4, wINST, #8 // w4<- AA
+ and w2, w0, #255 // w2<- BB
+ lsr w3, w0, #8 // w3<- CC
+ GET_VREG$wide $r1, w2
+ GET_VREG$wide $r2, w3
+ fcmp $r1, $r2
+ cset w0, ne
+ cneg w0, w0, $cond
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG w0, w4 // vAA<- w0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def funopNarrow(srcreg="s0", tgtreg="d0", instr=""):
+ /*
+ * Generic 32bit-to-32bit floating point unary operation. Provide an
+ * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
+ *
+ * For: int-to-float, float-to-int
+ * TODO: refactor all of the conversions - parameterize width and use same template.
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG $srcreg, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ $instr // d0<- op
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG $tgtreg, w4 // vA<- d0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def funopNarrower(srcreg="s0", tgtreg="d0", instr=""):
+ /*
+ * Generic 64bit-to-32bit floating point unary operation. Provide an
+ * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
+ *
+ * For: int-to-double, float-to-double, float-to-long
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG_WIDE $srcreg, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ $instr // d0<- op
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG $tgtreg, w4 // vA<- d0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def funopWide(srcreg="s0", tgtreg="d0", instr=""):
+ /*
+ * Generic 64bit-to-64bit floating point unary operation. Provide an
+ * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
+ *
+ * For: long-to-double, double-to-long
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG_WIDE $srcreg, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ $instr // d0<- op
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE $tgtreg, w4 // vA<- d0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def funopWider(srcreg="s0", tgtreg="d0", instr=""):
+ /*
+ * Generic 32bit-to-64bit floating point unary operation. Provide an
+ * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
+ *
+ * For: int-to-double, float-to-double, float-to-long
+ */
+ /* unop vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w4, wINST, #8, #4 // w4<- A
+ GET_VREG $srcreg, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ $instr // d0<- op
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE $tgtreg, w4 // vA<- d0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_add_double():
+% binopWide(instr="fadd d0, d1, d2", result="d0", r1="d1", r2="d2")
+
+%def op_add_double_2addr():
+% binopWide2addr(instr="fadd d0, d0, d1", r0="d0", r1="d1")
+
+%def op_add_float():
+% fbinop(instr="fadd s0, s0, s1")
+
+%def op_add_float_2addr():
+% fbinop2addr(instr="fadd s2, s0, s1")
+
+%def op_cmpg_double():
+% fcmp(wide="_WIDE", r1="d1", r2="d2", cond="cc")
+
+%def op_cmpg_float():
+% fcmp(wide="", r1="s1", r2="s2", cond="cc")
+
+%def op_cmpl_double():
+% fcmp(wide="_WIDE", r1="d1", r2="d2", cond="lt")
+
+%def op_cmpl_float():
+% fcmp(wide="", r1="s1", r2="s2", cond="lt")
+
+%def op_div_double():
+% binopWide(instr="fdiv d0, d1, d2", result="d0", r1="d1", r2="d2")
+
+%def op_div_double_2addr():
+% binopWide2addr(instr="fdiv d0, d0, d1", r0="d0", r1="d1")
+
+%def op_div_float():
+% fbinop(instr="fdiv s0, s0, s1")
+
+%def op_div_float_2addr():
+% fbinop2addr(instr="fdiv s2, s0, s1")
+
+%def op_double_to_float():
+% funopNarrower(instr="fcvt s0, d0", srcreg="d0", tgtreg="s0")
+
+%def op_double_to_int():
+% funopNarrower(instr="fcvtzs w0, d0", srcreg="d0", tgtreg="w0")
+
+%def op_double_to_long():
+% funopWide(instr="fcvtzs x0, d0", srcreg="d0", tgtreg="x0")
+
+%def op_float_to_double():
+% funopWider(instr="fcvt d0, s0", srcreg="s0", tgtreg="d0")
+
+%def op_float_to_int():
+% funopNarrow(instr="fcvtzs w0, s0", srcreg="s0", tgtreg="w0")
+
+%def op_float_to_long():
+% funopWider(instr="fcvtzs x0, s0", srcreg="s0", tgtreg="x0")
+
+%def op_int_to_double():
+% funopWider(instr="scvtf d0, w0", srcreg="w0", tgtreg="d0")
+
+%def op_int_to_float():
+% funopNarrow(instr="scvtf s0, w0", srcreg="w0", tgtreg="s0")
+
+%def op_long_to_double():
+% funopWide(instr="scvtf d0, x0", srcreg="x0", tgtreg="d0")
+
+%def op_long_to_float():
+% funopNarrower(instr="scvtf s0, x0", srcreg="x0", tgtreg="s0")
+
+%def op_mul_double():
+% binopWide(instr="fmul d0, d1, d2", result="d0", r1="d1", r2="d2")
+
+%def op_mul_double_2addr():
+% binopWide2addr(instr="fmul d0, d0, d1", r0="d0", r1="d1")
+
+%def op_mul_float():
+% fbinop(instr="fmul s0, s0, s1")
+
+%def op_mul_float_2addr():
+% fbinop2addr(instr="fmul s2, s0, s1")
+
+%def op_neg_double():
+% unopWide(instr="eor x0, x0, #0x8000000000000000")
+
+%def op_neg_float():
+% unop(instr="eor w0, w0, #0x80000000")
+
+%def op_rem_double():
+ /* rem vAA, vBB, vCC */
+ FETCH w0, 1 // w0<- CCBB
+ lsr w2, w0, #8 // w2<- CC
+ and w1, w0, #255 // w1<- BB
+ GET_VREG_WIDE d1, w2 // d1<- vCC
+ GET_VREG_WIDE d0, w1 // d0<- vBB
+ bl fmod
+ lsr w4, wINST, #8 // w4<- AA
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG_WIDE d0, w4 // vAA<- result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 11-14 instructions */
+
+%def op_rem_double_2addr():
+ /* rem vA, vB */
+ lsr w1, wINST, #12 // w1<- B
+ ubfx w2, wINST, #8, #4 // w2<- A
+ GET_VREG_WIDE d1, w1 // d1<- vB
+ GET_VREG_WIDE d0, w2 // d0<- vA
+ bl fmod
+ ubfx w2, wINST, #8, #4 // w2<- A (need to reload - killed across call)
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG_WIDE d0, w2 // vAA<- result
+ GOTO_OPCODE ip // jump to next instruction
+ /* 10-13 instructions */
+
+%def op_rem_float():
+/* EABI doesn't define a float remainder function, but libm does */
+% fbinop(instr="bl fmodf")
+
+%def op_rem_float_2addr():
+ /* rem vA, vB */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w9, wINST, #8, #4 // w9<- A
+ GET_VREG s1, w3
+ GET_VREG s0, w9
+ bl fmodf
+ 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
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_sub_double():
+% binopWide(instr="fsub d0, d1, d2", result="d0", r1="d1", r2="d2")
+
+%def op_sub_double_2addr():
+% binopWide2addr(instr="fsub d0, d0, d1", r0="d0", r1="d1")
+
+%def op_sub_float():
+% fbinop(instr="fsub s0, s0, s1")
+
+%def op_sub_float_2addr():
+% fbinop2addr(instr="fsub s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/footer.S b/runtime/interpreter/mterp/arm64/footer.S
deleted file mode 100644
index ba17f5e..0000000
--- a/runtime/interpreter/mterp/arm64/footer.S
+++ /dev/null
@@ -1,305 +0,0 @@
-%def footer():
-/*
- * ===========================================================================
- * Common subroutines and data
- * ===========================================================================
- */
-
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-common_errDivideByZero:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogDivideByZeroException
-#endif
- b MterpCommonFallback
-
-common_errArrayIndex:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogArrayIndexException
-#endif
- b MterpCommonFallback
-
-common_errNegativeArraySize:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNegativeArraySizeException
-#endif
- b MterpCommonFallback
-
-common_errNoSuchMethod:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNoSuchMethodException
-#endif
- b MterpCommonFallback
-
-common_errNullObject:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogNullObjectException
-#endif
- b MterpCommonFallback
-
-common_exceptionThrown:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogExceptionThrownException
-#endif
- b MterpCommonFallback
-
-MterpSuspendFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- ldr x2, [xSELF, #THREAD_FLAGS_OFFSET]
- bl MterpLogSuspendFallback
-#endif
- b MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- ldr x0, [xSELF, #THREAD_EXCEPTION_OFFSET]
- cbz x0, MterpFallback // If not, fall back to reference interpreter.
- /* intentional fallthrough - handle pending exception. */
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
-MterpException:
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpHandleException // (self, shadow_frame)
- cbz w0, MterpExceptionReturn // no local catch, back to caller.
- ldr x0, [xFP, #OFF_FP_DEX_INSTRUCTIONS]
- ldr w1, [xFP, #OFF_FP_DEX_PC]
- ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
- add xPC, x0, x1, lsl #1 // generate new dex_pc_ptr
- /* Do we need to switch interpreters? */
- bl MterpShouldSwitchInterpreters
- cbnz w0, MterpFallback
- /* resume execution at catch block */
- EXPORT_PC
- FETCH_INST
- GET_INST_OPCODE ip
- GOTO_OPCODE ip
- /* NOTE: no fallthrough */
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * wINST <= signed offset
- * wPROFILE <= signed hotness countdown (expanded to 32 bits)
- * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- *
- */
-MterpCommonTakenBranchNoFlags:
- cmp wINST, #0
- b.gt .L_forward_branch // don't add forward branches to hotness
- tbnz wPROFILE, #31, .L_no_count_backwards // go if negative
- subs wPROFILE, wPROFILE, #1 // countdown
- b.eq .L_add_batch // counted down to zero - report
-.L_resume_backward_branch:
- ldr lr, [xSELF, #THREAD_FLAGS_OFFSET]
- add w2, wINST, wINST // w2<- byte offset
- FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
- REFRESH_IBASE
- ands lr, lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne .L_suspend_request_pending
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-
-.L_suspend_request_pending:
- EXPORT_PC
- mov x0, xSELF
- bl MterpSuspendCheck // (self)
- cbnz x0, MterpFallback
- REFRESH_IBASE // might have changed during suspend
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-
-.L_no_count_backwards:
- cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
- b.ne .L_resume_backward_branch
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xINST
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
- cbnz x0, MterpOnStackReplacement
- b .L_resume_backward_branch
-
-.L_forward_branch:
- cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
- b.eq .L_check_osr_forward
-.L_resume_forward_branch:
- add w2, wINST, wINST // w2<- byte offset
- FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-
-.L_check_osr_forward:
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xINST
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
- cbnz x0, MterpOnStackReplacement
- b .L_resume_forward_branch
-
-.L_add_batch:
- add x1, xFP, #OFF_FP_SHADOWFRAME
- strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
- ldr x0, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpAddHotnessBatch // (method, shadow_frame, self)
- mov wPROFILE, w0 // restore new hotness countdown to wPROFILE
- b .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, #2
- EXPORT_PC
- bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
- cbnz x0, MterpOnStackReplacement
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-
-/*
- * Check for suspend check request. Assumes wINST already loaded, xPC advanced and
- * still needs to get the opcode and branch to it, and flags are in lr.
- */
-MterpCheckSuspendAndContinue:
- ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh xIBASE
- ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne check1
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-check1:
- EXPORT_PC
- mov x0, xSELF
- bl MterpSuspendCheck // (self)
- cbnz x0, MterpFallback // Something in the environment changed, switch interpreters
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- sxtw x2, wINST
- bl MterpLogOSR
-#endif
- mov x0, #1 // Signal normal return
- b MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
-MterpFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- bl MterpLogFallback
-#endif
-MterpCommonFallback:
- mov x0, #0 // signal retry with reference interpreter.
- b MterpDone
-
-/*
- * We pushed some registers on the stack in ExecuteMterpImpl, then saved
- * SP and LR. Here we restore SP, restore the registers, and then restore
- * LR to PC.
- *
- * On entry:
- * uint32_t* xFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- mov x0, #1 // signal return to caller.
- b MterpDone
-MterpReturn:
- ldr x2, [xFP, #OFF_FP_RESULT_REGISTER]
- str x0, [x2]
- mov x0, #1 // signal return to caller.
-MterpDone:
-/*
- * At this point, we expect wPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending wPROFILE and the cached hotness counter). wPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- cmp wPROFILE, #0
- bgt MterpProfileActive // if > 0, we may have some counts to report.
- .cfi_remember_state
- RESTORE_TWO_REGS fp, lr, 64
- RESTORE_TWO_REGS xPC, xFP, 48
- RESTORE_TWO_REGS xSELF, xINST, 32
- RESTORE_TWO_REGS xIBASE, xREFS, 16
- RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
- ret
- .cfi_restore_state // Reset unwind info so following code unwinds.
- .cfi_def_cfa_offset 80 // workaround for clang bug: 31975598
-
-MterpProfileActive:
- mov xINST, x0 // stash return value
- /* Report cached hotness counts */
- ldr x0, [xFP, #OFF_FP_METHOD]
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xSELF
- strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
- bl MterpAddHotnessBatch // (method, shadow_frame, self)
- mov x0, xINST // restore return value
- RESTORE_TWO_REGS fp, lr, 64
- RESTORE_TWO_REGS xPC, xFP, 48
- RESTORE_TWO_REGS xSELF, xINST, 32
- RESTORE_TWO_REGS xIBASE, xREFS, 16
- RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
- ret
-
diff --git a/runtime/interpreter/mterp/arm64/funopNarrow.S b/runtime/interpreter/mterp/arm64/funopNarrow.S
deleted file mode 100644
index f08e87f..0000000
--- a/runtime/interpreter/mterp/arm64/funopNarrow.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def funopNarrow(srcreg="s0", tgtreg="d0", instr=""):
- /*
- * Generic 32bit-to-32bit floating point unary operation. Provide an
- * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
- *
- * For: int-to-float, float-to-int
- * TODO: refactor all of the conversions - parameterize width and use same template.
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG $srcreg, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- $instr // d0<- op
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG $tgtreg, w4 // vA<- d0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/funopNarrower.S b/runtime/interpreter/mterp/arm64/funopNarrower.S
deleted file mode 100644
index e1a1214..0000000
--- a/runtime/interpreter/mterp/arm64/funopNarrower.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def funopNarrower(srcreg="s0", tgtreg="d0", instr=""):
- /*
- * Generic 64bit-to-32bit floating point unary operation. Provide an
- * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
- *
- * For: int-to-double, float-to-double, float-to-long
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG_WIDE $srcreg, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- $instr // d0<- op
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG $tgtreg, w4 // vA<- d0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/funopWide.S b/runtime/interpreter/mterp/arm64/funopWide.S
deleted file mode 100644
index 83e55be..0000000
--- a/runtime/interpreter/mterp/arm64/funopWide.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def funopWide(srcreg="s0", tgtreg="d0", instr=""):
- /*
- * Generic 64bit-to-64bit floating point unary operation. Provide an
- * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
- *
- * For: long-to-double, double-to-long
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG_WIDE $srcreg, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- $instr // d0<- op
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE $tgtreg, w4 // vA<- d0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/funopWider.S b/runtime/interpreter/mterp/arm64/funopWider.S
deleted file mode 100644
index 825698e..0000000
--- a/runtime/interpreter/mterp/arm64/funopWider.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def funopWider(srcreg="s0", tgtreg="d0", instr=""):
- /*
- * Generic 32bit-to-64bit floating point unary operation. Provide an
- * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg".
- *
- * For: int-to-double, float-to-double, float-to-long
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG $srcreg, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- $instr // d0<- op
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE $tgtreg, w4 // vA<- d0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/header.S b/runtime/interpreter/mterp/arm64/header.S
deleted file mode 100644
index 4102972..0000000
--- a/runtime/interpreter/mterp/arm64/header.S
+++ /dev/null
@@ -1,354 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- Art assembly interpreter notes:
-
- First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
- handle invoke, allows higher-level code to create frame & shadow frame.
-
- Once that's working, support direct entry code & eliminate shadow frame (and
- excess locals allocation.
-
- Some (hopefully) temporary ugliness. We'll treat xFP as pointing to the
- base of the vreg array within the shadow frame. Access the other fields,
- dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
- the shadow frame mechanism of double-storing object references - via xFP &
- number_of_vregs_.
-
- */
-
-/*
-ARM64 Runtime register usage conventions.
-
- r0 : w0 is 32-bit return register and x0 is 64-bit.
- r0-r7 : Argument registers.
- r8-r15 : Caller save registers (used as temporary registers).
- r16-r17: Also known as ip0-ip1, respectively. Used as scratch registers by
- the linker, by the trampolines and other stubs (the backend uses
- these as temporary registers).
- r18 : Caller save register (used as temporary register).
- r19 : Pointer to thread-local storage.
- r20-r29: Callee save registers.
- r30 : (lr) is reserved (the link register).
- rsp : (sp) is reserved (the stack pointer).
- rzr : (zr) is reserved (the zero register).
-
- Floating-point registers
- v0-v31
-
- v0 : s0 is return register for singles (32-bit) and d0 for doubles (64-bit).
- This is analogous to the C/C++ (hard-float) calling convention.
- v0-v7 : Floating-point argument registers in both Dalvik and C/C++ conventions.
- Also used as temporary and codegen scratch registers.
-
- v0-v7 and v16-v31 : trashed across C calls.
- v8-v15 : bottom 64-bits preserved across C calls (d8-d15 are preserved).
-
- v16-v31: Used as codegen temp/scratch.
- v8-v15 : Can be used for promotion.
-
- Must maintain 16-byte stack alignment.
-
-Mterp notes:
-
-The following registers have fixed assignments:
-
- reg nick purpose
- x20 xPC interpreted program counter, used for fetching instructions
- x21 xFP interpreted frame pointer, used for accessing locals and args
- x22 xSELF self (Thread) pointer
- x23 xINST first 16-bit code unit of current instruction
- x24 xIBASE interpreted instruction base pointer, used for computed goto
- x25 xREFS base of object references in shadow frame (ideally, we'll get rid of this later).
- x26 wPROFILE jit profile hotness countdown
- x16 ip scratch reg
- x17 ip2 scratch reg (used by macros)
-
-Macros are provided for common operations. They MUST NOT alter unspecified registers or condition
-codes.
-*/
-
-/*
- * This is a #include, not a %include, because we want the C pre-processor
- * to expand the macros into assembler assignment statements.
- */
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-#define MTERP_PROFILE_BRANCHES 1
-#define MTERP_LOGGING 0
-
-/* During bringup, we'll use the shadow frame model instead of xFP */
-/* single-purpose registers, given names for clarity */
-#define xPC x20
-#define CFI_DEX 20 // DWARF register number of the register holding dex-pc (xPC).
-#define CFI_TMP 0 // DWARF register number of the first argument register (r0).
-#define xFP x21
-#define xSELF x22
-#define xINST x23
-#define wINST w23
-#define xIBASE x24
-#define xREFS x25
-#define wPROFILE w26
-#define xPROFILE x26
-#define ip x16
-#define ip2 x17
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep xFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_SHADOWFRAME OFF_FP(0)
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-.macro EXPORT_PC
- str xPC, [xFP, #OFF_FP_DEX_PC_PTR]
-.endm
-
-/*
- * Fetch the next instruction from xPC into wINST. Does not advance xPC.
- */
-.macro FETCH_INST
- ldrh wINST, [xPC]
-.endm
-
-/*
- * Fetch the next instruction from the specified offset. Advances xPC
- * to point to the next instruction. "_count" is in 16-bit code units.
- *
- * Because of the limited size of immediate constants on ARM, this is only
- * suitable for small forward movements (i.e. don't try to implement "goto"
- * with this).
- *
- * This must come AFTER anything that can throw an exception, or the
- * exception catch may miss. (This also implies that it must come after
- * EXPORT_PC.)
- */
-.macro FETCH_ADVANCE_INST count
- ldrh wINST, [xPC, #((\count)*2)]!
-.endm
-
-/*
- * The operation performed here is similar to FETCH_ADVANCE_INST, except the
- * src and dest registers are parameterized (not hard-wired to xPC and xINST).
- */
-.macro PREFETCH_ADVANCE_INST dreg, sreg, count
- ldrh \dreg, [\sreg, #((\count)*2)]!
-.endm
-
-/*
- * Similar to FETCH_ADVANCE_INST, but does not update xPC. Used to load
- * xINST ahead of possible exception point. Be sure to manually advance xPC
- * later.
- */
-.macro PREFETCH_INST count
- ldrh wINST, [xPC, #((\count)*2)]
-.endm
-
-/* Advance xPC by some number of code units. */
-.macro ADVANCE count
- add xPC, xPC, #((\count)*2)
-.endm
-
-/*
- * Fetch the next instruction from an offset specified by _reg and advance xPC.
- * xPC to point to the next instruction. "_reg" must specify the distance
- * in bytes, *not* 16-bit code units, and may be a signed value. Must not set flags.
- *
- */
-.macro FETCH_ADVANCE_INST_RB reg
- add xPC, xPC, \reg, sxtw
- ldrh wINST, [xPC]
-.endm
-
-/*
- * Fetch a half-word code unit from an offset past the current PC. The
- * "_count" value is in 16-bit code units. Does not advance xPC.
- *
- * The "_S" variant works the same but treats the value as signed.
- */
-.macro FETCH reg, count
- ldrh \reg, [xPC, #((\count)*2)]
-.endm
-
-.macro FETCH_S reg, count
- ldrsh \reg, [xPC, #((\count)*2)]
-.endm
-
-/*
- * Fetch one byte from an offset past the current PC. Pass in the same
- * "_count" as you would for FETCH, and an additional 0/1 indicating which
- * byte of the halfword you want (lo/hi).
- */
-.macro FETCH_B reg, count, byte
- ldrb \reg, [xPC, #((\count)*2+(\byte))]
-.endm
-
-/*
- * Put the instruction's opcode field into the specified register.
- */
-.macro GET_INST_OPCODE reg
- and \reg, xINST, #255
-.endm
-
-/*
- * Put the prefetched instruction's opcode field into the specified register.
- */
-.macro GET_PREFETCHED_OPCODE oreg, ireg
- and \oreg, \ireg, #255
-.endm
-
-/*
- * Begin executing the opcode in _reg. Clobbers reg
- */
-
-.macro GOTO_OPCODE reg
- add \reg, xIBASE, \reg, lsl #${handler_size_bits}
- br \reg
-.endm
-.macro GOTO_OPCODE_BASE base,reg
- add \reg, \base, \reg, lsl #${handler_size_bits}
- br \reg
-.endm
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- */
-.macro GET_VREG reg, vreg
- ldr \reg, [xFP, \vreg, uxtw #2]
-.endm
-.macro SET_VREG reg, vreg
- str \reg, [xFP, \vreg, uxtw #2]
- str wzr, [xREFS, \vreg, uxtw #2]
-.endm
-.macro SET_VREG_OBJECT reg, vreg, tmpreg
- str \reg, [xFP, \vreg, uxtw #2]
- str \reg, [xREFS, \vreg, uxtw #2]
-.endm
-
-/*
- * Get/set the 64-bit value from a Dalvik register.
- * TUNING: can we do better here?
- */
-.macro GET_VREG_WIDE reg, vreg
- add ip2, xFP, \vreg, lsl #2
- ldr \reg, [ip2]
-.endm
-.macro SET_VREG_WIDE reg, vreg
- add ip2, xFP, \vreg, lsl #2
- str \reg, [ip2]
- add ip2, xREFS, \vreg, lsl #2
- str xzr, [ip2]
-.endm
-
-/*
- * Get the 32-bit value from a Dalvik register and sign-extend to 64-bit.
- * Used to avoid an extra instruction in int-to-long.
- */
-.macro GET_VREG_S reg, vreg
- ldrsw \reg, [xFP, \vreg, uxtw #2]
-.endm
-
-/*
- * 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 */
-.endm
-
-/*
- * Refresh handler table.
- */
-.macro REFRESH_IBASE
- ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
-.endm
-
-/*
- * Save two registers to the stack.
- */
-.macro SAVE_TWO_REGS reg1, reg2, offset
- stp \reg1, \reg2, [sp, #(\offset)]
- .cfi_rel_offset \reg1, (\offset)
- .cfi_rel_offset \reg2, (\offset) + 8
-.endm
-
-/*
- * Restore two registers from the stack.
- */
-.macro RESTORE_TWO_REGS reg1, reg2, offset
- ldp \reg1, \reg2, [sp, #(\offset)]
- .cfi_restore \reg1
- .cfi_restore \reg2
-.endm
-
-/*
- * Increase frame size and save two registers to the bottom of the stack.
- */
-.macro SAVE_TWO_REGS_INCREASE_FRAME reg1, reg2, frame_adjustment
- stp \reg1, \reg2, [sp, #-(\frame_adjustment)]!
- .cfi_adjust_cfa_offset (\frame_adjustment)
- .cfi_rel_offset \reg1, 0
- .cfi_rel_offset \reg2, 8
-.endm
-
-/*
- * Restore two registers from the bottom of the stack and decrease frame size.
- */
-.macro RESTORE_TWO_REGS_DECREASE_FRAME reg1, reg2, frame_adjustment
- ldp \reg1, \reg2, [sp], #(\frame_adjustment)
- .cfi_restore \reg1
- .cfi_restore \reg2
- .cfi_adjust_cfa_offset -(\frame_adjustment)
-.endm
-
-/*
- * cfi support macros.
- */
-.macro ENTRY name
- .type \name, #function
- .hidden \name // Hide this as a global symbol, so we do not incur plt calls.
- .global \name
- /* Cache alignment for function entry */
- .balign 16
-\name:
- .cfi_startproc
-.endm
-
-.macro END name
- .cfi_endproc
- .size \name, .-\name
-.endm
diff --git a/runtime/interpreter/mterp/arm64/instruction_end.S b/runtime/interpreter/mterp/arm64/instruction_end.S
deleted file mode 100644
index cf30a9b..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_end.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end():
-
- .type artMterpAsmInstructionEnd, #object
- .hidden artMterpAsmInstructionEnd
- .global artMterpAsmInstructionEnd
-artMterpAsmInstructionEnd:
diff --git a/runtime/interpreter/mterp/arm64/instruction_end_alt.S b/runtime/interpreter/mterp/arm64/instruction_end_alt.S
deleted file mode 100644
index 9509a63..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_end_alt.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_alt():
-
- .type artMterpAsmAltInstructionEnd, #object
- .hidden artMterpAsmAltInstructionEnd
- .global artMterpAsmAltInstructionEnd
-artMterpAsmAltInstructionEnd:
diff --git a/runtime/interpreter/mterp/arm64/instruction_end_sister.S b/runtime/interpreter/mterp/arm64/instruction_end_sister.S
deleted file mode 100644
index 18f1dbb..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_end_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_sister():
-
- .type artMterpAsmSisterEnd, #object
- .hidden artMterpAsmSisterEnd
- .global artMterpAsmSisterEnd
-artMterpAsmSisterEnd:
diff --git a/runtime/interpreter/mterp/arm64/instruction_start.S b/runtime/interpreter/mterp/arm64/instruction_start.S
deleted file mode 100644
index 457dcf9..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_start.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start():
-
- .type artMterpAsmInstructionStart, #object
- .hidden artMterpAsmInstructionStart
- .global artMterpAsmInstructionStart
-artMterpAsmInstructionStart = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/arm64/instruction_start_alt.S b/runtime/interpreter/mterp/arm64/instruction_start_alt.S
deleted file mode 100644
index 40d2bf5..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_start_alt.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start_alt():
-
- .type artMterpAsmAltInstructionStart, #object
- .hidden artMterpAsmAltInstructionStart
- .global artMterpAsmAltInstructionStart
-artMterpAsmAltInstructionStart = .L_ALT_op_nop
- .text
diff --git a/runtime/interpreter/mterp/arm64/instruction_start_sister.S b/runtime/interpreter/mterp/arm64/instruction_start_sister.S
deleted file mode 100644
index 2bf2463..0000000
--- a/runtime/interpreter/mterp/arm64/instruction_start_sister.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def instruction_start_sister():
-
- .type artMterpAsmSisterStart, #object
- .hidden artMterpAsmSisterStart
- .global artMterpAsmSisterStart
- .text
- .balign 4
-artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/arm64/invoke.S b/runtime/interpreter/mterp/arm64/invoke.S
index 9e5b5b7..03ac316 100644
--- a/runtime/interpreter/mterp/arm64/invoke.S
+++ b/runtime/interpreter/mterp/arm64/invoke.S
@@ -18,3 +18,93 @@
GET_INST_OPCODE ip
GOTO_OPCODE ip
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ EXPORT_PC
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xPC
+ mov x3, xINST
+ bl $helper
+ cbz w0, MterpException
+ FETCH_ADVANCE_INST 4
+ bl MterpShouldSwitchInterpreters
+ cbnz w0, MterpFallback
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+ /*
+ * Handle an interface method call.
+ *
+ * for: invoke-interface, invoke-interface/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+ /*
+ * Handle a "super" method call.
+ *
+ * for: invoke-super, invoke-super/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+ /*
+ * Handle a virtual method call.
+ *
+ * for: invoke-virtual, invoke-virtual/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/arm64/invoke_polymorphic.S b/runtime/interpreter/mterp/arm64/invoke_polymorphic.S
deleted file mode 100644
index 08ffb9c..0000000
--- a/runtime/interpreter/mterp/arm64/invoke_polymorphic.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- EXPORT_PC
- mov x0, xSELF
- add x1, xFP, #OFF_FP_SHADOWFRAME
- mov x2, xPC
- mov x3, xINST
- bl $helper
- cbz w0, MterpException
- FETCH_ADVANCE_INST 4
- bl MterpShouldSwitchInterpreters
- cbnz w0, MterpFallback
- GET_INST_OPCODE ip
- GOTO_OPCODE ip
diff --git a/runtime/interpreter/mterp/arm64/main.S b/runtime/interpreter/mterp/arm64/main.S
new file mode 100644
index 0000000..37ed83d
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/main.S
@@ -0,0 +1,799 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ Art assembly interpreter notes:
+
+ First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
+ handle invoke, allows higher-level code to create frame & shadow frame.
+
+ Once that's working, support direct entry code & eliminate shadow frame (and
+ excess locals allocation.
+
+ Some (hopefully) temporary ugliness. We'll treat xFP as pointing to the
+ base of the vreg array within the shadow frame. Access the other fields,
+ dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
+ the shadow frame mechanism of double-storing object references - via xFP &
+ number_of_vregs_.
+
+ */
+
+/*
+ARM64 Runtime register usage conventions.
+
+ r0 : w0 is 32-bit return register and x0 is 64-bit.
+ r0-r7 : Argument registers.
+ r8-r15 : Caller save registers (used as temporary registers).
+ r16-r17: Also known as ip0-ip1, respectively. Used as scratch registers by
+ the linker, by the trampolines and other stubs (the backend uses
+ these as temporary registers).
+ r18 : Caller save register (used as temporary register).
+ r19 : Pointer to thread-local storage.
+ r20-r29: Callee save registers.
+ r30 : (lr) is reserved (the link register).
+ rsp : (sp) is reserved (the stack pointer).
+ rzr : (zr) is reserved (the zero register).
+
+ Floating-point registers
+ v0-v31
+
+ v0 : s0 is return register for singles (32-bit) and d0 for doubles (64-bit).
+ This is analogous to the C/C++ (hard-float) calling convention.
+ v0-v7 : Floating-point argument registers in both Dalvik and C/C++ conventions.
+ Also used as temporary and codegen scratch registers.
+
+ v0-v7 and v16-v31 : trashed across C calls.
+ v8-v15 : bottom 64-bits preserved across C calls (d8-d15 are preserved).
+
+ v16-v31: Used as codegen temp/scratch.
+ v8-v15 : Can be used for promotion.
+
+ Must maintain 16-byte stack alignment.
+
+Mterp notes:
+
+The following registers have fixed assignments:
+
+ reg nick purpose
+ x20 xPC interpreted program counter, used for fetching instructions
+ x21 xFP interpreted frame pointer, used for accessing locals and args
+ x22 xSELF self (Thread) pointer
+ x23 xINST first 16-bit code unit of current instruction
+ x24 xIBASE interpreted instruction base pointer, used for computed goto
+ x25 xREFS base of object references in shadow frame (ideally, we'll get rid of this later).
+ x26 wPROFILE jit profile hotness countdown
+ x16 ip scratch reg
+ x17 ip2 scratch reg (used by macros)
+
+Macros are provided for common operations. They MUST NOT alter unspecified registers or condition
+codes.
+*/
+
+/*
+ * This is a #include, not a %include, because we want the C pre-processor
+ * to expand the macros into assembler assignment statements.
+ */
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
+/* During bringup, we'll use the shadow frame model instead of xFP */
+/* single-purpose registers, given names for clarity */
+#define xPC x20
+#define CFI_DEX 20 // DWARF register number of the register holding dex-pc (xPC).
+#define CFI_TMP 0 // DWARF register number of the first argument register (r0).
+#define xFP x21
+#define xSELF x22
+#define xINST x23
+#define wINST w23
+#define xIBASE x24
+#define xREFS x25
+#define wPROFILE w26
+#define xPROFILE x26
+#define ip x16
+#define ip2 x17
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep xFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_SHADOWFRAME OFF_FP(0)
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+.macro EXPORT_PC
+ str xPC, [xFP, #OFF_FP_DEX_PC_PTR]
+.endm
+
+/*
+ * Fetch the next instruction from xPC into wINST. Does not advance xPC.
+ */
+.macro FETCH_INST
+ ldrh wINST, [xPC]
+.endm
+
+/*
+ * Fetch the next instruction from the specified offset. Advances xPC
+ * to point to the next instruction. "_count" is in 16-bit code units.
+ *
+ * Because of the limited size of immediate constants on ARM, this is only
+ * suitable for small forward movements (i.e. don't try to implement "goto"
+ * with this).
+ *
+ * This must come AFTER anything that can throw an exception, or the
+ * exception catch may miss. (This also implies that it must come after
+ * EXPORT_PC.)
+ */
+.macro FETCH_ADVANCE_INST count
+ ldrh wINST, [xPC, #((\count)*2)]!
+.endm
+
+/*
+ * The operation performed here is similar to FETCH_ADVANCE_INST, except the
+ * src and dest registers are parameterized (not hard-wired to xPC and xINST).
+ */
+.macro PREFETCH_ADVANCE_INST dreg, sreg, count
+ ldrh \dreg, [\sreg, #((\count)*2)]!
+.endm
+
+/*
+ * Similar to FETCH_ADVANCE_INST, but does not update xPC. Used to load
+ * xINST ahead of possible exception point. Be sure to manually advance xPC
+ * later.
+ */
+.macro PREFETCH_INST count
+ ldrh wINST, [xPC, #((\count)*2)]
+.endm
+
+/* Advance xPC by some number of code units. */
+.macro ADVANCE count
+ add xPC, xPC, #((\count)*2)
+.endm
+
+/*
+ * Fetch the next instruction from an offset specified by _reg and advance xPC.
+ * xPC to point to the next instruction. "_reg" must specify the distance
+ * in bytes, *not* 16-bit code units, and may be a signed value. Must not set flags.
+ *
+ */
+.macro FETCH_ADVANCE_INST_RB reg
+ add xPC, xPC, \reg, sxtw
+ ldrh wINST, [xPC]
+.endm
+
+/*
+ * Fetch a half-word code unit from an offset past the current PC. The
+ * "_count" value is in 16-bit code units. Does not advance xPC.
+ *
+ * The "_S" variant works the same but treats the value as signed.
+ */
+.macro FETCH reg, count
+ ldrh \reg, [xPC, #((\count)*2)]
+.endm
+
+.macro FETCH_S reg, count
+ ldrsh \reg, [xPC, #((\count)*2)]
+.endm
+
+/*
+ * Fetch one byte from an offset past the current PC. Pass in the same
+ * "_count" as you would for FETCH, and an additional 0/1 indicating which
+ * byte of the halfword you want (lo/hi).
+ */
+.macro FETCH_B reg, count, byte
+ ldrb \reg, [xPC, #((\count)*2+(\byte))]
+.endm
+
+/*
+ * Put the instruction's opcode field into the specified register.
+ */
+.macro GET_INST_OPCODE reg
+ and \reg, xINST, #255
+.endm
+
+/*
+ * Put the prefetched instruction's opcode field into the specified register.
+ */
+.macro GET_PREFETCHED_OPCODE oreg, ireg
+ and \oreg, \ireg, #255
+.endm
+
+/*
+ * Begin executing the opcode in _reg. Clobbers reg
+ */
+
+.macro GOTO_OPCODE reg
+ add \reg, xIBASE, \reg, lsl #${handler_size_bits}
+ br \reg
+.endm
+.macro GOTO_OPCODE_BASE base,reg
+ add \reg, \base, \reg, lsl #${handler_size_bits}
+ br \reg
+.endm
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ */
+.macro GET_VREG reg, vreg
+ ldr \reg, [xFP, \vreg, uxtw #2]
+.endm
+.macro SET_VREG reg, vreg
+ str \reg, [xFP, \vreg, uxtw #2]
+ str wzr, [xREFS, \vreg, uxtw #2]
+.endm
+.macro SET_VREG_OBJECT reg, vreg, tmpreg
+ str \reg, [xFP, \vreg, uxtw #2]
+ str \reg, [xREFS, \vreg, uxtw #2]
+.endm
+
+/*
+ * Get/set the 64-bit value from a Dalvik register.
+ * TUNING: can we do better here?
+ */
+.macro GET_VREG_WIDE reg, vreg
+ add ip2, xFP, \vreg, lsl #2
+ ldr \reg, [ip2]
+.endm
+.macro SET_VREG_WIDE reg, vreg
+ add ip2, xFP, \vreg, lsl #2
+ str \reg, [ip2]
+ add ip2, xREFS, \vreg, lsl #2
+ str xzr, [ip2]
+.endm
+
+/*
+ * Get the 32-bit value from a Dalvik register and sign-extend to 64-bit.
+ * Used to avoid an extra instruction in int-to-long.
+ */
+.macro GET_VREG_S reg, vreg
+ ldrsw \reg, [xFP, \vreg, uxtw #2]
+.endm
+
+/*
+ * 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 */
+.endm
+
+/*
+ * Refresh handler table.
+ */
+.macro REFRESH_IBASE
+ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
+.endm
+
+/*
+ * Save two registers to the stack.
+ */
+.macro SAVE_TWO_REGS reg1, reg2, offset
+ stp \reg1, \reg2, [sp, #(\offset)]
+ .cfi_rel_offset \reg1, (\offset)
+ .cfi_rel_offset \reg2, (\offset) + 8
+.endm
+
+/*
+ * Restore two registers from the stack.
+ */
+.macro RESTORE_TWO_REGS reg1, reg2, offset
+ ldp \reg1, \reg2, [sp, #(\offset)]
+ .cfi_restore \reg1
+ .cfi_restore \reg2
+.endm
+
+/*
+ * Increase frame size and save two registers to the bottom of the stack.
+ */
+.macro SAVE_TWO_REGS_INCREASE_FRAME reg1, reg2, frame_adjustment
+ stp \reg1, \reg2, [sp, #-(\frame_adjustment)]!
+ .cfi_adjust_cfa_offset (\frame_adjustment)
+ .cfi_rel_offset \reg1, 0
+ .cfi_rel_offset \reg2, 8
+.endm
+
+/*
+ * Restore two registers from the bottom of the stack and decrease frame size.
+ */
+.macro RESTORE_TWO_REGS_DECREASE_FRAME reg1, reg2, frame_adjustment
+ ldp \reg1, \reg2, [sp], #(\frame_adjustment)
+ .cfi_restore \reg1
+ .cfi_restore \reg2
+ .cfi_adjust_cfa_offset -(\frame_adjustment)
+.endm
+
+/*
+ * cfi support macros.
+ */
+.macro ENTRY name
+ .type \name, #function
+ .hidden \name // Hide this as a global symbol, so we do not incur plt calls.
+ .global \name
+ /* Cache alignment for function entry */
+ .balign 16
+\name:
+ .cfi_startproc
+.endm
+
+.macro END name
+ .cfi_endproc
+ .size \name, .-\name
+.endm
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ .text
+
+/*
+ * Interpreter entry point.
+ * On entry:
+ * x0 Thread* self/
+ * x1 insns_
+ * x2 ShadowFrame
+ * x3 JValue* result_register
+ *
+ */
+ENTRY ExecuteMterpImpl
+ SAVE_TWO_REGS_INCREASE_FRAME xPROFILE, x27, 80
+ SAVE_TWO_REGS xIBASE, xREFS, 16
+ SAVE_TWO_REGS xSELF, xINST, 32
+ SAVE_TWO_REGS xPC, xFP, 48
+ SAVE_TWO_REGS fp, lr, 64
+ add fp, sp, #64
+
+ /* Remember the return register */
+ str x3, [x2, #SHADOWFRAME_RESULT_REGISTER_OFFSET]
+
+ /* Remember the dex instruction pointer */
+ str x1, [x2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET]
+
+ /* set up "named" registers */
+ 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
+ ldr w0, [x2, #SHADOWFRAME_DEX_PC_OFFSET] // Get starting dex_pc.
+ add xPC, x1, w0, lsl #1 // Create direct pointer to 1st dex opcode
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+ EXPORT_PC
+
+ /* Starting ibase */
+ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
+
+ /* Set up for backwards branches & osr profiling */
+ ldr x0, [xFP, #OFF_FP_METHOD]
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xSELF
+ bl MterpSetUpHotnessCountdown
+ mov wPROFILE, w0 // Starting hotness countdown to xPROFILE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST // load wINST from rPC
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Note that the call to MterpCheckBefore is done as a tail call.
+ */
+ .extern MterpCheckBefore
+ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh IBASE.
+ adr lr, artMterpAsmInstructionStart + (${opnum} * 128) // Addr of primary handler.
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xPC
+ b MterpCheckBefore // (self, shadow_frame, dex_pc_ptr) Note: tail call.
+
+%def close_cfi():
+// Close out the cfi info. We're treating mterp as a single function.
+
+END ExecuteMterpImpl
+
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ b MterpFallback
+
+
+%def footer():
+/*
+ * ===========================================================================
+ * Common subroutines and data
+ * ===========================================================================
+ */
+
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+common_errDivideByZero:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogDivideByZeroException
+#endif
+ b MterpCommonFallback
+
+common_errArrayIndex:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogArrayIndexException
+#endif
+ b MterpCommonFallback
+
+common_errNegativeArraySize:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNegativeArraySizeException
+#endif
+ b MterpCommonFallback
+
+common_errNoSuchMethod:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNoSuchMethodException
+#endif
+ b MterpCommonFallback
+
+common_errNullObject:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogNullObjectException
+#endif
+ b MterpCommonFallback
+
+common_exceptionThrown:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogExceptionThrownException
+#endif
+ b MterpCommonFallback
+
+MterpSuspendFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ ldr x2, [xSELF, #THREAD_FLAGS_OFFSET]
+ bl MterpLogSuspendFallback
+#endif
+ b MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ ldr x0, [xSELF, #THREAD_EXCEPTION_OFFSET]
+ cbz x0, MterpFallback // If not, fall back to reference interpreter.
+ /* intentional fallthrough - handle pending exception. */
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+MterpException:
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpHandleException // (self, shadow_frame)
+ cbz w0, MterpExceptionReturn // no local catch, back to caller.
+ ldr x0, [xFP, #OFF_FP_DEX_INSTRUCTIONS]
+ ldr w1, [xFP, #OFF_FP_DEX_PC]
+ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
+ add xPC, x0, x1, lsl #1 // generate new dex_pc_ptr
+ /* Do we need to switch interpreters? */
+ bl MterpShouldSwitchInterpreters
+ cbnz w0, MterpFallback
+ /* resume execution at catch block */
+ EXPORT_PC
+ FETCH_INST
+ GET_INST_OPCODE ip
+ GOTO_OPCODE ip
+ /* NOTE: no fallthrough */
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * wINST <= signed offset
+ * wPROFILE <= signed hotness countdown (expanded to 32 bits)
+ * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ *
+ */
+MterpCommonTakenBranchNoFlags:
+ cmp wINST, #0
+ b.gt .L_forward_branch // don't add forward branches to hotness
+ tbnz wPROFILE, #31, .L_no_count_backwards // go if negative
+ subs wPROFILE, wPROFILE, #1 // countdown
+ b.eq .L_add_batch // counted down to zero - report
+.L_resume_backward_branch:
+ ldr lr, [xSELF, #THREAD_FLAGS_OFFSET]
+ add w2, wINST, wINST // w2<- byte offset
+ FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
+ REFRESH_IBASE
+ ands lr, lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne .L_suspend_request_pending
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+.L_suspend_request_pending:
+ EXPORT_PC
+ mov x0, xSELF
+ bl MterpSuspendCheck // (self)
+ cbnz x0, MterpFallback
+ REFRESH_IBASE // might have changed during suspend
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+.L_no_count_backwards:
+ cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
+ b.ne .L_resume_backward_branch
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xINST
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
+ cbnz x0, MterpOnStackReplacement
+ b .L_resume_backward_branch
+
+.L_forward_branch:
+ cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
+ b.eq .L_check_osr_forward
+.L_resume_forward_branch:
+ add w2, wINST, wINST // w2<- byte offset
+ FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+.L_check_osr_forward:
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xINST
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
+ cbnz x0, MterpOnStackReplacement
+ b .L_resume_forward_branch
+
+.L_add_batch:
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
+ ldr x0, [xFP, #OFF_FP_METHOD]
+ mov x2, xSELF
+ bl MterpAddHotnessBatch // (method, shadow_frame, self)
+ mov wPROFILE, w0 // restore new hotness countdown to wPROFILE
+ b .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, #2
+ EXPORT_PC
+ bl MterpMaybeDoOnStackReplacement // (self, shadow_frame, offset)
+ cbnz x0, MterpOnStackReplacement
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+/*
+ * Check for suspend check request. Assumes wINST already loaded, xPC advanced and
+ * still needs to get the opcode and branch to it, and flags are in lr.
+ */
+MterpCheckSuspendAndContinue:
+ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh xIBASE
+ ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ b.ne check1
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+check1:
+ EXPORT_PC
+ mov x0, xSELF
+ bl MterpSuspendCheck // (self)
+ cbnz x0, MterpFallback // Something in the environment changed, switch interpreters
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sxtw x2, wINST
+ bl MterpLogOSR
+#endif
+ mov x0, #1 // Signal normal return
+ b MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+MterpFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ bl MterpLogFallback
+#endif
+MterpCommonFallback:
+ mov x0, #0 // signal retry with reference interpreter.
+ b MterpDone
+
+/*
+ * We pushed some registers on the stack in ExecuteMterpImpl, then saved
+ * SP and LR. Here we restore SP, restore the registers, and then restore
+ * LR to PC.
+ *
+ * On entry:
+ * uint32_t* xFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ mov x0, #1 // signal return to caller.
+ b MterpDone
+MterpReturn:
+ ldr x2, [xFP, #OFF_FP_RESULT_REGISTER]
+ str x0, [x2]
+ mov x0, #1 // signal return to caller.
+MterpDone:
+/*
+ * At this point, we expect wPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending wPROFILE and the cached hotness counter). wPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ cmp wPROFILE, #0
+ bgt MterpProfileActive // if > 0, we may have some counts to report.
+ .cfi_remember_state
+ RESTORE_TWO_REGS fp, lr, 64
+ RESTORE_TWO_REGS xPC, xFP, 48
+ RESTORE_TWO_REGS xSELF, xINST, 32
+ RESTORE_TWO_REGS xIBASE, xREFS, 16
+ RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
+ ret
+ .cfi_restore_state // Reset unwind info so following code unwinds.
+ .cfi_def_cfa_offset 80 // workaround for clang bug: 31975598
+
+MterpProfileActive:
+ mov xINST, x0 // stash return value
+ /* Report cached hotness counts */
+ ldr x0, [xFP, #OFF_FP_METHOD]
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xSELF
+ strh wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
+ bl MterpAddHotnessBatch // (method, shadow_frame, self)
+ mov x0, xINST // restore return value
+ RESTORE_TWO_REGS fp, lr, 64
+ RESTORE_TWO_REGS xPC, xFP, 48
+ RESTORE_TWO_REGS xSELF, xINST, 32
+ RESTORE_TWO_REGS xIBASE, xREFS, 16
+ RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
+ ret
+
+
+%def instruction_end():
+
+ .type artMterpAsmInstructionEnd, #object
+ .hidden artMterpAsmInstructionEnd
+ .global artMterpAsmInstructionEnd
+artMterpAsmInstructionEnd:
+
+%def instruction_end_alt():
+
+ .type artMterpAsmAltInstructionEnd, #object
+ .hidden artMterpAsmAltInstructionEnd
+ .global artMterpAsmAltInstructionEnd
+artMterpAsmAltInstructionEnd:
+
+%def instruction_end_sister():
+
+ .type artMterpAsmSisterEnd, #object
+ .hidden artMterpAsmSisterEnd
+ .global artMterpAsmSisterEnd
+artMterpAsmSisterEnd:
+
+%def instruction_start():
+
+ .type artMterpAsmInstructionStart, #object
+ .hidden artMterpAsmInstructionStart
+ .global artMterpAsmInstructionStart
+artMterpAsmInstructionStart = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ .type artMterpAsmAltInstructionStart, #object
+ .hidden artMterpAsmAltInstructionStart
+ .global artMterpAsmAltInstructionStart
+artMterpAsmAltInstructionStart = .L_ALT_op_nop
+ .text
+
+%def instruction_start_sister():
+
+ .type artMterpAsmSisterStart, #object
+ .hidden artMterpAsmSisterStart
+ .global artMterpAsmSisterStart
+ .text
+ .balign 4
+artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/arm64/object.S b/runtime/interpreter/mterp/arm64/object.S
new file mode 100644
index 0000000..388aba5
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/object.S
@@ -0,0 +1,263 @@
+%def field(helper=""):
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl $helper
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_check_cast():
+ /*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class//BBBB */
+ EXPORT_PC
+ FETCH w0, 1 // w0<- BBBB
+ lsr w1, wINST, #8 // w1<- AA
+ VREG_INDEX_TO_ADDR x1, w1 // w1<- &object
+ ldr x2, [xFP, #OFF_FP_METHOD] // w2<- method
+ mov x3, xSELF // w3<- self
+ bl MterpCheckCast // (index, &obj, method, self)
+ PREFETCH_INST 2
+ cbnz w0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="ldrb")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="ldrsb")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="ldrh")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset//CCCC */
+ lsr w2, wINST, #12 // w2<- B
+ FETCH w1, 1 // w1<- field byte offset
+ EXPORT_PC
+ GET_VREG w0, w2 // w0<- object we're operating on
+ bl artIGetObjectFromMterp // (obj, offset)
+ ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
+ ubfx w2, wINST, #8, #4 // w2<- A
+ PREFETCH_INST 2
+ cbnz w3, MterpPossibleException // bail out
+ SET_VREG_OBJECT w0, w2 // fp[A]<- w0
+ ADVANCE 2 // advance rPC
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iget_quick(load="ldr", extend=""):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
+ /* op vA, vB, offset//CCCC */
+ lsr w2, wINST, #12 // w2<- B
+ FETCH w1, 1 // w1<- 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
+ $load w0, [x3, x1] // w0<- obj.field
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $extend
+ SET_VREG w0, w2 // fp[A]<- w0
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="ldrsh")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+ /* iget-wide-quick vA, vB, offset//CCCC */
+ lsr w2, wINST, #12 // w2<- B
+ 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
+ ldr x0, [x3, x4] // x0<- obj.field
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ SET_VREG_WIDE x0, w2
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_instance_of():
+ /*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class//CCCC */
+ EXPORT_PC
+ FETCH w0, 1 // w0<- CCCC
+ lsr w1, wINST, #12 // w1<- B
+ VREG_INDEX_TO_ADDR x1, w1 // w1<- &object
+ ldr x2, [xFP, #OFF_FP_METHOD] // w2<- method
+ mov x3, xSELF // w3<- self
+ bl MterpInstanceOf // (index, &obj, method, self)
+ ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
+ ubfx w2, wINST, #8, #4 // w2<- A
+ PREFETCH_INST 2
+ cbnz x1, MterpException
+ ADVANCE 2 // advance rPC
+ SET_VREG w0, w2 // vA<- w0
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(store="strb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(store="strb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(store="strh")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ EXPORT_PC
+ add x0, xFP, #OFF_FP_SHADOWFRAME
+ mov x1, xPC
+ mov w2, wINST
+ bl MterpIputObjectQuick
+ cbz w0, MterpException
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iput_quick(store="str"):
+ /* For: iput-quick, iput-object-quick */
+ /* op vA, vB, offset//CCCC */
+ lsr w2, wINST, #12 // w2<- B
+ FETCH w1, 1 // w1<- field byte offset
+ GET_VREG w3, w2 // w3<- fp[B], the object pointer
+ ubfx w2, wINST, #8, #4 // w2<- A
+ cbz w3, common_errNullObject // object was null
+ GET_VREG w0, w2 // w0<- fp[A]
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ $store w0, [x3, x1] // obj.field<- w0
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(store="strh")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset//CCCC */
+ lsr w2, wINST, #12 // w2<- B
+ FETCH w3, 1 // w3<- field byte offset
+ GET_VREG w2, w2 // w2<- fp[B], the object pointer
+ ubfx w0, wINST, #8, #4 // w0<- A
+ cbz w2, common_errNullObject // object was null
+ GET_VREG_WIDE x0, w0 // x0<- fp[A]
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ str x0, [x2, x3] // obj.field<- x0
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_new_instance():
+ /*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class//BBBB */
+ EXPORT_PC
+ add x0, xFP, #OFF_FP_SHADOWFRAME
+ mov x1, xSELF
+ mov w2, wINST
+ bl MterpNewInstance // (shadow_frame, self, inst_data)
+ cbz w0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/arm64/op_add_double.S b/runtime/interpreter/mterp/arm64/op_add_double.S
deleted file mode 100644
index 8d31342..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% binopWide(instr="fadd d0, d1, d2", result="d0", r1="d1", r2="d2")
diff --git a/runtime/interpreter/mterp/arm64/op_add_double_2addr.S b/runtime/interpreter/mterp/arm64/op_add_double_2addr.S
deleted file mode 100644
index 88c1d5e..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% binopWide2addr(instr="fadd d0, d0, d1", r0="d0", r1="d1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_float.S b/runtime/interpreter/mterp/arm64/op_add_float.S
deleted file mode 100644
index 388732e..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% fbinop(instr="fadd s0, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_float_2addr.S b/runtime/interpreter/mterp/arm64/op_add_float_2addr.S
deleted file mode 100644
index 061c9d5..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% fbinop2addr(instr="fadd s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_int.S b/runtime/interpreter/mterp/arm64/op_add_int.S
deleted file mode 100644
index 99953ee..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="add w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_int_2addr.S b/runtime/interpreter/mterp/arm64/op_add_int_2addr.S
deleted file mode 100644
index d61fcce..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="add w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_int_lit16.S b/runtime/interpreter/mterp/arm64/op_add_int_lit16.S
deleted file mode 100644
index 37bf2e8..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="add w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_add_int_lit8.S b/runtime/interpreter/mterp/arm64/op_add_int_lit8.S
deleted file mode 100644
index f4cab96..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(extract="", instr="add w0, w0, w3, asr #8")
diff --git a/runtime/interpreter/mterp/arm64/op_add_long.S b/runtime/interpreter/mterp/arm64/op_add_long.S
deleted file mode 100644
index 0ac3246..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long():
-% binopWide(instr="add x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_add_long_2addr.S b/runtime/interpreter/mterp/arm64/op_add_long_2addr.S
deleted file mode 100644
index 03987eb..0000000
--- a/runtime/interpreter/mterp/arm64/op_add_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long_2addr():
-% binopWide2addr(instr="add x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/op_aget.S b/runtime/interpreter/mterp/arm64/op_aget.S
deleted file mode 100644
index edc62f5..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
- * instructions. We use a pair of FETCH_Bs instead.
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short
- *
- * NOTE: assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B w2, 1, 0 // w2<- BB
- lsr w9, wINST, #8 // w9<- AA
- FETCH_B w3, 1, 1 // w3<- CC
- GET_VREG w0, w2 // w0<- vBB (array object)
- GET_VREG w1, w3 // w1<- vCC (requested index)
- cbz x0, common_errNullObject // bail if null array object.
- ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- arrayObj->length
- 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
- $load w2, [x0, #$data_offset] // w2<- vBB[vCC]
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG w2, w9 // vAA<- w2
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_aget_boolean.S b/runtime/interpreter/mterp/arm64/op_aget_boolean.S
deleted file mode 100644
index d6e0a1b..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aget_byte.S b/runtime/interpreter/mterp/arm64/op_aget_byte.S
deleted file mode 100644
index 6c9f1b7..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aget_char.S b/runtime/interpreter/mterp/arm64/op_aget_char.S
deleted file mode 100644
index c5812e3..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aget_object.S b/runtime/interpreter/mterp/arm64/op_aget_object.S
deleted file mode 100644
index 0c5d2c3..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_object.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_aget_object():
- /*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- FETCH_B w2, 1, 0 // w2<- BB
- FETCH_B w3, 1, 1 // w3<- CC
- EXPORT_PC
- GET_VREG w0, w2 // w0<- vBB (array object)
- GET_VREG w1, w3 // w1<- vCC (requested index)
- bl artAGetObjectFromMterp // (array, index)
- ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w9<- AA
- PREFETCH_INST 2
- cbnz w1, MterpException
- SET_VREG_OBJECT w0, w2
- ADVANCE 2
- GET_INST_OPCODE ip
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_aget_short.S b/runtime/interpreter/mterp/arm64/op_aget_short.S
deleted file mode 100644
index 9727560..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aget_wide.S b/runtime/interpreter/mterp/arm64/op_aget_wide.S
deleted file mode 100644
index e9bccd6..0000000
--- a/runtime/interpreter/mterp/arm64/op_aget_wide.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aget_wide():
- /*
- * Array get, 64 bits. vAA <- vBB[vCC].
- *
- */
- /* aget-wide vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w4, wINST, #8 // w4<- AA
- and w2, w0, #255 // w2<- BB
- lsr w3, w0, #8 // w3<- CC
- GET_VREG w0, w2 // w0<- vBB (array object)
- 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
- cmp w1, w3 // compare unsigned index, length
- bcs common_errArrayIndex // index >= length, bail
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- ldr x2, [x0, #MIRROR_WIDE_ARRAY_DATA_OFFSET] // x2<- vBB[vCC]
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE x2, w4
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_and_int.S b/runtime/interpreter/mterp/arm64/op_and_int.S
deleted file mode 100644
index 364e615..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="and w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_and_int_2addr.S b/runtime/interpreter/mterp/arm64/op_and_int_2addr.S
deleted file mode 100644
index 98a5c5d..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="and w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_and_int_lit16.S b/runtime/interpreter/mterp/arm64/op_and_int_lit16.S
deleted file mode 100644
index add2ecc..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="and w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_and_int_lit8.S b/runtime/interpreter/mterp/arm64/op_and_int_lit8.S
deleted file mode 100644
index bf68c2a..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(extract="", instr="and w0, w0, w3, asr #8")
diff --git a/runtime/interpreter/mterp/arm64/op_and_long.S b/runtime/interpreter/mterp/arm64/op_and_long.S
deleted file mode 100644
index aff5ead..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(instr="and x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_and_long_2addr.S b/runtime/interpreter/mterp/arm64/op_and_long_2addr.S
deleted file mode 100644
index ba71e5c..0000000
--- a/runtime/interpreter/mterp/arm64/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(instr="and x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/op_aput.S b/runtime/interpreter/mterp/arm64/op_aput.S
deleted file mode 100644
index 85dd556..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
- * instructions. We use a pair of FETCH_Bs instead.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short
- *
- * NOTE: this assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B w2, 1, 0 // w2<- BB
- lsr w9, wINST, #8 // w9<- AA
- FETCH_B w3, 1, 1 // w3<- CC
- GET_VREG w0, w2 // w0<- vBB (array object)
- 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
- cmp w1, w3 // compare unsigned index, length
- bcs common_errArrayIndex // index >= length, bail
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_VREG w2, w9 // w2<- vAA
- GET_INST_OPCODE ip // extract opcode from rINST
- $store w2, [x0, #$data_offset] // vBB[vCC]<- w2
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_aput_boolean.S b/runtime/interpreter/mterp/arm64/op_aput_boolean.S
deleted file mode 100644
index 467cc4b..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aput_byte.S b/runtime/interpreter/mterp/arm64/op_aput_byte.S
deleted file mode 100644
index 2b4c0ba..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aput_char.S b/runtime/interpreter/mterp/arm64/op_aput_char.S
deleted file mode 100644
index cb7dcba..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aput_object.S b/runtime/interpreter/mterp/arm64/op_aput_object.S
deleted file mode 100644
index 4d1ee65..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_object.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_aput_object():
- /*
- * Store an object into an array. vBB[vCC] <- vAA.
- */
- /* op vAA, vBB, vCC */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- bl MterpAputObject
- cbz w0, MterpPossibleException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_aput_short.S b/runtime/interpreter/mterp/arm64/op_aput_short.S
deleted file mode 100644
index f624163..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/arm64/op_aput_wide.S b/runtime/interpreter/mterp/arm64/op_aput_wide.S
deleted file mode 100644
index 8498783..0000000
--- a/runtime/interpreter/mterp/arm64/op_aput_wide.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aput_wide():
- /*
- * Array put, 64 bits. vBB[vCC] <- vAA.
- *
- */
- /* aput-wide vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w4, wINST, #8 // w4<- AA
- and w2, w0, #255 // w2<- BB
- lsr w3, w0, #8 // w3<- CC
- GET_VREG w0, w2 // w0<- vBB (array object)
- 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
- cmp w1, w3 // compare unsigned index, length
- bcs common_errArrayIndex // index >= length, bail
- GET_VREG_WIDE x1, w4
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- str x1, [x0, #MIRROR_WIDE_ARRAY_DATA_OFFSET]
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_array_length.S b/runtime/interpreter/mterp/arm64/op_array_length.S
deleted file mode 100644
index 26979b8..0000000
--- a/runtime/interpreter/mterp/arm64/op_array_length.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_array_length():
- /*
- * Return the length of an array.
- */
- lsr w1, wINST, #12 // w1<- B
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w0, w1 // w0<- vB (object ref)
- cbz w0, common_errNullObject // yup, fail
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- ldr w3, [x0, #MIRROR_ARRAY_LENGTH_OFFSET] // w3<- array length
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG w3, w2 // vB<- length
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_check_cast.S b/runtime/interpreter/mterp/arm64/op_check_cast.S
deleted file mode 100644
index 359c860..0000000
--- a/runtime/interpreter/mterp/arm64/op_check_cast.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_check_cast():
- /*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class//BBBB */
- EXPORT_PC
- FETCH w0, 1 // w0<- BBBB
- lsr w1, wINST, #8 // w1<- AA
- VREG_INDEX_TO_ADDR x1, w1 // w1<- &object
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- method
- mov x3, xSELF // w3<- self
- bl MterpCheckCast // (index, &obj, method, self)
- PREFETCH_INST 2
- cbnz w0, MterpPossibleException
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_cmp_long.S b/runtime/interpreter/mterp/arm64/op_cmp_long.S
deleted file mode 100644
index 636262c..0000000
--- a/runtime/interpreter/mterp/arm64/op_cmp_long.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_cmp_long():
- FETCH w0, 1 // w0<- CCBB
- lsr w4, wINST, #8 // w4<- AA
- and w2, w0, #255 // w2<- BB
- lsr w3, w0, #8 // w3<- CC
- GET_VREG_WIDE x1, w2
- GET_VREG_WIDE x2, w3
- cmp x1, x2
- cset w0, ne
- cneg w0, w0, lt
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG w0, w4
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_cmpg_double.S b/runtime/interpreter/mterp/arm64/op_cmpg_double.S
deleted file mode 100644
index 4527873..0000000
--- a/runtime/interpreter/mterp/arm64/op_cmpg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_double():
-% fcmp(wide="_WIDE", r1="d1", r2="d2", cond="cc")
diff --git a/runtime/interpreter/mterp/arm64/op_cmpg_float.S b/runtime/interpreter/mterp/arm64/op_cmpg_float.S
deleted file mode 100644
index 395d186..0000000
--- a/runtime/interpreter/mterp/arm64/op_cmpg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_float():
-% fcmp(wide="", r1="s1", r2="s2", cond="cc")
diff --git a/runtime/interpreter/mterp/arm64/op_cmpl_double.S b/runtime/interpreter/mterp/arm64/op_cmpl_double.S
deleted file mode 100644
index 67b69c8..0000000
--- a/runtime/interpreter/mterp/arm64/op_cmpl_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_double():
-% fcmp(wide="_WIDE", r1="d1", r2="d2", cond="lt")
diff --git a/runtime/interpreter/mterp/arm64/op_cmpl_float.S b/runtime/interpreter/mterp/arm64/op_cmpl_float.S
deleted file mode 100644
index 7574f4c..0000000
--- a/runtime/interpreter/mterp/arm64/op_cmpl_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_float():
-% fcmp(wide="", r1="s1", r2="s2", cond="lt")
diff --git a/runtime/interpreter/mterp/arm64/op_const.S b/runtime/interpreter/mterp/arm64/op_const.S
deleted file mode 100644
index 493611e..0000000
--- a/runtime/interpreter/mterp/arm64/op_const.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const():
- /* const vAA, #+BBBBbbbb */
- lsr w3, wINST, #8 // w3<- AA
- FETCH w0, 1 // w0<- bbbb (low
- FETCH w1, 2 // w1<- BBBB (high
- FETCH_ADVANCE_INST 3 // advance rPC, load wINST
- orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG w0, w3 // vAA<- w0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_16.S b/runtime/interpreter/mterp/arm64/op_const_16.S
deleted file mode 100644
index 75e6936..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, #+BBBB */
- FETCH_S w0, 1 // w0<- ssssBBBB (sign-extended)
- lsr w3, wINST, #8 // w3<- AA
- FETCH_ADVANCE_INST 2 // advance xPC, load wINST
- SET_VREG w0, w3 // vAA<- w0
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_4.S b/runtime/interpreter/mterp/arm64/op_const_4.S
deleted file mode 100644
index e6281ed..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_4.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_4():
- /* const/4 vA, #+B */
- sbfx w1, wINST, #12, #4 // w1<- sssssssB
- ubfx w0, wINST, #8, #4 // w0<- A
- FETCH_ADVANCE_INST 1 // advance xPC, load wINST
- GET_INST_OPCODE ip // ip<- opcode from xINST
- SET_VREG w1, w0 // fp[A]<- w1
- GOTO_OPCODE ip // execute next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_class.S b/runtime/interpreter/mterp/arm64/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/arm64/op_const_high16.S b/runtime/interpreter/mterp/arm64/op_const_high16.S
deleted file mode 100644
index 8a8558f..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, #+BBBB0000 */
- FETCH w0, 1 // r0<- 0000BBBB (zero-extended)
- lsr w3, wINST, #8 // r3<- AA
- lsl w0, w0, #16 // r0<- BBBB0000
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- SET_VREG w0, w3 // vAA<- r0
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_method_handle.S b/runtime/interpreter/mterp/arm64/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/arm64/op_const_method_type.S b/runtime/interpreter/mterp/arm64/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/arm64/op_const_string.S b/runtime/interpreter/mterp/arm64/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/arm64/op_const_string_jumbo.S b/runtime/interpreter/mterp/arm64/op_const_string_jumbo.S
deleted file mode 100644
index 1a78bcb..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_string_jumbo.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, String//BBBBBBBB */
- EXPORT_PC
- FETCH w0, 1 // w0<- bbbb (low
- FETCH w2, 2 // w2<- BBBB (high
- lsr w1, wINST, #8 // w1<- AA
- orr w0, w0, w2, lsl #16 // w1<- BBBBbbbb
- add x2, xFP, #OFF_FP_SHADOWFRAME
- mov x3, xSELF
- bl MterpConstString // (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 3 // advance rPC
- cbnz w0, MterpPossibleException // let reference interpreter deal with it.
- ADVANCE 3 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_wide.S b/runtime/interpreter/mterp/arm64/op_const_wide.S
deleted file mode 100644
index 6d3be6b..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_wide.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
- FETCH w0, 1 // w0<- bbbb (low)
- FETCH w1, 2 // w1<- BBBB (low middle)
- FETCH w2, 3 // w2<- hhhh (high middle)
- FETCH w3, 4 // w3<- HHHH (high)
- lsr w4, wINST, #8 // r4<- AA
- FETCH_ADVANCE_INST 5 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
- orr x0, x0, x2, lsl #32 // w0<- hhhhBBBBbbbb
- orr x0, x0, x3, lsl #48 // w0<- HHHHhhhhBBBBbbbb
- SET_VREG_WIDE x0, w4
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_const_wide_16.S b/runtime/interpreter/mterp/arm64/op_const_wide_16.S
deleted file mode 100644
index 04615e1..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_wide_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, #+BBBB */
- FETCH_S x0, 1 // x0<- ssssssssssssBBBB (sign-extended)
- lsr w3, wINST, #8 // w3<- AA
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- 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
deleted file mode 100644
index 627ddea..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_wide_32.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, #+BBBBbbbb */
- FETCH w0, 1 // x0<- 000000000000bbbb (low)
- lsr w3, wINST, #8 // w3<- AA
- FETCH_S x2, 2 // x2<- ssssssssssssBBBB (high)
- FETCH_ADVANCE_INST 3 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- 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_const_wide_high16.S b/runtime/interpreter/mterp/arm64/op_const_wide_high16.S
deleted file mode 100644
index d51d25f..0000000
--- a/runtime/interpreter/mterp/arm64/op_const_wide_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, #+BBBB000000000000 */
- FETCH w0, 1 // w0<- 0000BBBB (zero-extended)
- lsr w1, wINST, #8 // w1<- AA
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- lsl x0, x0, #48
- SET_VREG_WIDE x0, w1
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_div_double.S b/runtime/interpreter/mterp/arm64/op_div_double.S
deleted file mode 100644
index ec5b1f5..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% binopWide(instr="fdiv d0, d1, d2", result="d0", r1="d1", r2="d2")
diff --git a/runtime/interpreter/mterp/arm64/op_div_double_2addr.S b/runtime/interpreter/mterp/arm64/op_div_double_2addr.S
deleted file mode 100644
index e2781b8..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% binopWide2addr(instr="fdiv d0, d0, d1", r0="d0", r1="d1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_float.S b/runtime/interpreter/mterp/arm64/op_div_float.S
deleted file mode 100644
index f0e72c4..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% fbinop(instr="fdiv s0, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_float_2addr.S b/runtime/interpreter/mterp/arm64/op_div_float_2addr.S
deleted file mode 100644
index aa73950..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% fbinop2addr(instr="fdiv s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_int.S b/runtime/interpreter/mterp/arm64/op_div_int.S
deleted file mode 100644
index 6f4cbf3..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int():
-% binop(instr="sdiv w0, w0, w1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_int_2addr.S b/runtime/interpreter/mterp/arm64/op_div_int_2addr.S
deleted file mode 100644
index eb01066..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_2addr():
-% binop2addr(instr="sdiv w0, w0, w1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_int_lit16.S b/runtime/interpreter/mterp/arm64/op_div_int_lit16.S
deleted file mode 100644
index c5cdb96..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit16():
-% binopLit16(instr="sdiv w0, w0, w1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_int_lit8.S b/runtime/interpreter/mterp/arm64/op_div_int_lit8.S
deleted file mode 100644
index 3842cd9..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit8():
-% binopLit8(instr="sdiv w0, w0, w1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_long.S b/runtime/interpreter/mterp/arm64/op_div_long.S
deleted file mode 100644
index 696a91f..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long():
-% binopWide(instr="sdiv x0, x1, x2", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_div_long_2addr.S b/runtime/interpreter/mterp/arm64/op_div_long_2addr.S
deleted file mode 100644
index cac878c..0000000
--- a/runtime/interpreter/mterp/arm64/op_div_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long_2addr():
-% binopWide2addr(instr="sdiv x0, x0, x1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_double_to_float.S b/runtime/interpreter/mterp/arm64/op_double_to_float.S
deleted file mode 100644
index 292dcc7..0000000
--- a/runtime/interpreter/mterp/arm64/op_double_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_float():
-% funopNarrower(instr="fcvt s0, d0", srcreg="d0", tgtreg="s0")
diff --git a/runtime/interpreter/mterp/arm64/op_double_to_int.S b/runtime/interpreter/mterp/arm64/op_double_to_int.S
deleted file mode 100644
index 640e6da..0000000
--- a/runtime/interpreter/mterp/arm64/op_double_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_int():
-% funopNarrower(instr="fcvtzs w0, d0", srcreg="d0", tgtreg="w0")
diff --git a/runtime/interpreter/mterp/arm64/op_double_to_long.S b/runtime/interpreter/mterp/arm64/op_double_to_long.S
deleted file mode 100644
index 99c15eb..0000000
--- a/runtime/interpreter/mterp/arm64/op_double_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_long():
-% funopWide(instr="fcvtzs x0, d0", srcreg="d0", tgtreg="x0")
diff --git a/runtime/interpreter/mterp/arm64/op_fill_array_data.S b/runtime/interpreter/mterp/arm64/op_fill_array_data.S
deleted file mode 100644
index 2ae444c..0000000
--- a/runtime/interpreter/mterp/arm64/op_fill_array_data.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- EXPORT_PC
- FETCH w0, 1 // x0<- 000000000000bbbb (lo)
- FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
- lsr w3, wINST, #8 // w3<- AA
- orr x1, x0, x1, lsl #16 // x1<- ssssssssBBBBbbbb
- GET_VREG w0, w3 // w0<- vAA (array object)
- add x1, xPC, x1, lsl #1 // x1<- PC + ssssssssBBBBbbbb*2 (array data off.)
- bl MterpFillArrayData // (obj, payload)
- cbz w0, MterpPossibleException // exception?
- FETCH_ADVANCE_INST 3 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_filled_new_array.S b/runtime/interpreter/mterp/arm64/op_filled_new_array.S
deleted file mode 100644
index 2be627c..0000000
--- a/runtime/interpreter/mterp/arm64/op_filled_new_array.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
- /*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class//CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type//BBBB */
- .extern $helper
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov x2, xSELF
- bl $helper
- cbz w0, MterpPossibleException
- FETCH_ADVANCE_INST 3 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_filled_new_array_range.S b/runtime/interpreter/mterp/arm64/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/arm64/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/arm64/op_float_to_double.S b/runtime/interpreter/mterp/arm64/op_float_to_double.S
deleted file mode 100644
index c3dff39..0000000
--- a/runtime/interpreter/mterp/arm64/op_float_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_double():
-% funopWider(instr="fcvt d0, s0", srcreg="s0", tgtreg="d0")
diff --git a/runtime/interpreter/mterp/arm64/op_float_to_int.S b/runtime/interpreter/mterp/arm64/op_float_to_int.S
deleted file mode 100644
index ed784e2..0000000
--- a/runtime/interpreter/mterp/arm64/op_float_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_int():
-% funopNarrow(instr="fcvtzs w0, s0", srcreg="s0", tgtreg="w0")
diff --git a/runtime/interpreter/mterp/arm64/op_float_to_long.S b/runtime/interpreter/mterp/arm64/op_float_to_long.S
deleted file mode 100644
index 1491249..0000000
--- a/runtime/interpreter/mterp/arm64/op_float_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_long():
-% funopWider(instr="fcvtzs x0, s0", srcreg="s0", tgtreg="x0")
diff --git a/runtime/interpreter/mterp/arm64/op_goto.S b/runtime/interpreter/mterp/arm64/op_goto.S
deleted file mode 100644
index 722eec6..0000000
--- a/runtime/interpreter/mterp/arm64/op_goto.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto():
- /*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- sbfx wINST, wINST, #8, #8 // wINST<- ssssssAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm64/op_goto_16.S b/runtime/interpreter/mterp/arm64/op_goto_16.S
deleted file mode 100644
index b5cfa71..0000000
--- a/runtime/interpreter/mterp/arm64/op_goto_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto_16():
- /*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm64/op_goto_32.S b/runtime/interpreter/mterp/arm64/op_goto_32.S
deleted file mode 100644
index 3843ba2..0000000
--- a/runtime/interpreter/mterp/arm64/op_goto_32.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_goto_32():
- /*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Unlike most opcodes, this one is allowed to branch to itself, so
- * our "backward branch" test must be "<=0" instead of "<0". Because
- * we need the V bit set, we'll use an adds to convert from Dalvik
- * offset to byte offset.
- */
- /* goto/32 +AAAAAAAA */
- FETCH w0, 1 // w0<- aaaa (lo)
- FETCH w1, 2 // w1<- AAAA (hi)
- orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm64/op_if_eq.S b/runtime/interpreter/mterp/arm64/op_if_eq.S
deleted file mode 100644
index da58674..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(condition="eq")
diff --git a/runtime/interpreter/mterp/arm64/op_if_eqz.S b/runtime/interpreter/mterp/arm64/op_if_eqz.S
deleted file mode 100644
index 8241db8..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(compare="0", branch="cbz w2,")
diff --git a/runtime/interpreter/mterp/arm64/op_if_ge.S b/runtime/interpreter/mterp/arm64/op_if_ge.S
deleted file mode 100644
index 5b6ed2f..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(condition="ge")
diff --git a/runtime/interpreter/mterp/arm64/op_if_gez.S b/runtime/interpreter/mterp/arm64/op_if_gez.S
deleted file mode 100644
index f7903b8..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(compare="0", branch="tbz w2, #31,")
diff --git a/runtime/interpreter/mterp/arm64/op_if_gt.S b/runtime/interpreter/mterp/arm64/op_if_gt.S
deleted file mode 100644
index 201decf..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(condition="gt")
diff --git a/runtime/interpreter/mterp/arm64/op_if_gtz.S b/runtime/interpreter/mterp/arm64/op_if_gtz.S
deleted file mode 100644
index e0663a0..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(branch="b.gt")
diff --git a/runtime/interpreter/mterp/arm64/op_if_le.S b/runtime/interpreter/mterp/arm64/op_if_le.S
deleted file mode 100644
index e6024f2..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(condition="le")
diff --git a/runtime/interpreter/mterp/arm64/op_if_lez.S b/runtime/interpreter/mterp/arm64/op_if_lez.S
deleted file mode 100644
index 7ec4a9e..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(branch="b.le")
diff --git a/runtime/interpreter/mterp/arm64/op_if_lt.S b/runtime/interpreter/mterp/arm64/op_if_lt.S
deleted file mode 100644
index 4ef22fd..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(condition="lt")
diff --git a/runtime/interpreter/mterp/arm64/op_if_ltz.S b/runtime/interpreter/mterp/arm64/op_if_ltz.S
deleted file mode 100644
index a9f04ee..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(compare="0", branch="tbnz w2, #31,")
diff --git a/runtime/interpreter/mterp/arm64/op_if_ne.S b/runtime/interpreter/mterp/arm64/op_if_ne.S
deleted file mode 100644
index ec3a688..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(condition="ne")
diff --git a/runtime/interpreter/mterp/arm64/op_if_nez.S b/runtime/interpreter/mterp/arm64/op_if_nez.S
deleted file mode 100644
index c4bb3b3..0000000
--- a/runtime/interpreter/mterp/arm64/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(compare="0", branch="cbnz w2,")
diff --git a/runtime/interpreter/mterp/arm64/op_iget.S b/runtime/interpreter/mterp/arm64/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm64/op_iget_boolean.S b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_boolean_quick.S b/runtime/interpreter/mterp/arm64/op_iget_boolean_quick.S
deleted file mode 100644
index 7ac9fce..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="ldrb")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_byte.S b/runtime/interpreter/mterp/arm64/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_byte_quick.S b/runtime/interpreter/mterp/arm64/op_iget_byte_quick.S
deleted file mode 100644
index bbccaff..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="ldrsb")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_char.S b/runtime/interpreter/mterp/arm64/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_char_quick.S b/runtime/interpreter/mterp/arm64/op_iget_char_quick.S
deleted file mode 100644
index 71a9276..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="ldrh")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_object.S b/runtime/interpreter/mterp/arm64/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_object_quick.S b/runtime/interpreter/mterp/arm64/op_iget_object_quick.S
deleted file mode 100644
index f55b08f..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_object_quick.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset//CCCC */
- lsr w2, wINST, #12 // w2<- B
- FETCH w1, 1 // w1<- field byte offset
- EXPORT_PC
- GET_VREG w0, w2 // w0<- object we're operating on
- bl artIGetObjectFromMterp // (obj, offset)
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz w3, MterpPossibleException // bail out
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- 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
deleted file mode 100644
index 641bfab..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iget_quick(load="ldr", extend=""):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
- /* op vA, vB, offset//CCCC */
- lsr w2, wINST, #12 // w2<- B
- FETCH w1, 1 // w1<- 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
- $load w0, [x3, x1] // w0<- obj.field
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $extend
- SET_VREG w0, w2 // fp[A]<- w0
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iget_short.S b/runtime/interpreter/mterp/arm64/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_short_quick.S b/runtime/interpreter/mterp/arm64/op_iget_short_quick.S
deleted file mode 100644
index 5dbdc4f..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="ldrsh")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide.S b/runtime/interpreter/mterp/arm64/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S b/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S
deleted file mode 100644
index 9f7a61b..0000000
--- a/runtime/interpreter/mterp/arm64/op_iget_wide_quick.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_iget_wide_quick():
- /* iget-wide-quick vA, vB, offset//CCCC */
- lsr w2, wINST, #12 // w2<- B
- 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
- ldr x0, [x3, x4] // x0<- obj.field
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG_WIDE x0, w2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_instance_of.S b/runtime/interpreter/mterp/arm64/op_instance_of.S
deleted file mode 100644
index 9c337d1..0000000
--- a/runtime/interpreter/mterp/arm64/op_instance_of.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_instance_of():
- /*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class//CCCC */
- EXPORT_PC
- FETCH w0, 1 // w0<- CCCC
- lsr w1, wINST, #12 // w1<- B
- VREG_INDEX_TO_ADDR x1, w1 // w1<- &object
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- method
- mov x3, xSELF // w3<- self
- bl MterpInstanceOf // (index, &obj, method, self)
- ldr x1, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x1, MterpException
- ADVANCE 2 // advance rPC
- SET_VREG w0, w2 // vA<- w0
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_byte.S b/runtime/interpreter/mterp/arm64/op_int_to_byte.S
deleted file mode 100644
index 8174978..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="sxtb w0, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_char.S b/runtime/interpreter/mterp/arm64/op_int_to_char.S
deleted file mode 100644
index bbf3239..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(instr="uxth w0, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_double.S b/runtime/interpreter/mterp/arm64/op_int_to_double.S
deleted file mode 100644
index f2b9dc0..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_double():
-% funopWider(instr="scvtf d0, w0", srcreg="w0", tgtreg="d0")
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_float.S b/runtime/interpreter/mterp/arm64/op_int_to_float.S
deleted file mode 100644
index ffe873d..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_float():
-% funopNarrow(instr="scvtf s0, w0", srcreg="w0", tgtreg="s0")
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_long.S b/runtime/interpreter/mterp/arm64/op_int_to_long.S
deleted file mode 100644
index d7e5b46..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_long.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_int_to_long():
- /* int-to-long vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG_S x0, w3 // x0<- sign_extend(fp[B])
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE x0, w4 // fp[A]<- x0
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_int_to_short.S b/runtime/interpreter/mterp/arm64/op_int_to_short.S
deleted file mode 100644
index 0c51c76..0000000
--- a/runtime/interpreter/mterp/arm64/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="sxth w0, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_custom.S b/runtime/interpreter/mterp/arm64/op_invoke_custom.S
deleted file mode 100644
index 4bba9ee..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_custom.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_custom_range.S b/runtime/interpreter/mterp/arm64/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_direct.S b/runtime/interpreter/mterp/arm64/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_direct_range.S b/runtime/interpreter/mterp/arm64/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_interface.S b/runtime/interpreter/mterp/arm64/op_invoke_interface.S
deleted file mode 100644
index b064126..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_interface.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
- /*
- * Handle an interface method call.
- *
- * for: invoke-interface, invoke-interface/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_interface_range.S b/runtime/interpreter/mterp/arm64/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_polymorphic.S b/runtime/interpreter/mterp/arm64/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/arm64/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_static.S b/runtime/interpreter/mterp/arm64/op_invoke_static.S
deleted file mode 100644
index 3e38d36..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_static.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
-
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_static_range.S b/runtime/interpreter/mterp/arm64/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_super.S b/runtime/interpreter/mterp/arm64/op_invoke_super.S
deleted file mode 100644
index 3c34c99..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_super.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
- /*
- * Handle a "super" method call.
- *
- * for: invoke-super, invoke-super/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_super_range.S b/runtime/interpreter/mterp/arm64/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_virtual.S b/runtime/interpreter/mterp/arm64/op_invoke_virtual.S
deleted file mode 100644
index 249177b..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_virtual.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
- /*
- * Handle a virtual method call.
- *
- * for: invoke-virtual, invoke-virtual/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/arm64/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_virtual_range.S b/runtime/interpreter/mterp/arm64/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/arm64/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/arm64/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/arm64/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/arm64/op_iput.S b/runtime/interpreter/mterp/arm64/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm64/op_iput_boolean.S b/runtime/interpreter/mterp/arm64/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_boolean_quick.S b/runtime/interpreter/mterp/arm64/op_iput_boolean_quick.S
deleted file mode 100644
index fd077a7..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(store="strb")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_byte.S b/runtime/interpreter/mterp/arm64/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_byte_quick.S b/runtime/interpreter/mterp/arm64/op_iput_byte_quick.S
deleted file mode 100644
index 30238cf..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(store="strb")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_char.S b/runtime/interpreter/mterp/arm64/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_char_quick.S b/runtime/interpreter/mterp/arm64/op_iput_char_quick.S
deleted file mode 100644
index 0deff56..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(store="strh")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_object.S b/runtime/interpreter/mterp/arm64/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_object_quick.S b/runtime/interpreter/mterp/arm64/op_iput_object_quick.S
deleted file mode 100644
index 58c1026..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_object_quick.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_iput_object_quick():
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- bl MterpIputObjectQuick
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iput_quick.S b/runtime/interpreter/mterp/arm64/op_iput_quick.S
deleted file mode 100644
index 1d99108..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iput_quick(store="str"):
- /* For: iput-quick, iput-object-quick */
- /* op vA, vB, offset//CCCC */
- lsr w2, wINST, #12 // w2<- B
- FETCH w1, 1 // w1<- field byte offset
- GET_VREG w3, w2 // w3<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- cbz w3, common_errNullObject // object was null
- GET_VREG w0, w2 // w0<- fp[A]
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $store w0, [x3, x1] // obj.field<- w0
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iput_short.S b/runtime/interpreter/mterp/arm64/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_short_quick.S b/runtime/interpreter/mterp/arm64/op_iput_short_quick.S
deleted file mode 100644
index 6a1b651..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(store="strh")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide.S b/runtime/interpreter/mterp/arm64/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S b/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S
deleted file mode 100644
index a789188..0000000
--- a/runtime/interpreter/mterp/arm64/op_iput_wide_quick.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset//CCCC */
- lsr w2, wINST, #12 // w2<- B
- FETCH w3, 1 // w3<- field byte offset
- GET_VREG w2, w2 // w2<- fp[B], the object pointer
- ubfx w0, wINST, #8, #4 // w0<- A
- cbz w2, common_errNullObject // object was null
- GET_VREG_WIDE x0, w0 // x0<- fp[A]
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- str x0, [x2, x3] // obj.field<- x0
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_long_to_double.S b/runtime/interpreter/mterp/arm64/op_long_to_double.S
deleted file mode 100644
index b1b7b4e..0000000
--- a/runtime/interpreter/mterp/arm64/op_long_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_double():
-% funopWide(instr="scvtf d0, x0", srcreg="x0", tgtreg="d0")
diff --git a/runtime/interpreter/mterp/arm64/op_long_to_float.S b/runtime/interpreter/mterp/arm64/op_long_to_float.S
deleted file mode 100644
index 424dea0..0000000
--- a/runtime/interpreter/mterp/arm64/op_long_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_float():
-% funopNarrower(instr="scvtf s0, x0", srcreg="x0", tgtreg="s0")
diff --git a/runtime/interpreter/mterp/arm64/op_long_to_int.S b/runtime/interpreter/mterp/arm64/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/arm64/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/arm64/op_monitor_enter.S b/runtime/interpreter/mterp/arm64/op_monitor_enter.S
deleted file mode 100644
index 9d167a2..0000000
--- a/runtime/interpreter/mterp/arm64/op_monitor_enter.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_monitor_enter():
- /*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- EXPORT_PC
- lsr w2, wINST, #8 // w2<- AA
- GET_VREG w0, w2 // w0<- vAA (object)
- mov x1, xSELF // w1<- self
- bl artLockObjectFromCode
- cbnz w0, MterpException
- FETCH_ADVANCE_INST 1
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_monitor_exit.S b/runtime/interpreter/mterp/arm64/op_monitor_exit.S
deleted file mode 100644
index 985769f..0000000
--- a/runtime/interpreter/mterp/arm64/op_monitor_exit.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_monitor_exit():
- /*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- EXPORT_PC
- lsr w2, wINST, #8 // w2<- AA
- GET_VREG w0, w2 // w0<- vAA (object)
- mov x1, xSELF // w0<- self
- bl artUnlockObjectFromCode // w0<- success for unlock(self, obj)
- cbnz w0, MterpException
- FETCH_ADVANCE_INST 1 // before throw: advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move.S b/runtime/interpreter/mterp/arm64/op_move.S
deleted file mode 100644
index d3324f1..0000000
--- a/runtime/interpreter/mterp/arm64/op_move.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- lsr w1, wINST, #12 // x1<- B from 15:12
- ubfx w0, wINST, #8, #4 // x0<- A from 11:8
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- GET_VREG w2, w1 // x2<- fp[B]
- GET_INST_OPCODE ip // ip<- opcode from wINST
- .if $is_object
- SET_VREG_OBJECT w2, w0 // fp[A]<- x2
- .else
- SET_VREG w2, w0 // fp[A]<- x2
- .endif
- GOTO_OPCODE ip // execute next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_16.S b/runtime/interpreter/mterp/arm64/op_move_16.S
deleted file mode 100644
index 0dc862d..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- FETCH w1, 2 // w1<- BBBB
- FETCH w0, 1 // w0<- AAAA
- FETCH_ADVANCE_INST 3 // advance xPC, load xINST
- GET_VREG w2, w1 // w2<- fp[BBBB]
- GET_INST_OPCODE ip // extract opcode from xINST
- .if $is_object
- SET_VREG_OBJECT w2, w0 // fp[AAAA]<- w2
- .else
- SET_VREG w2, w0 // fp[AAAA]<- w2
- .endif
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_exception.S b/runtime/interpreter/mterp/arm64/op_move_exception.S
deleted file mode 100644
index 2ae5ca8..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_exception.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- lsr w2, wINST, #8 // w2<- AA
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- mov x1, #0 // w1<- 0
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- SET_VREG_OBJECT w3, w2 // fp[AA]<- exception obj
- GET_INST_OPCODE ip // extract opcode from rINST
- str x1, [xSELF, #THREAD_EXCEPTION_OFFSET] // clear exception
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_from16.S b/runtime/interpreter/mterp/arm64/op_move_from16.S
deleted file mode 100644
index 5c73445..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_from16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- FETCH w1, 1 // r1<- BBBB
- lsr w0, wINST, #8 // r0<- AA
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- GET_VREG w2, w1 // r2<- fp[BBBB]
- GET_INST_OPCODE ip // extract opcode from wINST
- .if $is_object
- SET_VREG_OBJECT w2, w0 // fp[AA]<- r2
- .else
- SET_VREG w2, w0 // fp[AA]<- r2
- .endif
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_object.S b/runtime/interpreter/mterp/arm64/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/arm64/op_move_object_16.S b/runtime/interpreter/mterp/arm64/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/arm64/op_move_object_from16.S b/runtime/interpreter/mterp/arm64/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/arm64/op_move_result.S b/runtime/interpreter/mterp/arm64/op_move_result.S
deleted file mode 100644
index 9c048f0..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_result.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- lsr w2, wINST, #8 // r2<- AA
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- ldr x0, [xFP, #OFF_FP_RESULT_REGISTER] // get pointer to result JType.
- ldr w0, [x0] // r0 <- result.i.
- GET_INST_OPCODE ip // extract opcode from wINST
- .if $is_object
- SET_VREG_OBJECT w0, w2, w1 // fp[AA]<- r0
- .else
- SET_VREG w0, w2 // fp[AA]<- r0
- .endif
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_result_object.S b/runtime/interpreter/mterp/arm64/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/arm64/op_move_result_wide.S b/runtime/interpreter/mterp/arm64/op_move_result_wide.S
deleted file mode 100644
index 96347ea..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_result_wide.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_result_wide():
- /* for: move-result-wide */
- /* op vAA */
- lsr w2, wINST, #8 // r2<- AA
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- 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
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_wide.S b/runtime/interpreter/mterp/arm64/op_move_wide.S
deleted file mode 100644
index 4576987..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_wide.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- lsr w3, wINST, #12 // w3<- B
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG_WIDE x3, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE x3, w2
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_wide_16.S b/runtime/interpreter/mterp/arm64/op_move_wide_16.S
deleted file mode 100644
index 09f7a61..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_wide_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- FETCH w3, 2 // w3<- BBBB
- FETCH w2, 1 // w2<- AAAA
- GET_VREG_WIDE x3, w3
- FETCH_ADVANCE_INST 3 // advance rPC, load rINST
- SET_VREG_WIDE x3, w2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_move_wide_from16.S b/runtime/interpreter/mterp/arm64/op_move_wide_from16.S
deleted file mode 100644
index 6afc20a..0000000
--- a/runtime/interpreter/mterp/arm64/op_move_wide_from16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- FETCH w3, 1 // w3<- BBBB
- lsr w2, wINST, #8 // w2<- AA
- GET_VREG_WIDE x3, w3
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE x3, w2
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_mul_double.S b/runtime/interpreter/mterp/arm64/op_mul_double.S
deleted file mode 100644
index 30ca309..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% binopWide(instr="fmul d0, d1, d2", result="d0", r1="d1", r2="d2")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_double_2addr.S b/runtime/interpreter/mterp/arm64/op_mul_double_2addr.S
deleted file mode 100644
index dedecb5..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% binopWide2addr(instr="fmul d0, d0, d1", r0="d0", r1="d1")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_float.S b/runtime/interpreter/mterp/arm64/op_mul_float.S
deleted file mode 100644
index 3bbbe73..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% fbinop(instr="fmul s0, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_float_2addr.S b/runtime/interpreter/mterp/arm64/op_mul_float_2addr.S
deleted file mode 100644
index 035a1fb..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% fbinop2addr(instr="fmul s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_int.S b/runtime/interpreter/mterp/arm64/op_mul_int.S
deleted file mode 100644
index 267623d..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int():
-/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
-% binop(instr="mul w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_int_2addr.S b/runtime/interpreter/mterp/arm64/op_mul_int_2addr.S
deleted file mode 100644
index c0f533a..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_int_2addr.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_2addr():
-/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
-% binop2addr(instr="mul w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_int_lit16.S b/runtime/interpreter/mterp/arm64/op_mul_int_lit16.S
deleted file mode 100644
index d309c86..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_int_lit16.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_lit16():
-/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
-% binopLit16(instr="mul w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_int_lit8.S b/runtime/interpreter/mterp/arm64/op_mul_int_lit8.S
deleted file mode 100644
index b336841..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_int_lit8.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_mul_int_lit8():
-/* must be "mul w0, w1, w0" -- "w0, w0, w1" is illegal */
-% binopLit8(instr="mul w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_long.S b/runtime/interpreter/mterp/arm64/op_mul_long.S
deleted file mode 100644
index 5056c0e..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_long():
-% binopWide(instr="mul x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_mul_long_2addr.S b/runtime/interpreter/mterp/arm64/op_mul_long_2addr.S
deleted file mode 100644
index e69d40a..0000000
--- a/runtime/interpreter/mterp/arm64/op_mul_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_long_2addr():
-% binopWide2addr(instr="mul x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/op_neg_double.S b/runtime/interpreter/mterp/arm64/op_neg_double.S
deleted file mode 100644
index a56eff5..0000000
--- a/runtime/interpreter/mterp/arm64/op_neg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_double():
-% unopWide(instr="eor x0, x0, #0x8000000000000000")
diff --git a/runtime/interpreter/mterp/arm64/op_neg_float.S b/runtime/interpreter/mterp/arm64/op_neg_float.S
deleted file mode 100644
index 1366168..0000000
--- a/runtime/interpreter/mterp/arm64/op_neg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_float():
-% unop(instr="eor w0, w0, #0x80000000")
diff --git a/runtime/interpreter/mterp/arm64/op_neg_int.S b/runtime/interpreter/mterp/arm64/op_neg_int.S
deleted file mode 100644
index be56dd2..0000000
--- a/runtime/interpreter/mterp/arm64/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr="sub w0, wzr, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_neg_long.S b/runtime/interpreter/mterp/arm64/op_neg_long.S
deleted file mode 100644
index eb2882c..0000000
--- a/runtime/interpreter/mterp/arm64/op_neg_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_long():
-% unopWide(instr="sub x0, xzr, x0")
diff --git a/runtime/interpreter/mterp/arm64/op_new_array.S b/runtime/interpreter/mterp/arm64/op_new_array.S
deleted file mode 100644
index 34729a7..0000000
--- a/runtime/interpreter/mterp/arm64/op_new_array.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_new_array():
- /*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class//CCCC */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- mov x3, xSELF
- bl MterpNewArray
- cbz w0, MterpPossibleException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_new_instance.S b/runtime/interpreter/mterp/arm64/op_new_instance.S
deleted file mode 100644
index beb1f6e..0000000
--- a/runtime/interpreter/mterp/arm64/op_new_instance.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_new_instance():
- /*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class//BBBB */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xSELF
- mov w2, wINST
- bl MterpNewInstance // (shadow_frame, self, inst_data)
- cbz w0, MterpPossibleException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_nop.S b/runtime/interpreter/mterp/arm64/op_nop.S
deleted file mode 100644
index 9702c5c..0000000
--- a/runtime/interpreter/mterp/arm64/op_nop.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_nop():
- FETCH_ADVANCE_INST 1 // advance to next instr, load rINST
- GET_INST_OPCODE ip // ip<- opcode from rINST
- GOTO_OPCODE ip // execute it
diff --git a/runtime/interpreter/mterp/arm64/op_not_int.S b/runtime/interpreter/mterp/arm64/op_not_int.S
deleted file mode 100644
index d2fc205..0000000
--- a/runtime/interpreter/mterp/arm64/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr="mvn w0, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_not_long.S b/runtime/interpreter/mterp/arm64/op_not_long.S
deleted file mode 100644
index 014a60d..0000000
--- a/runtime/interpreter/mterp/arm64/op_not_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_long():
-% unopWide(instr="mvn x0, x0")
diff --git a/runtime/interpreter/mterp/arm64/op_or_int.S b/runtime/interpreter/mterp/arm64/op_or_int.S
deleted file mode 100644
index 8041c6d..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="orr w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_or_int_2addr.S b/runtime/interpreter/mterp/arm64/op_or_int_2addr.S
deleted file mode 100644
index 918c523..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="orr w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_or_int_lit16.S b/runtime/interpreter/mterp/arm64/op_or_int_lit16.S
deleted file mode 100644
index dda068b..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="orr w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_or_int_lit8.S b/runtime/interpreter/mterp/arm64/op_or_int_lit8.S
deleted file mode 100644
index 0fe6122..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(extract="", instr="orr w0, w0, w3, asr #8")
diff --git a/runtime/interpreter/mterp/arm64/op_or_long.S b/runtime/interpreter/mterp/arm64/op_or_long.S
deleted file mode 100644
index f434d3f..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(instr="orr x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_or_long_2addr.S b/runtime/interpreter/mterp/arm64/op_or_long_2addr.S
deleted file mode 100644
index 4186ce9..0000000
--- a/runtime/interpreter/mterp/arm64/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(instr="orr x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S
deleted file mode 100644
index 9e4eb9b..0000000
--- a/runtime/interpreter/mterp/arm64/op_packed_switch.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
- /*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBB */
- FETCH w0, 1 // x0<- 000000000000bbbb (lo)
- FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi)
- lsr w3, wINST, #8 // w3<- AA
- orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb
- GET_VREG w1, w3 // w1<- vAA
- add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2
- bl $func // w0<- code-unit branch offset
- sxtw xINST, w0
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/arm64/op_rem_double.S b/runtime/interpreter/mterp/arm64/op_rem_double.S
deleted file mode 100644
index 3d43467..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_double.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_rem_double():
- /* rem vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w2, w0, #8 // w2<- CC
- and w1, w0, #255 // w1<- BB
- GET_VREG_WIDE d1, w2 // d1<- vCC
- GET_VREG_WIDE d0, w1 // d0<- vBB
- bl fmod
- lsr w4, wINST, #8 // w4<- AA
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG_WIDE d0, w4 // vAA<- result
- GOTO_OPCODE ip // jump to next instruction
- /* 11-14 instructions */
diff --git a/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S
deleted file mode 100644
index 179886d..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_rem_double_2addr():
- /* rem vA, vB */
- lsr w1, wINST, #12 // w1<- B
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG_WIDE d1, w1 // d1<- vB
- GET_VREG_WIDE d0, w2 // d0<- vA
- bl fmod
- ubfx w2, wINST, #8, #4 // w2<- A (need to reload - killed across call)
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG_WIDE d0, w2 // vAA<- result
- GOTO_OPCODE ip // jump to next instruction
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm64/op_rem_float.S b/runtime/interpreter/mterp/arm64/op_rem_float.S
deleted file mode 100644
index 29241e5..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_float.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rem_float():
-/* EABI doesn't define a float remainder function, but libm does */
-% fbinop(instr="bl fmodf")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S
deleted file mode 100644
index 49bf8ea..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_float_2addr.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_rem_float_2addr():
- /* rem vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w9, wINST, #8, #4 // w9<- A
- GET_VREG s1, w3
- GET_VREG s0, w9
- bl fmodf
- 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
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_rem_int.S b/runtime/interpreter/mterp/arm64/op_rem_int.S
deleted file mode 100644
index 6f2f999..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int():
-% binop(preinstr="sdiv w2, w0, w1", instr="msub w0, w2, w1, w0", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_int_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_int_2addr.S
deleted file mode 100644
index dc46b2f..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_2addr():
-% binop2addr(preinstr="sdiv w2, w0, w1", instr="msub w0, w2, w1, w0", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_int_lit16.S b/runtime/interpreter/mterp/arm64/op_rem_int_lit16.S
deleted file mode 100644
index 75be334..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit16():
-% binopLit16(preinstr="sdiv w3, w0, w1", instr="msub w0, w3, w1, w0", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_int_lit8.S b/runtime/interpreter/mterp/arm64/op_rem_int_lit8.S
deleted file mode 100644
index c5fef4b..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit8():
-% binopLit8(preinstr="sdiv w3, w0, w1", instr="msub w0, w3, w1, w0", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_long.S b/runtime/interpreter/mterp/arm64/op_rem_long.S
deleted file mode 100644
index 31dd6be..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long():
-% binopWide(preinstr="sdiv x3, x1, x2", instr="msub x0, x3, x2, x1", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_rem_long_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_long_2addr.S
deleted file mode 100644
index b30ef67..0000000
--- a/runtime/interpreter/mterp/arm64/op_rem_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long_2addr():
-% binopWide2addr(preinstr="sdiv x3, x0, x1", instr="msub x0, x3, x1, x0", chkzero="1")
diff --git a/runtime/interpreter/mterp/arm64/op_return.S b/runtime/interpreter/mterp/arm64/op_return.S
deleted file mode 100644
index eedae64..0000000
--- a/runtime/interpreter/mterp/arm64/op_return.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_return():
- /*
- * Return a 32-bit value.
- *
- * for: return, return-object
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- mov x0, xSELF
- ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne .L${opcode}_check
-.L${opcode}_return:
- lsr w2, wINST, #8 // r2<- AA
- GET_VREG w0, w2 // r0<- vAA
- b MterpReturn
-.L${opcode}_check:
- bl MterpSuspendCheck // (self)
- b .L${opcode}_return
diff --git a/runtime/interpreter/mterp/arm64/op_return_object.S b/runtime/interpreter/mterp/arm64/op_return_object.S
deleted file mode 100644
index 2eeec0b..0000000
--- a/runtime/interpreter/mterp/arm64/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return()
diff --git a/runtime/interpreter/mterp/arm64/op_return_void.S b/runtime/interpreter/mterp/arm64/op_return_void.S
deleted file mode 100644
index 6962bb2..0000000
--- a/runtime/interpreter/mterp/arm64/op_return_void.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- mov x0, xSELF
- ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne .L${opcode}_check
-.L${opcode}_return:
- mov x0, #0
- b MterpReturn
-.L${opcode}_check:
- bl MterpSuspendCheck // (self)
- b .L${opcode}_return
diff --git a/runtime/interpreter/mterp/arm64/op_return_void_no_barrier.S b/runtime/interpreter/mterp/arm64/op_return_void_no_barrier.S
deleted file mode 100644
index 8d872d1..0000000
--- a/runtime/interpreter/mterp/arm64/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_return_void_no_barrier():
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- mov x0, xSELF
- ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne .L${opcode}_check
-.L${opcode}_return:
- mov x0, #0
- b MterpReturn
-.L${opcode}_check:
- bl MterpSuspendCheck // (self)
- b .L${opcode}_return
diff --git a/runtime/interpreter/mterp/arm64/op_return_wide.S b/runtime/interpreter/mterp/arm64/op_return_wide.S
deleted file mode 100644
index 5d31c6a..0000000
--- a/runtime/interpreter/mterp/arm64/op_return_wide.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_return_wide():
- /*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- bl MterpThreadFenceForConstructor
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- mov x0, xSELF
- ands w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- b.ne .L${opcode}_check
-.L${opcode}_return:
- lsr w2, wINST, #8 // w2<- AA
- GET_VREG_WIDE x0, w2 // x0<- vAA
- b MterpReturn
-.L${opcode}_check:
- bl MterpSuspendCheck // (self)
- b .L${opcode}_return
diff --git a/runtime/interpreter/mterp/arm64/op_rsub_int.S b/runtime/interpreter/mterp/arm64/op_rsub_int.S
deleted file mode 100644
index dc2342d..0000000
--- a/runtime/interpreter/mterp/arm64/op_rsub_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rsub_int():
-/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
-% binopLit16(instr="sub w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_rsub_int_lit8.S b/runtime/interpreter/mterp/arm64/op_rsub_int_lit8.S
deleted file mode 100644
index 51a48fb..0000000
--- a/runtime/interpreter/mterp/arm64/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(instr="sub w0, w1, w0")
diff --git a/runtime/interpreter/mterp/arm64/op_sget.S b/runtime/interpreter/mterp/arm64/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm64/op_sget_boolean.S b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/arm64/op_sget_byte.S b/runtime/interpreter/mterp/arm64/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/arm64/op_sget_char.S b/runtime/interpreter/mterp/arm64/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/arm64/op_sget_object.S b/runtime/interpreter/mterp/arm64/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/arm64/op_sget_short.S b/runtime/interpreter/mterp/arm64/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/arm64/op_sget_wide.S b/runtime/interpreter/mterp/arm64/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/arm64/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/arm64/op_shl_int.S b/runtime/interpreter/mterp/arm64/op_shl_int.S
deleted file mode 100644
index 673d4a0..0000000
--- a/runtime/interpreter/mterp/arm64/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop(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
deleted file mode 100644
index f4c2f8c..0000000
--- a/runtime/interpreter/mterp/arm64/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% binop2addr(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
deleted file mode 100644
index 38f3f8e..0000000
--- a/runtime/interpreter/mterp/arm64/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(extract="ubfx w1, w3, #8, #5", instr="lsl w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_shl_long.S b/runtime/interpreter/mterp/arm64/op_shl_long.S
deleted file mode 100644
index c56b59f..0000000
--- a/runtime/interpreter/mterp/arm64/op_shl_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long():
-% shiftWide(opcode="lsl")
diff --git a/runtime/interpreter/mterp/arm64/op_shl_long_2addr.S b/runtime/interpreter/mterp/arm64/op_shl_long_2addr.S
deleted file mode 100644
index ed10db2..0000000
--- a/runtime/interpreter/mterp/arm64/op_shl_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long_2addr():
-% shiftWide2addr(opcode="lsl")
diff --git a/runtime/interpreter/mterp/arm64/op_shr_int.S b/runtime/interpreter/mterp/arm64/op_shr_int.S
deleted file mode 100644
index 9dab83d..0000000
--- a/runtime/interpreter/mterp/arm64/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop(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
deleted file mode 100644
index 8bdcc11..0000000
--- a/runtime/interpreter/mterp/arm64/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% binop2addr(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
deleted file mode 100644
index 7f58bca..0000000
--- a/runtime/interpreter/mterp/arm64/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(extract="ubfx w1, w3, #8, #5", instr="asr w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_shr_long.S b/runtime/interpreter/mterp/arm64/op_shr_long.S
deleted file mode 100644
index fcaf0ec..0000000
--- a/runtime/interpreter/mterp/arm64/op_shr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long():
-% shiftWide(opcode="asr")
diff --git a/runtime/interpreter/mterp/arm64/op_shr_long_2addr.S b/runtime/interpreter/mterp/arm64/op_shr_long_2addr.S
deleted file mode 100644
index 359778a..0000000
--- a/runtime/interpreter/mterp/arm64/op_shr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long_2addr():
-% shiftWide2addr(opcode="asr")
diff --git a/runtime/interpreter/mterp/arm64/op_sparse_switch.S b/runtime/interpreter/mterp/arm64/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/arm64/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/arm64/op_sput.S b/runtime/interpreter/mterp/arm64/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/arm64/op_sput_boolean.S b/runtime/interpreter/mterp/arm64/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/arm64/op_sput_byte.S b/runtime/interpreter/mterp/arm64/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/arm64/op_sput_char.S b/runtime/interpreter/mterp/arm64/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/arm64/op_sput_object.S b/runtime/interpreter/mterp/arm64/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/arm64/op_sput_short.S b/runtime/interpreter/mterp/arm64/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/arm64/op_sput_wide.S b/runtime/interpreter/mterp/arm64/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/arm64/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_double.S b/runtime/interpreter/mterp/arm64/op_sub_double.S
deleted file mode 100644
index cca7556..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% binopWide(instr="fsub d0, d1, d2", result="d0", r1="d1", r2="d2")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_double_2addr.S b/runtime/interpreter/mterp/arm64/op_sub_double_2addr.S
deleted file mode 100644
index 6d425fc..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% binopWide2addr(instr="fsub d0, d0, d1", r0="d0", r1="d1")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_float.S b/runtime/interpreter/mterp/arm64/op_sub_float.S
deleted file mode 100644
index e1c469b..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% fbinop(instr="fsub s0, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_float_2addr.S b/runtime/interpreter/mterp/arm64/op_sub_float_2addr.S
deleted file mode 100644
index 91b8346..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% fbinop2addr(instr="fsub s2, s0, s1")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_int.S b/runtime/interpreter/mterp/arm64/op_sub_int.S
deleted file mode 100644
index 8951463..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="sub w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_int_2addr.S b/runtime/interpreter/mterp/arm64/op_sub_int_2addr.S
deleted file mode 100644
index a450ce4..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="sub w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_long.S b/runtime/interpreter/mterp/arm64/op_sub_long.S
deleted file mode 100644
index 696e79a..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long():
-% binopWide(instr="sub x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_sub_long_2addr.S b/runtime/interpreter/mterp/arm64/op_sub_long_2addr.S
deleted file mode 100644
index a622451..0000000
--- a/runtime/interpreter/mterp/arm64/op_sub_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long_2addr():
-% binopWide2addr(instr="sub x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/op_throw.S b/runtime/interpreter/mterp/arm64/op_throw.S
deleted file mode 100644
index ed5a19e..0000000
--- a/runtime/interpreter/mterp/arm64/op_throw.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_throw():
- /*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC
- lsr w2, wINST, #8 // r2<- AA
- GET_VREG w1, w2 // r1<- vAA (exception object)
- cbz w1, common_errNullObject
- str x1, [xSELF, #THREAD_EXCEPTION_OFFSET] // thread->exception<- obj
- b MterpException
diff --git a/runtime/interpreter/mterp/arm64/op_unused_3e.S b/runtime/interpreter/mterp/arm64/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_3f.S b/runtime/interpreter/mterp/arm64/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_40.S b/runtime/interpreter/mterp/arm64/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_41.S b/runtime/interpreter/mterp/arm64/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_42.S b/runtime/interpreter/mterp/arm64/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_43.S b/runtime/interpreter/mterp/arm64/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_73.S b/runtime/interpreter/mterp/arm64/op_unused_73.S
deleted file mode 100644
index e3267a3..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_73.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_73():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_79.S b/runtime/interpreter/mterp/arm64/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_7a.S b/runtime/interpreter/mterp/arm64/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f3.S b/runtime/interpreter/mterp/arm64/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f4.S b/runtime/interpreter/mterp/arm64/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f5.S b/runtime/interpreter/mterp/arm64/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f6.S b/runtime/interpreter/mterp/arm64/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f7.S b/runtime/interpreter/mterp/arm64/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f8.S b/runtime/interpreter/mterp/arm64/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_f9.S b/runtime/interpreter/mterp/arm64/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_fc.S b/runtime/interpreter/mterp/arm64/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_unused_fd.S b/runtime/interpreter/mterp/arm64/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/arm64/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_int.S b/runtime/interpreter/mterp/arm64/op_ushr_int.S
deleted file mode 100644
index 5f6ad2d..0000000
--- a/runtime/interpreter/mterp/arm64/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop(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
deleted file mode 100644
index 47527b1..0000000
--- a/runtime/interpreter/mterp/arm64/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% binop2addr(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
deleted file mode 100644
index abc5898..0000000
--- a/runtime/interpreter/mterp/arm64/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(extract="ubfx w1, w3, #8, #5", instr="lsr w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_long.S b/runtime/interpreter/mterp/arm64/op_ushr_long.S
deleted file mode 100644
index 4f3e941..0000000
--- a/runtime/interpreter/mterp/arm64/op_ushr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long():
-% shiftWide(opcode="lsr")
diff --git a/runtime/interpreter/mterp/arm64/op_ushr_long_2addr.S b/runtime/interpreter/mterp/arm64/op_ushr_long_2addr.S
deleted file mode 100644
index 5606d12..0000000
--- a/runtime/interpreter/mterp/arm64/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long_2addr():
-% shiftWide2addr(opcode="lsr")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_int.S b/runtime/interpreter/mterp/arm64/op_xor_int.S
deleted file mode 100644
index 369af7d..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="eor w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_int_2addr.S b/runtime/interpreter/mterp/arm64/op_xor_int_2addr.S
deleted file mode 100644
index f8e87b3..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="eor w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_int_lit16.S b/runtime/interpreter/mterp/arm64/op_xor_int_lit16.S
deleted file mode 100644
index bcfc6e2..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="eor w0, w0, w1")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_int_lit8.S b/runtime/interpreter/mterp/arm64/op_xor_int_lit8.S
deleted file mode 100644
index bd59c4c..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(extract="", instr="eor w0, w0, w3, asr #8")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_long.S b/runtime/interpreter/mterp/arm64/op_xor_long.S
deleted file mode 100644
index 58b97bd..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(instr="eor x0, x1, x2")
diff --git a/runtime/interpreter/mterp/arm64/op_xor_long_2addr.S b/runtime/interpreter/mterp/arm64/op_xor_long_2addr.S
deleted file mode 100644
index 5877665..0000000
--- a/runtime/interpreter/mterp/arm64/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(instr="eor x0, x0, x1")
diff --git a/runtime/interpreter/mterp/arm64/other.S b/runtime/interpreter/mterp/arm64/other.S
new file mode 100644
index 0000000..024a5c8
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/other.S
@@ -0,0 +1,355 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC
+ FETCH w0, 1 // w0<- BBBB
+ lsr w1, wINST, #8 // w1<- AA
+ add x2, xFP, #OFF_FP_SHADOWFRAME
+ mov x3, xSELF
+ bl $helper // (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 2 // load rINST
+ cbnz w0, MterpPossibleException // let reference interpreter deal with it.
+ ADVANCE 2 // advance rPC
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
+%def op_const():
+ /* const vAA, #+BBBBbbbb */
+ lsr w3, wINST, #8 // w3<- AA
+ FETCH w0, 1 // w0<- bbbb (low
+ FETCH w1, 2 // w1<- BBBB (high
+ FETCH_ADVANCE_INST 3 // advance rPC, load wINST
+ orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG w0, w3 // vAA<- w0
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_16():
+ /* const/16 vAA, #+BBBB */
+ FETCH_S w0, 1 // w0<- ssssBBBB (sign-extended)
+ lsr w3, wINST, #8 // w3<- AA
+ FETCH_ADVANCE_INST 2 // advance xPC, load wINST
+ SET_VREG w0, w3 // vAA<- w0
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_4():
+ /* const/4 vA, #+B */
+ sbfx w1, wINST, #12, #4 // w1<- sssssssB
+ ubfx w0, wINST, #8, #4 // w0<- A
+ FETCH_ADVANCE_INST 1 // advance xPC, load wINST
+ GET_INST_OPCODE ip // ip<- opcode from xINST
+ SET_VREG w1, w0 // fp[A]<- w1
+ GOTO_OPCODE ip // execute next instruction
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, #+BBBB0000 */
+ FETCH w0, 1 // r0<- 0000BBBB (zero-extended)
+ lsr w3, wINST, #8 // r3<- AA
+ lsl w0, w0, #16 // r0<- BBBB0000
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ SET_VREG w0, w3 // vAA<- r0
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, String//BBBBBBBB */
+ EXPORT_PC
+ FETCH w0, 1 // w0<- bbbb (low
+ FETCH w2, 2 // w2<- BBBB (high
+ lsr w1, wINST, #8 // w1<- AA
+ orr w0, w0, w2, lsl #16 // w1<- BBBBbbbb
+ add x2, xFP, #OFF_FP_SHADOWFRAME
+ mov x3, xSELF
+ bl MterpConstString // (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 3 // advance rPC
+ cbnz w0, MterpPossibleException // let reference interpreter deal with it.
+ ADVANCE 3 // advance rPC
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_wide():
+ /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
+ FETCH w0, 1 // w0<- bbbb (low)
+ FETCH w1, 2 // w1<- BBBB (low middle)
+ FETCH w2, 3 // w2<- hhhh (high middle)
+ FETCH w3, 4 // w3<- HHHH (high)
+ lsr w4, wINST, #8 // r4<- AA
+ FETCH_ADVANCE_INST 5 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb
+ orr x0, x0, x2, lsl #32 // w0<- hhhhBBBBbbbb
+ orr x0, x0, x3, lsl #48 // w0<- HHHHhhhhBBBBbbbb
+ SET_VREG_WIDE x0, w4
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, #+BBBB */
+ FETCH_S x0, 1 // x0<- ssssssssssssBBBB (sign-extended)
+ lsr w3, wINST, #8 // w3<- AA
+ FETCH_ADVANCE_INST 2 // advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ SET_VREG_WIDE x0, w3
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, #+BBBBbbbb */
+ FETCH w0, 1 // x0<- 000000000000bbbb (low)
+ lsr w3, wINST, #8 // w3<- AA
+ FETCH_S x2, 2 // x2<- ssssssssssssBBBB (high)
+ FETCH_ADVANCE_INST 3 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ orr x0, x0, x2, lsl #16 // x0<- ssssssssBBBBbbbb
+ SET_VREG_WIDE x0, w3
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, #+BBBB000000000000 */
+ FETCH w0, 1 // w0<- 0000BBBB (zero-extended)
+ lsr w1, wINST, #8 // w1<- AA
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ lsl x0, x0, #48
+ SET_VREG_WIDE x0, w1
+ GET_INST_OPCODE ip // extract opcode from wINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_monitor_enter():
+ /*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ EXPORT_PC
+ lsr w2, wINST, #8 // w2<- AA
+ GET_VREG w0, w2 // w0<- vAA (object)
+ mov x1, xSELF // w1<- self
+ bl artLockObjectFromCode
+ cbnz w0, MterpException
+ FETCH_ADVANCE_INST 1
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_monitor_exit():
+ /*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ EXPORT_PC
+ lsr w2, wINST, #8 // w2<- AA
+ GET_VREG w0, w2 // w0<- vAA (object)
+ mov x1, xSELF // w0<- self
+ bl artUnlockObjectFromCode // w0<- success for unlock(self, obj)
+ cbnz w0, MterpException
+ FETCH_ADVANCE_INST 1 // before throw: advance rPC, load rINST
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ lsr w1, wINST, #12 // x1<- B from 15:12
+ ubfx w0, wINST, #8, #4 // x0<- A from 11:8
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ GET_VREG w2, w1 // x2<- fp[B]
+ GET_INST_OPCODE ip // ip<- opcode from wINST
+ .if $is_object
+ SET_VREG_OBJECT w2, w0 // fp[A]<- x2
+ .else
+ SET_VREG w2, w0 // fp[A]<- x2
+ .endif
+ GOTO_OPCODE ip // execute next instruction
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ FETCH w1, 2 // w1<- BBBB
+ FETCH w0, 1 // w0<- AAAA
+ FETCH_ADVANCE_INST 3 // advance xPC, load xINST
+ GET_VREG w2, w1 // w2<- fp[BBBB]
+ GET_INST_OPCODE ip // extract opcode from xINST
+ .if $is_object
+ SET_VREG_OBJECT w2, w0 // fp[AAAA]<- w2
+ .else
+ SET_VREG w2, w0 // fp[AAAA]<- w2
+ .endif
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_exception():
+ /* move-exception vAA */
+ lsr w2, wINST, #8 // w2<- AA
+ ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
+ mov x1, #0 // w1<- 0
+ FETCH_ADVANCE_INST 1 // advance rPC, load rINST
+ SET_VREG_OBJECT w3, w2 // fp[AA]<- exception obj
+ GET_INST_OPCODE ip // extract opcode from rINST
+ str x1, [xSELF, #THREAD_EXCEPTION_OFFSET] // clear exception
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ FETCH w1, 1 // r1<- BBBB
+ lsr w0, wINST, #8 // r0<- AA
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ GET_VREG w2, w1 // r2<- fp[BBBB]
+ GET_INST_OPCODE ip // extract opcode from wINST
+ .if $is_object
+ SET_VREG_OBJECT w2, w0 // fp[AA]<- r2
+ .else
+ SET_VREG w2, w0 // fp[AA]<- r2
+ .endif
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ lsr w2, wINST, #8 // r2<- AA
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ ldr x0, [xFP, #OFF_FP_RESULT_REGISTER] // get pointer to result JType.
+ ldr w0, [x0] // r0 <- result.i.
+ GET_INST_OPCODE ip // extract opcode from wINST
+ .if $is_object
+ SET_VREG_OBJECT w0, w2, w1 // fp[AA]<- r0
+ .else
+ SET_VREG w0, w2 // fp[AA]<- r0
+ .endif
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* for: move-result-wide */
+ /* op vAA */
+ lsr w2, wINST, #8 // r2<- AA
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ 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
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ lsr w3, wINST, #12 // w3<- B
+ ubfx w2, wINST, #8, #4 // w2<- A
+ GET_VREG_WIDE x3, w3
+ FETCH_ADVANCE_INST 1 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE x3, w2
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ FETCH w3, 2 // w3<- BBBB
+ FETCH w2, 1 // w2<- AAAA
+ GET_VREG_WIDE x3, w3
+ FETCH_ADVANCE_INST 3 // advance rPC, load rINST
+ SET_VREG_WIDE x3, w2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ FETCH w3, 1 // w3<- BBBB
+ lsr w2, wINST, #8 // w2<- AA
+ GET_VREG_WIDE x3, w3
+ FETCH_ADVANCE_INST 2 // advance rPC, load wINST
+ GET_INST_OPCODE ip // extract opcode from wINST
+ SET_VREG_WIDE x3, w2
+ GOTO_OPCODE ip // jump to next instruction
+
+%def op_nop():
+ FETCH_ADVANCE_INST 1 // advance to next instr, load rINST
+ GET_INST_OPCODE ip // ip<- opcode from rINST
+ GOTO_OPCODE ip // execute it
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_73():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/arm64/shiftWide.S b/runtime/interpreter/mterp/arm64/shiftWide.S
deleted file mode 100644
index 46922c8..0000000
--- a/runtime/interpreter/mterp/arm64/shiftWide.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def shiftWide(opcode="shl"):
- /*
- * 64-bit shift operation.
- *
- * For: shl-long, shr-long, ushr-long
- */
- /* binop vAA, vBB, vCC */
- FETCH w0, 1 // w0<- CCBB
- lsr w3, wINST, #8 // w3<- AA
- lsr w2, w0, #8 // w2<- CC
- GET_VREG w2, w2 // w2<- vCC (shift count)
- and w1, w0, #255 // w1<- BB
- GET_VREG_WIDE x1, w1 // x1<- vBB
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- $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
- /* 11-14 instructions */
diff --git a/runtime/interpreter/mterp/arm64/shiftWide2addr.S b/runtime/interpreter/mterp/arm64/shiftWide2addr.S
deleted file mode 100644
index 2780d45..0000000
--- a/runtime/interpreter/mterp/arm64/shiftWide2addr.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def shiftWide2addr(opcode="lsl"):
- /*
- * Generic 64-bit shift operation.
- */
- /* binop/2addr vA, vB */
- lsr w1, wINST, #12 // w1<- B
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w1, w1 // x1<- vB
- GET_VREG_WIDE x0, w2 // x0<- vA
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- $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
- /* 10-13 instructions */
diff --git a/runtime/interpreter/mterp/arm64/unop.S b/runtime/interpreter/mterp/arm64/unop.S
deleted file mode 100644
index 65faf66..0000000
--- a/runtime/interpreter/mterp/arm64/unop.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def unop(instr=""):
- /*
- * Generic 32-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op w0".
- * This could be an ARM instruction or a function call.
- *
- * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
- * int-to-byte, int-to-char, int-to-short
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- GET_VREG w0, w3 // w0<- vB
- ubfx w9, wINST, #8, #4 // w9<- A
- FETCH_ADVANCE_INST 1 // advance rPC, load rINST
- $instr // w0<- op, w0-w3 changed
- GET_INST_OPCODE ip // extract opcode from rINST
- SET_VREG w0, w9 // vAA<- w0
- GOTO_OPCODE ip // jump to next instruction
- /* 8-9 instructions */
diff --git a/runtime/interpreter/mterp/arm64/unopWide.S b/runtime/interpreter/mterp/arm64/unopWide.S
deleted file mode 100644
index 6a16dfa..0000000
--- a/runtime/interpreter/mterp/arm64/unopWide.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def unopWide(instr="sub x0, xzr, x0"):
- /*
- * Generic 64-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op x0".
- *
- * For: neg-long, not-long
- */
- /* unop vA, vB */
- lsr w3, wINST, #12 // w3<- B
- ubfx w4, wINST, #8, #4 // w4<- A
- GET_VREG_WIDE x0, w3
- FETCH_ADVANCE_INST 1 // advance rPC, load wINST
- $instr
- GET_INST_OPCODE ip // extract opcode from wINST
- SET_VREG_WIDE x0, w4
- GOTO_OPCODE ip // jump to next instruction
- /* 10-11 instructions */
diff --git a/runtime/interpreter/mterp/arm64/unused.S b/runtime/interpreter/mterp/arm64/unused.S
deleted file mode 100644
index 3f37e74..0000000
--- a/runtime/interpreter/mterp/arm64/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/arm64/zcmp.S b/runtime/interpreter/mterp/arm64/zcmp.S
deleted file mode 100644
index 4435854..0000000
--- a/runtime/interpreter/mterp/arm64/zcmp.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def zcmp(compare="1", branch=""):
- /*
- * Generic one-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- lsr w0, wINST, #8 // w0<- AA
- GET_VREG w2, w0 // w2<- vAA
- FETCH_S wINST, 1 // w1<- branch offset, in code units
- .if ${compare}
- cmp w2, #0 // compare (vA, 0)
- .endif
- ${branch} MterpCommonTakenBranchNoFlags
- cmp wPROFILE, #JIT_CHECK_OSR // possible OSR re-entry?
- b.eq .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/alt_stub.S b/runtime/interpreter/mterp/mips/alt_stub.S
deleted file mode 100644
index 1ce7561..0000000
--- a/runtime/interpreter/mterp/mips/alt_stub.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Note that the call to MterpCheckBefore is done as a tail call.
- */
- .extern MterpCheckBefore
- la ra, artMterpAsmInstructionStart + (${opnum} * 128) # Addr of primary handler
- lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF) # refresh IBASE
- move a0, rSELF # arg0
- addu a1, rFP, OFF_FP_SHADOWFRAME # arg1
- move a2, rPC
- la t9, MterpCheckBefore
- jalr zero, t9 # Tail call to Mterp(self, shadow_frame, dex_pc_ptr)
diff --git a/runtime/interpreter/mterp/mips/arithmetic.S b/runtime/interpreter/mterp/mips/arithmetic.S
new file mode 100644
index 0000000..0743bde
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/arithmetic.S
@@ -0,0 +1,803 @@
+%def binop(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = a0 op a1".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus. Note that we
+ * *don't* check for (INT_MIN / -1) here, because the CPU handles it
+ * correctly.
+ *
+ * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
+ * xor-int, shl-int, shr-int, ushr-int
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ srl a3, a0, 8 # a3 <- CC
+ and a2, a0, 255 # a2 <- BB
+ GET_VREG(a1, a3) # a1 <- vCC
+ GET_VREG(a0, a2) # a0 <- vBB
+ .if $chkzero
+ # is second operand zero?
+ beqz a1, common_errDivideByZero
+ .endif
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO($result, rOBJ, t0) # vAA <- $result
+
+%def binop2addr(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be an MIPS instruction or a function call.
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus.
+ *
+ * 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
+ */
+ /* binop/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG(a0, rOBJ) # a0 <- vA
+ GET_VREG(a1, a3) # a1 <- vB
+ .if $chkzero
+ # is second operand zero?
+ beqz a1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO($result, rOBJ, t0) # vA <- $result
+
+%def binopLit16(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit16" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be an MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus.
+ *
+ * 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(a1, 1) # a1 <- ssssCCCC (sign-extended)
+ GET_OPB(a2) # a2 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_VREG(a0, a2) # a0 <- vB
+ .if $chkzero
+ # cmp a1, 0; is second operand zero?
+ beqz a1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO($result, rOBJ, t0) # vA <- $result
+
+%def binopLit8(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit8" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be an MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus.
+ *
+ * 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(a3, 1) # a3 <- ssssCCBB (sign-extended for CC)
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a2, a3, 255 # a2 <- BB
+ GET_VREG(a0, a2) # a0 <- vBB
+ sra a1, a3, 8 # a1 <- ssssssCC (sign extended)
+ .if $chkzero
+ # is second operand zero?
+ beqz a1, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO($result, rOBJ, t0) # vAA <- $result
+
+%def binopWide(preinstr="", result0="a0", result1="a1", chkzero="0", arg0="a0", arg1="a1", arg2="a2", arg3="a3", instr=""):
+ /*
+ * Generic 64-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = a0-a1 op a2-a3".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register pair other than a0-a1, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a2-a3). Useful for integer division and modulus.
+ *
+ * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
+ * xor-long
+ *
+ * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8 # a3 <- CC
+ EAS2(a2, rFP, a2) # a2 <- &fp[BB]
+ EAS2(t1, rFP, a3) # a3 <- &fp[CC]
+ LOAD64($arg0, $arg1, a2) # a0/a1 <- vBB/vBB+1
+ LOAD64($arg2, $arg3, t1) # a2/a3 <- vCC/vCC+1
+ .if $chkzero
+ or t0, $arg2, $arg3 # second arg (a2-a3) is zero?
+ beqz t0, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+
+ $preinstr # optional op
+ $instr # result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vAA/vAA+1 <- $result0/$result1
+
+%def binopWide2addr(preinstr="", result0="a0", result1="a1", chkzero="0", arg0="a0", arg1="a1", arg2="a2", arg3="a3", instr=""):
+ /*
+ * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0-a1 op a2-a3".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register pair other than a0-a1, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vB (a2-a3). Useful for integer division and modulus.
+ *
+ * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
+ * and-long/2addr, or-long/2addr, xor-long/2addr
+ */
+ /* binop/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a1) # a1 <- B
+ EAS2(a1, rFP, a1) # a1 <- &fp[B]
+ EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
+ LOAD64($arg2, $arg3, a1) # a2/a3 <- vB/vB+1
+ LOAD64($arg0, $arg1, t0) # a0/a1 <- vA/vA+1
+ .if $chkzero
+ or t0, $arg2, $arg3 # second arg (a2-a3) is zero?
+ beqz t0, common_errDivideByZero
+ .endif
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+ $preinstr # optional op
+ $instr # result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- $result0/$result1
+
+%def unop(preinstr="", result0="a0", instr=""):
+ /*
+ * Generic 32-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result0 = op a0".
+ * This could be a MIPS instruction or a function call.
+ *
+ * for: int-to-byte, int-to-char, int-to-short,
+ * neg-int, not-int, neg-float
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(t0) # t0 <- A+
+ GET_VREG(a0, a3) # a0 <- vB
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # a0 <- op, a0-a3 changed
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ SET_VREG_GOTO($result0, t0, t1) # vA <- result0
+
+%def unopNarrower(load="LOAD64_F(fa0, fa0f, a3)", instr=""):
+ /*
+ * Generic 64bit-to-32bit floating-point unary operation. Provide an "instr"
+ * line that specifies an instruction that performs "fv0 = op fa0".
+ *
+ * For: double-to-float
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+ $load
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $instr
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- fv0
+
+%def unopWide(preinstr="", result0="a0", result1="a1", instr=""):
+ /*
+ * Generic 64-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result0/result1 = op a0/a1".
+ * This could be MIPS instruction or a function call.
+ *
+ * For: neg-long, not-long, neg-double,
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+ LOAD64(a0, a1, a3) # a0/a1 <- vA
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # a0/a1 <- op, a2-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- a0/a1
+
+%def unopWider(preinstr="", result0="a0", result1="a1", instr=""):
+ /*
+ * Generic 32bit-to-64bit unary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result0/result1 = op a0".
+ *
+ * For: int-to-long
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG(a0, a3) # a0 <- vB
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # result <- op, a0-a3 changed
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- a0/a1
+
+%def op_add_int():
+% binop(instr="addu a0, a0, a1")
+
+%def op_add_int_2addr():
+% binop2addr(instr="addu a0, a0, a1")
+
+%def op_add_int_lit16():
+% binopLit16(instr="addu a0, a0, a1")
+
+%def op_add_int_lit8():
+% binopLit8(instr="addu a0, a0, a1")
+
+%def op_add_long():
+/*
+ * The compiler generates the following sequence for
+ * [v1 v0] = [a1 a0] + [a3 a2];
+ * addu v0,a2,a0
+ * addu a1,a3,a1
+ * sltu v1,v0,a2
+ * addu v1,v1,a1
+ */
+% binopWide(result0="v0", result1="v1", preinstr="addu v0, a2, a0", instr="addu a1, a3, a1; sltu v1, v0, a2; addu v1, v1, a1")
+
+%def op_add_long_2addr():
+/*
+ * See op_add_long.S for details
+ */
+% binopWide2addr(result0="v0", result1="v1", preinstr="addu v0, a2, a0", instr="addu a1, a3, a1; sltu v1, v0, a2; addu v1, v1, a1")
+
+%def op_and_int():
+% binop(instr="and a0, a0, a1")
+
+%def op_and_int_2addr():
+% binop2addr(instr="and a0, a0, a1")
+
+%def op_and_int_lit16():
+% binopLit16(instr="and a0, a0, a1")
+
+%def op_and_int_lit8():
+% binopLit8(instr="and a0, a0, a1")
+
+%def op_and_long():
+% binopWide(preinstr="and a0, a0, a2", instr="and a1, a1, a3")
+
+%def op_and_long_2addr():
+% binopWide2addr(preinstr="and a0, a0, a2", instr="and a1, a1, a3")
+
+%def op_cmp_long():
+ /*
+ * Compare two 64-bit values
+ * x = y return 0
+ * x < y return -1
+ * x > y return 1
+ *
+ * I think I can improve on the ARM code by the following observation
+ * slt t0, x.hi, y.hi; # (x.hi < y.hi) ? 1:0
+ * sgt t1, x.hi, y.hi; # (y.hi > x.hi) ? 1:0
+ * subu v0, t0, t1 # v0= -1:1:0 for [ < > = ]
+ */
+ /* cmp-long vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8 # a3 <- CC
+ EAS2(a2, rFP, a2) # a2 <- &fp[BB]
+ EAS2(a3, rFP, a3) # a3 <- &fp[CC]
+ LOAD64(a0, a1, a2) # a0/a1 <- vBB/vBB+1
+ LOAD64(a2, a3, a3) # a2/a3 <- vCC/vCC+1
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ slt t0, a1, a3 # compare hi
+ sgt t1, a1, a3
+ subu v0, t1, t0 # v0 <- (-1, 1, 0)
+ bnez v0, .L${opcode}_finish
+ # at this point x.hi==y.hi
+ sltu t0, a0, a2 # compare lo
+ sgtu t1, a0, a2
+ subu v0, t1, t0 # v0 <- (-1, 1, 0) for [< > =]
+
+.L${opcode}_finish:
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(v0, rOBJ, t0) # vAA <- v0
+
+%def op_div_int():
+#ifdef MIPS32REVGE6
+% binop(instr="div a0, a0, a1", chkzero="1")
+#else
+% binop(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
+#endif
+
+%def op_div_int_2addr():
+#ifdef MIPS32REVGE6
+% binop2addr(instr="div a0, a0, a1", chkzero="1")
+#else
+% binop2addr(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
+#endif
+
+%def op_div_int_lit16():
+#ifdef MIPS32REVGE6
+% binopLit16(instr="div a0, a0, a1", chkzero="1")
+#else
+% binopLit16(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
+#endif
+
+%def op_div_int_lit8():
+#ifdef MIPS32REVGE6
+% binopLit8(instr="div a0, a0, a1", chkzero="1")
+#else
+% binopLit8(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
+#endif
+
+%def op_div_long():
+% binopWide(result0="v0", result1="v1", instr="JAL(__divdi3)", chkzero="1")
+
+%def op_div_long_2addr():
+% binopWide2addr(result0="v0", result1="v1", instr="JAL(__divdi3)", chkzero="1")
+
+%def op_int_to_byte():
+% unop(instr="SEB(a0, a0)")
+
+%def op_int_to_char():
+% unop(preinstr="", instr="and a0, 0xffff")
+
+%def op_int_to_long():
+% unopWider(instr="sra a1, a0, 31")
+
+%def op_int_to_short():
+% unop(instr="SEH(a0, a0)")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+% binop(instr="mul a0, a0, a1")
+
+%def op_mul_int_2addr():
+% binop2addr(instr="mul a0, a0, a1")
+
+%def op_mul_int_lit16():
+% binopLit16(instr="mul a0, a0, a1")
+
+%def op_mul_int_lit8():
+% binopLit8(instr="mul a0, a0, a1")
+
+%def op_mul_long():
+ /*
+ * Signed 64-bit integer multiply.
+ * a1 a0
+ * x a3 a2
+ * -------------
+ * a2a1 a2a0
+ * a3a0
+ * a3a1 (<= unused)
+ * ---------------
+ * v1 v0
+ */
+ /* mul-long vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ and t0, a0, 255 # a2 <- BB
+ srl t1, a0, 8 # a3 <- CC
+ EAS2(t0, rFP, t0) # t0 <- &fp[BB]
+ LOAD64(a0, a1, t0) # a0/a1 <- vBB/vBB+1
+
+ EAS2(t1, rFP, t1) # t0 <- &fp[CC]
+ LOAD64(a2, a3, t1) # a2/a3 <- vCC/vCC+1
+
+ mul v1, a3, a0 # v1= a3a0
+#ifdef MIPS32REVGE6
+ mulu v0, a2, a0 # v0= a2a0
+ muhu t1, a2, a0
+#else
+ multu a2, a0
+ mfhi t1
+ mflo v0 # v0= a2a0
+#endif
+ mul t0, a2, a1 # t0= a2a1
+ addu v1, v1, t1 # v1+= hi(a2a0)
+ addu v1, v1, t0 # v1= a3a0 + a2a1;
+
+ GET_OPA(a0) # a0 <- AA
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ b .L${opcode}_finish
+%def op_mul_long_sister_code():
+
+.L${opcode}_finish:
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(v0, v1, a0, t0) # vAA/vAA+1 <- v0(low)/v1(high)
+
+%def op_mul_long_2addr():
+ /*
+ * See op_mul_long.S for more details
+ */
+ /* mul-long/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+
+ EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
+ LOAD64(a0, a1, t0) # vAA.low / high
+
+ GET_OPB(t1) # t1 <- B
+ EAS2(t1, rFP, t1) # t1 <- &fp[B]
+ LOAD64(a2, a3, t1) # vBB.low / high
+
+ mul v1, a3, a0 # v1= a3a0
+#ifdef MIPS32REVGE6
+ mulu v0, a2, a0 # v0= a2a0
+ muhu t1, a2, a0
+#else
+ multu a2, a0
+ mfhi t1
+ mflo v0 # v0= a2a0
+ #endif
+ mul t2, a2, a1 # t2= a2a1
+ addu v1, v1, t1 # v1= a3a0 + hi(a2a0)
+ addu v1, v1, t2 # v1= v1 + a2a1;
+
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ SET_VREG64_GOTO(v0, v1, rOBJ, t1) # vA/vA+1 <- v0(low)/v1(high)
+
+%def op_neg_int():
+% unop(instr="negu a0, a0")
+
+%def op_neg_long():
+% unopWide(result0="v0", result1="v1", preinstr="negu v0, a0", instr="negu v1, a1; sltu a0, zero, v0; subu v1, v1, a0")
+
+%def op_not_int():
+% unop(instr="not a0, a0")
+
+%def op_not_long():
+% unopWide(preinstr="not a0, a0", instr="not a1, a1")
+
+%def op_or_int():
+% binop(instr="or a0, a0, a1")
+
+%def op_or_int_2addr():
+% binop2addr(instr="or a0, a0, a1")
+
+%def op_or_int_lit16():
+% binopLit16(instr="or a0, a0, a1")
+
+%def op_or_int_lit8():
+% binopLit8(instr="or a0, a0, a1")
+
+%def op_or_long():
+% binopWide(preinstr="or a0, a0, a2", instr="or a1, a1, a3")
+
+%def op_or_long_2addr():
+% binopWide2addr(preinstr="or a0, a0, a2", instr="or a1, a1, a3")
+
+%def op_rem_int():
+#ifdef MIPS32REVGE6
+% binop(instr="mod a0, a0, a1", chkzero="1")
+#else
+% binop(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
+#endif
+
+%def op_rem_int_2addr():
+#ifdef MIPS32REVGE6
+% binop2addr(instr="mod a0, a0, a1", chkzero="1")
+#else
+% binop2addr(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
+#endif
+
+%def op_rem_int_lit16():
+#ifdef MIPS32REVGE6
+% binopLit16(instr="mod a0, a0, a1", chkzero="1")
+#else
+% binopLit16(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
+#endif
+
+%def op_rem_int_lit8():
+#ifdef MIPS32REVGE6
+% binopLit8(instr="mod a0, a0, a1", chkzero="1")
+#else
+% binopLit8(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
+#endif
+
+%def op_rem_long():
+% binopWide(result0="v0", result1="v1", instr="JAL(__moddi3)", chkzero="1")
+
+%def op_rem_long_2addr():
+% binopWide2addr(result0="v0", result1="v1", instr="JAL(__moddi3)", chkzero="1")
+
+%def op_rsub_int():
+/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
+% binopLit16(instr="subu a0, a1, a0")
+
+%def op_rsub_int_lit8():
+% binopLit8(instr="subu a0, a1, a0")
+
+%def op_shl_int():
+% binop(instr="sll a0, a0, a1")
+
+%def op_shl_int_2addr():
+% binop2addr(instr="sll a0, a0, a1")
+
+%def op_shl_int_lit8():
+% binopLit8(instr="sll a0, a0, a1")
+
+%def op_shl_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* shl-long vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(t2) # t2 <- AA
+ and a3, a0, 255 # a3 <- BB
+ srl a0, a0, 8 # a0 <- CC
+ EAS2(a3, rFP, a3) # a3 <- &fp[BB]
+ GET_VREG(a2, a0) # a2 <- vCC
+ LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v1, a2, 0x20 # shift< shift & 0x20
+ sll v0, a0, a2 # rlo<- alo << (shift&31)
+ bnez v1, .L${opcode}_finish
+ not v1, a2 # rhi<- 31-shift (shift is 5b)
+ srl a0, 1
+ srl a0, v1 # alo<- alo >> (32-(shift&31))
+ sll v1, a1, a2 # rhi<- ahi << (shift&31)
+ or v1, a0 # rhi<- rhi | alo
+ SET_VREG64_GOTO(v0, v1, t2, t0) # vAA/vAA+1 <- v0/v1
+%def op_shl_long_sister_code():
+
+.L${opcode}_finish:
+ SET_VREG64_GOTO(zero, v0, t2, t0) # vAA/vAA+1 <- rlo/rhi
+
+%def op_shl_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shl-long/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG(a2, a3) # a2 <- vB
+ EAS2(t2, rFP, rOBJ) # t2 <- &fp[A]
+ LOAD64(a0, a1, t2) # a0/a1 <- vA/vA+1
+
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v1, a2, 0x20 # shift< shift & 0x20
+ sll v0, a0, a2 # rlo<- alo << (shift&31)
+ bnez v1, .L${opcode}_finish
+ not v1, a2 # rhi<- 31-shift (shift is 5b)
+ srl a0, 1
+ srl a0, v1 # alo<- alo >> (32-(shift&31))
+ sll v1, a1, a2 # rhi<- ahi << (shift&31)
+ or v1, a0 # rhi<- rhi | alo
+ SET_VREG64_GOTO(v0, v1, rOBJ, t0) # vA/vA+1 <- v0/v1
+%def op_shl_long_2addr_sister_code():
+
+.L${opcode}_finish:
+ SET_VREG64_GOTO(zero, v0, rOBJ, t0) # vA/vA+1 <- rlo/rhi
+
+%def op_shr_int():
+% binop(instr="sra a0, a0, a1")
+
+%def op_shr_int_2addr():
+% binop2addr(instr="sra a0, a0, a1")
+
+%def op_shr_int_lit8():
+% binopLit8(instr="sra a0, a0, a1")
+
+%def op_shr_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* shr-long vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(t3) # t3 <- AA
+ and a3, a0, 255 # a3 <- BB
+ srl a0, a0, 8 # a0 <- CC
+ EAS2(a3, rFP, a3) # a3 <- &fp[BB]
+ GET_VREG(a2, a0) # a2 <- vCC
+ LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v0, a2, 0x20 # shift & 0x20
+ sra v1, a1, a2 # rhi<- ahi >> (shift&31)
+ bnez v0, .L${opcode}_finish
+ srl v0, a0, a2 # rlo<- alo >> (shift&31)
+ not a0, a2 # alo<- 31-shift (shift is 5b)
+ sll a1, 1
+ sll a1, a0 # ahi<- ahi << (32-(shift&31))
+ or v0, a1 # rlo<- rlo | ahi
+ SET_VREG64_GOTO(v0, v1, t3, t0) # vAA/VAA+1 <- v0/v1
+%def op_shr_long_sister_code():
+
+.L${opcode}_finish:
+ sra a3, a1, 31 # a3<- sign(ah)
+ SET_VREG64_GOTO(v1, a3, t3, t0) # vAA/VAA+1 <- rlo/rhi
+
+%def op_shr_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shr-long/2addr vA, vB */
+ GET_OPA4(t2) # t2 <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG(a2, a3) # a2 <- vB
+ EAS2(t0, rFP, t2) # t0 <- &fp[A]
+ LOAD64(a0, a1, t0) # a0/a1 <- vA/vA+1
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v0, a2, 0x20 # shift & 0x20
+ sra v1, a1, a2 # rhi<- ahi >> (shift&31)
+ bnez v0, .L${opcode}_finish
+ srl v0, a0, a2 # rlo<- alo >> (shift&31)
+ not a0, a2 # alo<- 31-shift (shift is 5b)
+ sll a1, 1
+ sll a1, a0 # ahi<- ahi << (32-(shift&31))
+ or v0, a1 # rlo<- rlo | ahi
+ SET_VREG64_GOTO(v0, v1, t2, t0) # vA/vA+1 <- v0/v1
+%def op_shr_long_2addr_sister_code():
+
+.L${opcode}_finish:
+ sra a3, a1, 31 # a3<- sign(ah)
+ SET_VREG64_GOTO(v1, a3, t2, t0) # vA/vA+1 <- rlo/rhi
+
+%def op_sub_int():
+% binop(instr="subu a0, a0, a1")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="subu a0, a0, a1")
+
+%def op_sub_long():
+/*
+ * For little endian the code sequence looks as follows:
+ * subu v0,a0,a2
+ * subu v1,a1,a3
+ * sltu a0,a0,v0
+ * subu v1,v1,a0
+ */
+% binopWide(result0="v0", result1="v1", preinstr="subu v0, a0, a2", instr="subu v1, a1, a3; sltu a0, a0, v0; subu v1, v1, a0")
+
+%def op_sub_long_2addr():
+/*
+ * See op_sub_long.S for more details
+ */
+% binopWide2addr(result0="v0", result1="v1", preinstr="subu v0, a0, a2", instr="subu v1, a1, a3; sltu a0, a0, v0; subu v1, v1, a0")
+
+%def op_ushr_int():
+% binop(instr="srl a0, a0, a1")
+
+%def op_ushr_int_2addr():
+% binop2addr(instr="srl a0, a0, a1 ")
+
+%def op_ushr_int_lit8():
+% binopLit8(instr="srl a0, a0, a1")
+
+%def op_ushr_long():
+ /*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance.
+ */
+ /* ushr-long vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a3, a0, 255 # a3 <- BB
+ srl a0, a0, 8 # a0 <- CC
+ EAS2(a3, rFP, a3) # a3 <- &fp[BB]
+ GET_VREG(a2, a0) # a2 <- vCC
+ LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v0, a2, 0x20 # shift & 0x20
+ srl v1, a1, a2 # rhi<- ahi >> (shift&31)
+ bnez v0, .L${opcode}_finish
+ srl v0, a0, a2 # rlo<- alo >> (shift&31)
+ not a0, a2 # alo<- 31-n (shift is 5b)
+ sll a1, 1
+ sll a1, a0 # ahi<- ahi << (32-(shift&31))
+ or v0, a1 # rlo<- rlo | ahi
+ SET_VREG64_GOTO(v0, v1, rOBJ, t0) # vAA/vAA+1 <- v0/v1
+%def op_ushr_long_sister_code():
+
+.L${opcode}_finish:
+ SET_VREG64_GOTO(v1, zero, rOBJ, t0) # vAA/vAA+1 <- rlo/rhi
+
+%def op_ushr_long_2addr():
+ /*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* ushr-long/2addr vA, vB */
+ GET_OPA4(t3) # t3 <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG(a2, a3) # a2 <- vB
+ EAS2(t0, rFP, t3) # t0 <- &fp[A]
+ LOAD64(a0, a1, t0) # a0/a1 <- vA/vA+1
+
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+
+ andi v0, a2, 0x20 # shift & 0x20
+ srl v1, a1, a2 # rhi<- ahi >> (shift&31)
+ bnez v0, .L${opcode}_finish
+ srl v0, a0, a2 # rlo<- alo >> (shift&31)
+ not a0, a2 # alo<- 31-n (shift is 5b)
+ sll a1, 1
+ sll a1, a0 # ahi<- ahi << (32-(shift&31))
+ or v0, a1 # rlo<- rlo | ahi
+ SET_VREG64_GOTO(v0, v1, t3, t0) # vA/vA+1 <- v0/v1
+%def op_ushr_long_2addr_sister_code():
+
+.L${opcode}_finish:
+ SET_VREG64_GOTO(v1, zero, t3, t0) # vA/vA+1 <- rlo/rhi
+
+%def op_xor_int():
+% binop(instr="xor a0, a0, a1")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="xor a0, a0, a1")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="xor a0, a0, a1")
+
+%def op_xor_int_lit8():
+% binopLit8(instr="xor a0, a0, a1")
+
+%def op_xor_long():
+% binopWide(preinstr="xor a0, a0, a2", instr="xor a1, a1, a3")
+
+%def op_xor_long_2addr():
+% binopWide2addr(preinstr="xor a0, a0, a2", instr="xor a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/array.S b/runtime/interpreter/mterp/mips/array.S
new file mode 100644
index 0000000..57ab147
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/array.S
@@ -0,0 +1,239 @@
+%def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
+ * instructions. We use a pair of FETCH_Bs instead.
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short
+ *
+ * NOTE: assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B(a2, 1, 0) # a2 <- BB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ FETCH_B(a3, 1, 1) # a3 <- CC
+ GET_VREG(a0, a2) # a0 <- vBB (array object)
+ GET_VREG(a1, a3) # a1 <- vCC (requested index)
+ # null array object?
+ beqz a0, common_errNullObject # yes, bail
+ LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
+ EASN(a0, a0, a1, $shift) # a0 <- arrayObj + index*width
+ # a1 >= a3; compare unsigned index
+ bgeu a1, a3, common_errArrayIndex # index >= length, bail
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ $load a2, $data_offset(a0) # a2 <- vBB[vCC]
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a2, rOBJ, t0) # vAA <- a2
+
+%def op_aget_boolean():
+% op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+ /*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B(a2, 1, 0) # a2 <- BB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ FETCH_B(a3, 1, 1) # a3 <- CC
+ EXPORT_PC()
+ GET_VREG(a0, a2) # a0 <- vBB (array object)
+ GET_VREG(a1, a3) # a1 <- vCC (requested index)
+ JAL(artAGetObjectFromMterp) # v0 <- GetObj(array, index)
+ lw a1, THREAD_EXCEPTION_OFFSET(rSELF)
+ PREFETCH_INST(2) # load rINST
+ bnez a1, MterpException
+ ADVANCE(2) # advance rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_OBJECT_GOTO(v0, rOBJ, t0) # vAA <- v0
+
+%def op_aget_short():
+% op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+ /*
+ * Array get, 64 bits. vAA <- vBB[vCC].
+ *
+ * Arrays of long/double are 64-bit aligned.
+ */
+ /* aget-wide vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8 # a3 <- CC
+ GET_VREG(a0, a2) # a0 <- vBB (array object)
+ GET_VREG(a1, a3) # a1 <- vCC (requested index)
+ # null array object?
+ beqz a0, common_errNullObject # yes, bail
+ LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
+ EAS3(a0, a0, a1) # a0 <- arrayObj + index*width
+ bgeu a1, a3, common_errArrayIndex # index >= length, bail
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ LOAD64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET)
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a2, a3, rOBJ, t0) # vAA/vAA+1 <- a2/a3
+
+%def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+
+ /*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short
+ *
+ * NOTE: this assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ FETCH_B(a2, 1, 0) # a2 <- BB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ FETCH_B(a3, 1, 1) # a3 <- CC
+ GET_VREG(a0, a2) # a0 <- vBB (array object)
+ GET_VREG(a1, a3) # a1 <- vCC (requested index)
+ # null array object?
+ beqz a0, common_errNullObject # yes, bail
+ LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
+ EASN(a0, a0, a1, $shift) # a0 <- arrayObj + index*width
+ bgeu a1, a3, common_errArrayIndex # index >= length, bail
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_VREG(a2, rOBJ) # a2 <- vAA
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GET_OPCODE_TARGET(t0)
+ $store a2, $data_offset(a0) # vBB[vCC] <- a2
+ JR(t0) # jump to next instruction
+
+%def op_aput_boolean():
+% op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+ /*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ *
+ */
+ /* op vAA, vBB, vCC */
+ EXPORT_PC()
+ addu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ JAL(MterpAputObject)
+ beqz v0, MterpPossibleException
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_aput_short():
+% op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+ /*
+ * Array put, 64 bits. vBB[vCC] <- vAA.
+ */
+ /* aput-wide vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(t0) # t0 <- AA
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8 # a3 <- CC
+ GET_VREG(a0, a2) # a0 <- vBB (array object)
+ GET_VREG(a1, a3) # a1 <- vCC (requested index)
+ # null array object?
+ beqz a0, common_errNullObject # yes, bail
+ LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
+ EAS3(a0, a0, a1) # a0 <- arrayObj + index*width
+ EAS2(rOBJ, rFP, t0) # rOBJ <- &fp[AA]
+ # compare unsigned index, length
+ bgeu a1, a3, common_errArrayIndex # index >= length, bail
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ LOAD64(a2, a3, rOBJ) # a2/a3 <- vAA/vAA+1
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GET_OPCODE_TARGET(t0)
+ STORE64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET) # a2/a3 <- vBB[vCC]
+ JR(t0) # jump to next instruction
+
+%def op_array_length():
+ /*
+ * Return the length of an array.
+ */
+ /* array-length vA, vB */
+ GET_OPB(a1) # a1 <- B
+ GET_OPA4(a2) # a2 <- A+
+ GET_VREG(a0, a1) # a0 <- vB (object ref)
+ # is object null?
+ beqz a0, common_errNullObject # yup, fail
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ LOAD_base_offMirrorArray_length(a3, a0) # a3 <- array length
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a3, a2, t0) # vA <- length
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ EXPORT_PC()
+ FETCH(a1, 1) # a1 <- bbbb (lo)
+ FETCH(a0, 2) # a0 <- BBBB (hi)
+ GET_OPA(a3) # a3 <- AA
+ INSERT_HIGH_HALF(a1, a0) # a1 <- BBBBbbbb
+ GET_VREG(a0, a3) # a0 <- vAA (array object)
+ EAS1(a1, rPC, a1) # a1 <- PC + BBBBbbbb*2 (array data off.)
+ JAL(MterpFillArrayData) # v0 <- Mterp(obj, payload)
+ beqz v0, MterpPossibleException # has exception
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+ /*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
+ .extern $helper
+ EXPORT_PC()
+ addu a0, rFP, OFF_FP_SHADOWFRAME # a0 <- shadow frame
+ move a1, rPC
+ move a2, rSELF
+ JAL($helper) # v0 <- helper(shadow_frame, pc, self)
+ beqz v0, MterpPossibleException # has exception
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+ /*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class@CCCC */
+ EXPORT_PC()
+ addu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ move a3, rSELF
+ JAL(MterpNewArray)
+ beqz v0, MterpPossibleException
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/bincmp.S b/runtime/interpreter/mterp/mips/bincmp.S
deleted file mode 100644
index b4b671f..0000000
--- a/runtime/interpreter/mterp/mips/bincmp.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def bincmp(condition=""):
- /*
- * Generic two-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- GET_OPA4(a0) # a0 <- A+
- GET_OPB(a1) # a1 <- B
- GET_VREG(a3, a1) # a3 <- vB
- GET_VREG(a0, a0) # a0 <- vA
- FETCH_S(rINST, 1) # rINST<- branch offset, in code units
- b${condition} a0, a3, MterpCommonTakenBranchNoFlags # compare (vA, vB)
- li t0, JIT_CHECK_OSR
- beq rPROFILE, t0, .L_check_not_taken_osr
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/binop.S b/runtime/interpreter/mterp/mips/binop.S
deleted file mode 100644
index 062b22d..0000000
--- a/runtime/interpreter/mterp/mips/binop.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def binop(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = a0 op a1".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (INT_MIN / -1) here, because the CPU handles it
- * correctly.
- *
- * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
- * xor-int, shl-int, shr-int, ushr-int
- */
- /* binop vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- srl a3, a0, 8 # a3 <- CC
- and a2, a0, 255 # a2 <- BB
- GET_VREG(a1, a3) # a1 <- vCC
- GET_VREG(a0, a2) # a0 <- vBB
- .if $chkzero
- # is second operand zero?
- beqz a1, common_errDivideByZero
- .endif
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO($result, rOBJ, t0) # vAA <- $result
diff --git a/runtime/interpreter/mterp/mips/binop2addr.S b/runtime/interpreter/mterp/mips/binop2addr.S
deleted file mode 100644
index 89af6e1..0000000
--- a/runtime/interpreter/mterp/mips/binop2addr.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def binop2addr(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be an MIPS instruction or a function call.
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus.
- *
- * 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
- */
- /* binop/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG(a0, rOBJ) # a0 <- vA
- GET_VREG(a1, a3) # a1 <- vB
- .if $chkzero
- # is second operand zero?
- beqz a1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO($result, rOBJ, t0) # vA <- $result
diff --git a/runtime/interpreter/mterp/mips/binopLit16.S b/runtime/interpreter/mterp/mips/binopLit16.S
deleted file mode 100644
index 9ae0da7..0000000
--- a/runtime/interpreter/mterp/mips/binopLit16.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def binopLit16(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit16" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be an MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus.
- *
- * 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(a1, 1) # a1 <- ssssCCCC (sign-extended)
- GET_OPB(a2) # a2 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_VREG(a0, a2) # a0 <- vB
- .if $chkzero
- # cmp a1, 0; is second operand zero?
- beqz a1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
-
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO($result, rOBJ, t0) # vA <- $result
diff --git a/runtime/interpreter/mterp/mips/binopLit8.S b/runtime/interpreter/mterp/mips/binopLit8.S
deleted file mode 100644
index ecf08c2..0000000
--- a/runtime/interpreter/mterp/mips/binopLit8.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binopLit8(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit8" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be an MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus.
- *
- * 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(a3, 1) # a3 <- ssssCCBB (sign-extended for CC)
- GET_OPA(rOBJ) # rOBJ <- AA
- and a2, a3, 255 # a2 <- BB
- GET_VREG(a0, a2) # a0 <- vBB
- sra a1, a3, 8 # a1 <- ssssssCC (sign extended)
- .if $chkzero
- # is second operand zero?
- beqz a1, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
-
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO($result, rOBJ, t0) # vAA <- $result
diff --git a/runtime/interpreter/mterp/mips/binopWide.S b/runtime/interpreter/mterp/mips/binopWide.S
deleted file mode 100644
index 5768e95..0000000
--- a/runtime/interpreter/mterp/mips/binopWide.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def binopWide(preinstr="", result0="a0", result1="a1", chkzero="0", arg0="a0", arg1="a1", arg2="a2", arg3="a3", instr=""):
- /*
- * Generic 64-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = a0-a1 op a2-a3".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register pair other than a0-a1, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a2-a3). Useful for integer division and modulus.
- *
- * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
- * xor-long
- *
- * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
- */
- /* binop vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8 # a3 <- CC
- EAS2(a2, rFP, a2) # a2 <- &fp[BB]
- EAS2(t1, rFP, a3) # a3 <- &fp[CC]
- LOAD64($arg0, $arg1, a2) # a0/a1 <- vBB/vBB+1
- LOAD64($arg2, $arg3, t1) # a2/a3 <- vCC/vCC+1
- .if $chkzero
- or t0, $arg2, $arg3 # second arg (a2-a3) is zero?
- beqz t0, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
-
- $preinstr # optional op
- $instr # result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vAA/vAA+1 <- $result0/$result1
diff --git a/runtime/interpreter/mterp/mips/binopWide2addr.S b/runtime/interpreter/mterp/mips/binopWide2addr.S
deleted file mode 100644
index 4e00c81..0000000
--- a/runtime/interpreter/mterp/mips/binopWide2addr.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binopWide2addr(preinstr="", result0="a0", result1="a1", chkzero="0", arg0="a0", arg1="a1", arg2="a2", arg3="a3", instr=""):
- /*
- * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0-a1 op a2-a3".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register pair other than a0-a1, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vB (a2-a3). Useful for integer division and modulus.
- *
- * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
- * and-long/2addr, or-long/2addr, xor-long/2addr
- */
- /* binop/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a1) # a1 <- B
- EAS2(a1, rFP, a1) # a1 <- &fp[B]
- EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
- LOAD64($arg2, $arg3, a1) # a2/a3 <- vB/vB+1
- LOAD64($arg0, $arg1, t0) # a0/a1 <- vA/vA+1
- .if $chkzero
- or t0, $arg2, $arg3 # second arg (a2-a3) is zero?
- beqz t0, common_errDivideByZero
- .endif
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
- $preinstr # optional op
- $instr # result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- $result0/$result1
diff --git a/runtime/interpreter/mterp/mips/const.S b/runtime/interpreter/mterp/mips/const.S
deleted file mode 100644
index 403dfc7..0000000
--- a/runtime/interpreter/mterp/mips/const.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- BBBB
- GET_OPA(a1) # a1 <- AA
- addu a2, rFP, OFF_FP_SHADOWFRAME # a2 <- shadow frame
- move a3, rSELF
- JAL($helper) # v0 <- Mterp(index, tgt_reg, shadow_frame, self)
- PREFETCH_INST(2) # load rINST
- bnez v0, MterpPossibleException
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/control_flow.S b/runtime/interpreter/mterp/mips/control_flow.S
new file mode 100644
index 0000000..88e1f0e
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/control_flow.S
@@ -0,0 +1,214 @@
+%def bincmp(condition=""):
+ /*
+ * Generic two-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ GET_OPA4(a0) # a0 <- A+
+ GET_OPB(a1) # a1 <- B
+ GET_VREG(a3, a1) # a3 <- vB
+ GET_VREG(a0, a0) # a0 <- vA
+ FETCH_S(rINST, 1) # rINST<- branch offset, in code units
+ b${condition} a0, a3, MterpCommonTakenBranchNoFlags # compare (vA, vB)
+ li t0, JIT_CHECK_OSR
+ beq rPROFILE, t0, .L_check_not_taken_osr
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def zcmp(condition=""):
+ /*
+ * Generic one-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform.
+ *
+ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ GET_OPA(a0) # a0 <- AA
+ GET_VREG(a0, a0) # a0 <- vAA
+ FETCH_S(rINST, 1) # rINST <- branch offset, in code units
+ b${condition} a0, zero, MterpCommonTakenBranchNoFlags
+ li t0, JIT_CHECK_OSR # possible OSR re-entry?
+ beq rPROFILE, t0, .L_check_not_taken_osr
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_goto():
+ /*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ sll a0, rINST, 16 # a0 <- AAxx0000
+ sra rINST, a0, 24 # rINST <- ssssssAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_16():
+ /*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ FETCH_S(rINST, 1) # rINST <- ssssAAAA (sign-extended)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_32():
+ /*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Unlike most opcodes, this one is allowed to branch to itself, so
+ * our "backward branch" test must be "<=0" instead of "<0".
+ */
+ /* goto/32 +AAAAAAAA */
+ FETCH(rINST, 1) # rINST <- aaaa (lo)
+ FETCH(a1, 2) # a1 <- AAAA (hi)
+ INSERT_HIGH_HALF(rINST, a1) # rINST <- AAAAaaaa
+ b MterpCommonTakenBranchNoFlags
+
+%def op_if_eq():
+% bincmp(condition="eq")
+
+%def op_if_eqz():
+% zcmp(condition="eq")
+
+%def op_if_ge():
+% bincmp(condition="ge")
+
+%def op_if_gez():
+% zcmp(condition="ge")
+
+%def op_if_gt():
+% bincmp(condition="gt")
+
+%def op_if_gtz():
+% zcmp(condition="gt")
+
+%def op_if_le():
+% bincmp(condition="le")
+
+%def op_if_lez():
+% zcmp(condition="le")
+
+%def op_if_lt():
+% bincmp(condition="lt")
+
+%def op_if_ltz():
+% zcmp(condition="lt")
+
+%def op_if_ne():
+% bincmp(condition="ne")
+
+%def op_if_nez():
+% zcmp(condition="ne")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+ /*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBB */
+ FETCH(a0, 1) # a0 <- bbbb (lo)
+ FETCH(a1, 2) # a1 <- BBBB (hi)
+ GET_OPA(a3) # a3 <- AA
+ INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb
+ GET_VREG(a1, a3) # a1 <- vAA
+ EAS1(a0, rPC, a0) # a0 <- PC + BBBBbbbb*2
+ JAL($func) # a0 <- code-unit branch offset
+ move rINST, v0
+ b MterpCommonTakenBranchNoFlags
+
+%def op_return():
+ /*
+ * Return a 32-bit value.
+ *
+ * for: return, return-object
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ JAL(MterpThreadFenceForConstructor)
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqz ra, 1f
+ JAL(MterpSuspendCheck) # (self)
+1:
+ GET_OPA(a2) # a2 <- AA
+ GET_VREG(v0, a2) # v0 <- vAA
+ move v1, zero
+ b MterpReturn
+
+%def op_return_object():
+% op_return()
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ JAL(MterpThreadFenceForConstructor)
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqz ra, 1f
+ JAL(MterpSuspendCheck) # (self)
+1:
+ move v0, zero
+ move v1, zero
+ b MterpReturn
+
+%def op_return_void_no_barrier():
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqz ra, 1f
+ JAL(MterpSuspendCheck) # (self)
+1:
+ move v0, zero
+ move v1, zero
+ b MterpReturn
+
+%def op_return_wide():
+ /*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ .extern MterpThreadFenceForConstructor
+ JAL(MterpThreadFenceForConstructor)
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqz ra, 1f
+ JAL(MterpSuspendCheck) # (self)
+1:
+ GET_OPA(a2) # a2 <- AA
+ EAS2(a2, rFP, a2) # a2 <- &fp[AA]
+ LOAD64(v0, v1, a2) # v0/v1 <- vAA/vAA+1
+ b MterpReturn
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+ /*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC() # exception handler can throw
+ GET_OPA(a2) # a2 <- AA
+ GET_VREG(a1, a2) # a1 <- vAA (exception object)
+ # null object?
+ beqz a1, common_errNullObject # yes, throw an NPE instead
+ sw a1, THREAD_EXCEPTION_OFFSET(rSELF) # thread->exception <- obj
+ b MterpException
diff --git a/runtime/interpreter/mterp/mips/entry.S b/runtime/interpreter/mterp/mips/entry.S
deleted file mode 100644
index e40fc02..0000000
--- a/runtime/interpreter/mterp/mips/entry.S
+++ /dev/null
@@ -1,76 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Interpreter entry point.
- */
-
- .text
- .align 2
- .global ExecuteMterpImpl
- .ent ExecuteMterpImpl
- .frame sp, STACK_SIZE, ra
-/*
- * On entry:
- * a0 Thread* self
- * a1 dex_instructions
- * a2 ShadowFrame
- * a3 JValue* result_register
- *
- */
-
-ExecuteMterpImpl:
- .cfi_startproc
- .set noreorder
- .cpload t9
- .set reorder
-/* Save to the stack. Frame size = STACK_SIZE */
- STACK_STORE_FULL()
-/* This directive will make sure all subsequent jal restore gp at a known offset */
- .cprestore STACK_OFFSET_GP
-
- /* Remember the return register */
- sw a3, SHADOWFRAME_RESULT_REGISTER_OFFSET(a2)
-
- /* Remember the dex instruction pointer */
- sw a1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(a2)
-
- /* set up "named" registers */
- move rSELF, a0
- lw a0, SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(a2)
- addu rFP, a2, SHADOWFRAME_VREGS_OFFSET # point to vregs.
- EAS2(rREFS, rFP, a0) # point to reference array in shadow frame
- lw a0, SHADOWFRAME_DEX_PC_OFFSET(a2) # Get starting dex_pc
- EAS1(rPC, a1, a0) # Create direct pointer to 1st dex opcode
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
-
- EXPORT_PC()
-
- /* Starting ibase */
- lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
-
- /* Set up for backwards branches & osr profiling */
- lw a0, OFF_FP_METHOD(rFP)
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rSELF
- JAL(MterpSetUpHotnessCountdown) # (method, shadow_frame, self)
- move rPROFILE, v0 # Starting hotness countdown to rPROFILE
-
- /* start executing the instruction at rPC */
- FETCH_INST() # load rINST from rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/mips/fallback.S b/runtime/interpreter/mterp/mips/fallback.S
deleted file mode 100644
index 6133d9f..0000000
--- a/runtime/interpreter/mterp/mips/fallback.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/mips/fbinop.S b/runtime/interpreter/mterp/mips/fbinop.S
deleted file mode 100644
index 7cbf73f..0000000
--- a/runtime/interpreter/mterp/mips/fbinop.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def fbinop(instr=""):
- /*
- * Generic 32-bit binary float operation.
- *
- * For: add-fp, sub-fp, mul-fp, div-fp, rem-fp
- */
-
- /* binop vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- srl a3, a0, 8 # a3 <- CC
- and a2, a0, 255 # a2 <- BB
- GET_VREG_F(fa1, a3) # a1 <- vCC
- GET_VREG_F(fa0, a2) # a0 <- vBB
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- $instr # f0 = result
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_F_GOTO(fv0, rOBJ, t0) # vAA <- fv0
diff --git a/runtime/interpreter/mterp/mips/fbinop2addr.S b/runtime/interpreter/mterp/mips/fbinop2addr.S
deleted file mode 100644
index ea9970f..0000000
--- a/runtime/interpreter/mterp/mips/fbinop2addr.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def fbinop2addr(instr=""):
- /*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr"
- * that specifies an instruction that performs "fv0 = fa0 op fa1".
- * This could be an MIPS instruction or a function call.
- *
- * For: add-float/2addr, sub-float/2addr, mul-float/2addr,
- * div-float/2addr, rem-float/2addr
- */
- /* binop/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG_F(fa0, rOBJ)
- GET_VREG_F(fa1, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
- $instr
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- result
diff --git a/runtime/interpreter/mterp/mips/fbinopWide.S b/runtime/interpreter/mterp/mips/fbinopWide.S
deleted file mode 100644
index 1b5c0c1..0000000
--- a/runtime/interpreter/mterp/mips/fbinopWide.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def fbinopWide(instr=""):
- /*
- * Generic 64-bit floating-point binary operation. Provide an "instr"
- * line that specifies an instruction that performs "fv0 = fa0 op fa1".
- * This could be an MIPS instruction or a function call.
- *
- * for: add-double, sub-double, mul-double, div-double,
- * rem-double
- *
- */
- /* binop vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8 # a3 <- CC
- EAS2(a2, rFP, a2) # a2 <- &fp[BB]
- EAS2(t1, rFP, a3) # a3 <- &fp[CC]
- LOAD64_F(fa0, fa0f, a2)
- LOAD64_F(fa1, fa1f, t1)
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- $instr
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vAA/vAA+1 <- fv0
diff --git a/runtime/interpreter/mterp/mips/fbinopWide2addr.S b/runtime/interpreter/mterp/mips/fbinopWide2addr.S
deleted file mode 100644
index e36f1f8..0000000
--- a/runtime/interpreter/mterp/mips/fbinopWide2addr.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def fbinopWide2addr(instr=""):
- /*
- * Generic 64-bit floating-point "/2addr" binary operation.
- * Provide an "instr" line that specifies an instruction that
- * performs "fv0 = fa0 op fa1".
- * This could be an MIPS instruction or a function call.
- *
- * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
- * div-double/2addr, rem-double/2addr
- */
- /* binop/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a1) # a1 <- B
- EAS2(a1, rFP, a1) # a1 <- &fp[B]
- EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
- LOAD64_F(fa0, fa0f, t0)
- LOAD64_F(fa1, fa1f, a1)
-
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $instr
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- fv0
diff --git a/runtime/interpreter/mterp/mips/field.S b/runtime/interpreter/mterp/mips/field.S
deleted file mode 100644
index d61b06a..0000000
--- a/runtime/interpreter/mterp/mips/field.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def field(helper=""):
-TODO
diff --git a/runtime/interpreter/mterp/mips/floating_point.S b/runtime/interpreter/mterp/mips/floating_point.S
new file mode 100644
index 0000000..6f0dda3
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/floating_point.S
@@ -0,0 +1,518 @@
+%def fbinop(instr=""):
+ /*
+ * Generic 32-bit binary float operation.
+ *
+ * For: add-fp, sub-fp, mul-fp, div-fp, rem-fp
+ */
+
+ /* binop vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ srl a3, a0, 8 # a3 <- CC
+ and a2, a0, 255 # a2 <- BB
+ GET_VREG_F(fa1, a3) # a1 <- vCC
+ GET_VREG_F(fa0, a2) # a0 <- vBB
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ $instr # f0 = result
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_F_GOTO(fv0, rOBJ, t0) # vAA <- fv0
+
+%def fbinop2addr(instr=""):
+ /*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr"
+ * that specifies an instruction that performs "fv0 = fa0 op fa1".
+ * This could be an MIPS instruction or a function call.
+ *
+ * For: add-float/2addr, sub-float/2addr, mul-float/2addr,
+ * div-float/2addr, rem-float/2addr
+ */
+ /* binop/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG_F(fa0, rOBJ)
+ GET_VREG_F(fa1, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+ $instr
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- result
+
+%def fbinopWide(instr=""):
+ /*
+ * Generic 64-bit floating-point binary operation. Provide an "instr"
+ * line that specifies an instruction that performs "fv0 = fa0 op fa1".
+ * This could be an MIPS instruction or a function call.
+ *
+ * for: add-double, sub-double, mul-double, div-double,
+ * rem-double
+ *
+ */
+ /* binop vAA, vBB, vCC */
+ FETCH(a0, 1) # a0 <- CCBB
+ GET_OPA(rOBJ) # rOBJ <- AA
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8 # a3 <- CC
+ EAS2(a2, rFP, a2) # a2 <- &fp[BB]
+ EAS2(t1, rFP, a3) # a3 <- &fp[CC]
+ LOAD64_F(fa0, fa0f, a2)
+ LOAD64_F(fa1, fa1f, t1)
+
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ $instr
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vAA/vAA+1 <- fv0
+
+%def fbinopWide2addr(instr=""):
+ /*
+ * Generic 64-bit floating-point "/2addr" binary operation.
+ * Provide an "instr" line that specifies an instruction that
+ * performs "fv0 = fa0 op fa1".
+ * This could be an MIPS instruction or a function call.
+ *
+ * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
+ * div-double/2addr, rem-double/2addr
+ */
+ /* binop/2addr vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a1) # a1 <- B
+ EAS2(a1, rFP, a1) # a1 <- &fp[B]
+ EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
+ LOAD64_F(fa0, fa0f, t0)
+ LOAD64_F(fa1, fa1f, a1)
+
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $instr
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- fv0
+
+%def funop(instr=""):
+ /*
+ * Generic 32-bit floating-point unary operation. Provide an "instr"
+ * line that specifies an instruction that performs "fv0 = op fa0".
+ * This could be a MIPS instruction or a function call.
+ *
+ * for: int-to-float
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_VREG_F(fa0, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $instr
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ SET_VREG_F_GOTO(fv0, rOBJ, t1) # vA <- fv0
+
+%def funopWider(instr=""):
+ /*
+ * Generic 32bit-to-64bit floating-point unary operation. Provide an "instr"
+ * line that specifies an instruction that performs "fv0 = op fa0".
+ *
+ * For: int-to-double, float-to-double
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG_F(fa0, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ $instr
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- fv0
+
+%def op_add_double():
+% fbinopWide(instr="add.d fv0, fa0, fa1")
+
+%def op_add_double_2addr():
+% fbinopWide2addr(instr="add.d fv0, fa0, fa1")
+
+%def op_add_float():
+% fbinop(instr="add.s fv0, fa0, fa1")
+
+%def op_add_float_2addr():
+% fbinop2addr(instr="add.s fv0, fa0, fa1")
+
+%def op_cmpg_double():
+% op_cmpl_double(gt_bias="1")
+
+%def op_cmpg_float():
+% op_cmpl_float(gt_bias="1")
+
+%def op_cmpl_double(gt_bias="0"):
+ /*
+ * Compare two floating-point values. Puts 0(==), 1(>), or -1(<)
+ * into the destination register based on the comparison results.
+ *
+ * For: cmpl-double, cmpg-double
+ */
+ /* op vAA, vBB, vCC */
+
+ FETCH(a0, 1) # a0 <- CCBB
+ and rOBJ, a0, 255 # rOBJ <- BB
+ srl t0, a0, 8 # t0 <- CC
+ EAS2(rOBJ, rFP, rOBJ) # rOBJ <- &fp[BB]
+ EAS2(t0, rFP, t0) # t0 <- &fp[CC]
+ LOAD64_F(ft0, ft0f, rOBJ)
+ LOAD64_F(ft1, ft1f, t0)
+#ifdef MIPS32REVGE6
+ cmp.eq.d ft2, ft0, ft1
+ li rTEMP, 0
+ bc1nez ft2, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ cmp.lt.d ft2, ft0, ft1
+ li rTEMP, -1
+ bc1nez ft2, 1f # done if vBB < vCC (ordered)
+ li rTEMP, 1 # vBB > vCC or unordered
+ .else
+ cmp.lt.d ft2, ft1, ft0
+ li rTEMP, 1
+ bc1nez ft2, 1f # done if vBB > vCC (ordered)
+ li rTEMP, -1 # vBB < vCC or unordered
+ .endif
+#else
+ c.eq.d fcc0, ft0, ft1
+ li rTEMP, 0
+ bc1t fcc0, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ c.olt.d fcc0, ft0, ft1
+ li rTEMP, -1
+ bc1t fcc0, 1f # done if vBB < vCC (ordered)
+ li rTEMP, 1 # vBB > vCC or unordered
+ .else
+ c.olt.d fcc0, ft1, ft0
+ li rTEMP, 1
+ bc1t fcc0, 1f # done if vBB > vCC (ordered)
+ li rTEMP, -1 # vBB < vCC or unordered
+ .endif
+#endif
+1:
+ GET_OPA(rOBJ)
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(rTEMP, rOBJ, t0) # vAA <- rTEMP
+
+%def op_cmpl_float(gt_bias="0"):
+ /*
+ * Compare two floating-point values. Puts 0(==), 1(>), or -1(<)
+ * into the destination register based on the comparison results.
+ *
+ * for: cmpl-float, cmpg-float
+ */
+ /* op vAA, vBB, vCC */
+
+ FETCH(a0, 1) # a0 <- CCBB
+ and a2, a0, 255 # a2 <- BB
+ srl a3, a0, 8
+ GET_VREG_F(ft0, a2)
+ GET_VREG_F(ft1, a3)
+#ifdef MIPS32REVGE6
+ cmp.eq.s ft2, ft0, ft1
+ li rTEMP, 0
+ bc1nez ft2, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ cmp.lt.s ft2, ft0, ft1
+ li rTEMP, -1
+ bc1nez ft2, 1f # done if vBB < vCC (ordered)
+ li rTEMP, 1 # vBB > vCC or unordered
+ .else
+ cmp.lt.s ft2, ft1, ft0
+ li rTEMP, 1
+ bc1nez ft2, 1f # done if vBB > vCC (ordered)
+ li rTEMP, -1 # vBB < vCC or unordered
+ .endif
+#else
+ c.eq.s fcc0, ft0, ft1
+ li rTEMP, 0
+ bc1t fcc0, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ c.olt.s fcc0, ft0, ft1
+ li rTEMP, -1
+ bc1t fcc0, 1f # done if vBB < vCC (ordered)
+ li rTEMP, 1 # vBB > vCC or unordered
+ .else
+ c.olt.s fcc0, ft1, ft0
+ li rTEMP, 1
+ bc1t fcc0, 1f # done if vBB > vCC (ordered)
+ li rTEMP, -1 # vBB < vCC or unordered
+ .endif
+#endif
+1:
+ GET_OPA(rOBJ)
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(rTEMP, rOBJ, t0) # vAA <- rTEMP
+
+%def op_div_double():
+% fbinopWide(instr="div.d fv0, fa0, fa1")
+
+%def op_div_double_2addr():
+% fbinopWide2addr(instr="div.d fv0, fa0, fa1")
+
+%def op_div_float():
+% fbinop(instr="div.s fv0, fa0, fa1")
+
+%def op_div_float_2addr():
+% fbinop2addr(instr="div.s fv0, fa0, fa1")
+
+%def op_double_to_float():
+% unopNarrower(instr="cvt.s.d fv0, fa0")
+
+%def op_double_to_int():
+ /*
+ * double-to-int
+ *
+ * We have to clip values to int min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+ LOAD64_F(fa0, fa0f, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+#ifndef MIPS32REVGE6
+ li t0, INT_MIN_AS_DOUBLE_HIGH
+ mtc1 zero, fa1
+ MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
+ c.ole.d fcc0, fa1, fa0
+#endif
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
+ bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
+ c.eq.d fcc0, fa0, fa0
+ mtc1 zero, fa0
+ MOVE_TO_FPU_HIGH(zero, fa0, fa0f)
+ movt.d fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
+1:
+#endif
+ trunc.w.d fa0, fa0
+ SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
+
+%def op_double_to_long():
+ /*
+ * double-to-long
+ *
+ * We have to clip values to long min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+ LOAD64_F(fa0, fa0f, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+#ifdef MIPS32REVGE6
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ trunc.l.d fa0, fa0
+ SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
+#else
+ c.eq.d fcc0, fa0, fa0
+ li rRESULT0, 0
+ li rRESULT1, 0
+ bc1f fcc0, .L${opcode}_get_opcode
+
+ li t0, LONG_MIN_AS_DOUBLE_HIGH
+ mtc1 zero, fa1
+ MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
+ c.ole.d fcc0, fa0, fa1
+ li rRESULT1, LONG_MIN_HIGH
+ bc1t fcc0, .L${opcode}_get_opcode
+
+ neg.d fa1, fa1
+ c.ole.d fcc0, fa1, fa0
+ nor rRESULT0, rRESULT0, zero
+ nor rRESULT1, rRESULT1, zero
+ bc1t fcc0, .L${opcode}_get_opcode
+
+ JAL(__fixdfdi)
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ b .L${opcode}_set_vreg
+#endif
+%def op_double_to_long_sister_code():
+
+#ifndef MIPS32REVGE6
+.L${opcode}_get_opcode:
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+.L${opcode}_set_vreg:
+ SET_VREG64_GOTO(rRESULT0, rRESULT1, rOBJ, t1) # vA/vA+1 <- v0/v1
+#endif
+
+%def op_float_to_double():
+% funopWider(instr="cvt.d.s fv0, fa0")
+
+%def op_float_to_int():
+ /*
+ * float-to-int
+ *
+ * We have to clip values to int min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_VREG_F(fa0, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+#ifndef MIPS32REVGE6
+ li t0, INT_MIN_AS_FLOAT
+ mtc1 t0, fa1
+ c.ole.s fcc0, fa1, fa0
+#endif
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
+ bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
+ c.eq.s fcc0, fa0, fa0
+ mtc1 zero, fa0
+ movt.s fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
+1:
+#endif
+ trunc.w.s fa0, fa0
+ SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
+
+%def op_float_to_long():
+ /*
+ * float-to-long
+ *
+ * We have to clip values to long min/max per the specification. The
+ * expected common case is a "reasonable" value that converts directly
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ GET_VREG_F(fa0, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+
+#ifdef MIPS32REVGE6
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ trunc.l.s fa0, fa0
+ SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
+#else
+ c.eq.s fcc0, fa0, fa0
+ li rRESULT0, 0
+ li rRESULT1, 0
+ bc1f fcc0, .L${opcode}_get_opcode
+
+ li t0, LONG_MIN_AS_FLOAT
+ mtc1 t0, fa1
+ c.ole.s fcc0, fa0, fa1
+ li rRESULT1, LONG_MIN_HIGH
+ bc1t fcc0, .L${opcode}_get_opcode
+
+ neg.s fa1, fa1
+ c.ole.s fcc0, fa1, fa0
+ nor rRESULT0, rRESULT0, zero
+ nor rRESULT1, rRESULT1, zero
+ bc1t fcc0, .L${opcode}_get_opcode
+
+ JAL(__fixsfdi)
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ b .L${opcode}_set_vreg
+#endif
+%def op_float_to_long_sister_code():
+
+#ifndef MIPS32REVGE6
+.L${opcode}_get_opcode:
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+.L${opcode}_set_vreg:
+ SET_VREG64_GOTO(rRESULT0, rRESULT1, rOBJ, t1) # vA/vA+1 <- v0/v1
+#endif
+
+%def op_int_to_double():
+% funopWider(instr="cvt.d.w fv0, fa0")
+
+%def op_int_to_float():
+% funop(instr="cvt.s.w fv0, fa0")
+
+%def op_long_to_double():
+ /*
+ * long-to-double
+ */
+ /* unop vA, vB */
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ GET_OPB(a3) # a3 <- B
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+
+#ifdef MIPS32REVGE6
+ LOAD64_F(fv0, fv0f, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ cvt.d.l fv0, fv0
+#else
+ LOAD64(rARG0, rARG1, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ JAL(__floatdidf) # a0/a1 <- op, a2-a3 changed
+#endif
+
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- result
+
+%def op_long_to_float():
+ /*
+ * long-to-float
+ */
+ /* unop vA, vB */
+ GET_OPB(a3) # a3 <- B
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+
+#ifdef MIPS32REVGE6
+ LOAD64_F(fv0, fv0f, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ cvt.s.l fv0, fv0
+#else
+ LOAD64(rARG0, rARG1, a3)
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ JAL(__floatdisf)
+#endif
+
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- fv0
+
+%def op_mul_double():
+% fbinopWide(instr="mul.d fv0, fa0, fa1")
+
+%def op_mul_double_2addr():
+% fbinopWide2addr(instr="mul.d fv0, fa0, fa1")
+
+%def op_mul_float():
+% fbinop(instr="mul.s fv0, fa0, fa1")
+
+%def op_mul_float_2addr():
+% fbinop2addr(instr="mul.s fv0, fa0, fa1")
+
+%def op_neg_double():
+% unopWide(instr="addu a1, a1, 0x80000000")
+
+%def op_neg_float():
+% unop(instr="addu a0, a0, 0x80000000")
+
+%def op_rem_double():
+% fbinopWide(instr="JAL(fmod)")
+
+%def op_rem_double_2addr():
+% fbinopWide2addr(instr="JAL(fmod)")
+
+%def op_rem_float():
+% fbinop(instr="JAL(fmodf)")
+
+%def op_rem_float_2addr():
+% fbinop2addr(instr="JAL(fmodf)")
+
+%def op_sub_double():
+% fbinopWide(instr="sub.d fv0, fa0, fa1")
+
+%def op_sub_double_2addr():
+% fbinopWide2addr(instr="sub.d fv0, fa0, fa1")
+
+%def op_sub_float():
+% fbinop(instr="sub.s fv0, fa0, fa1")
+
+%def op_sub_float_2addr():
+% fbinop2addr(instr="sub.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/footer.S b/runtime/interpreter/mterp/mips/footer.S
deleted file mode 100644
index 0f641d2..0000000
--- a/runtime/interpreter/mterp/mips/footer.S
+++ /dev/null
@@ -1,289 +0,0 @@
-%def footer():
-/*
- * ===========================================================================
- * Common subroutines and data
- * ===========================================================================
- */
-
- .text
- .align 2
-
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-common_errDivideByZero:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogDivideByZeroException)
-#endif
- b MterpCommonFallback
-
-common_errArrayIndex:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogArrayIndexException)
-#endif
- b MterpCommonFallback
-
-common_errNegativeArraySize:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogNegativeArraySizeException)
-#endif
- b MterpCommonFallback
-
-common_errNoSuchMethod:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogNoSuchMethodException)
-#endif
- b MterpCommonFallback
-
-common_errNullObject:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogNullObjectException)
-#endif
- b MterpCommonFallback
-
-common_exceptionThrown:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogExceptionThrownException)
-#endif
- b MterpCommonFallback
-
-MterpSuspendFallback:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- lw a2, THREAD_FLAGS_OFFSET(rSELF)
- JAL(MterpLogSuspendFallback)
-#endif
- b MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- lw a0, THREAD_EXCEPTION_OFFSET(rSELF)
- beqz a0, MterpFallback # If exception, fall back to reference interpreter.
- /* intentional fallthrough - handle pending exception. */
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
-MterpException:
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpHandleException) # (self, shadow_frame)
- beqz v0, MterpExceptionReturn # no local catch, back to caller.
- lw a0, OFF_FP_DEX_INSTRUCTIONS(rFP)
- lw a1, OFF_FP_DEX_PC(rFP)
- lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
- EAS1(rPC, a0, a1) # generate new dex_pc_ptr
- /* Do we need to switch interpreters? */
- JAL(MterpShouldSwitchInterpreters)
- bnez v0, MterpFallback
- /* resume execution at catch block */
- EXPORT_PC()
- FETCH_INST()
- GET_INST_OPCODE(t0)
- GOTO_OPCODE(t0)
- /* NOTE: no fallthrough */
-
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * rINST <= signed offset
- * rPROFILE <= signed hotness countdown (expanded to 32 bits)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- */
-MterpCommonTakenBranchNoFlags:
- bgtz rINST, .L_forward_branch # don't add forward branches to hotness
-/*
- * We need to subtract 1 from positive values and we should not see 0 here,
- * so we may use the result of the comparison with -1.
- */
-#if JIT_CHECK_OSR != -1
-# error "JIT_CHECK_OSR must be -1."
-#endif
- li t0, JIT_CHECK_OSR
- beq rPROFILE, t0, .L_osr_check
- blt rPROFILE, t0, .L_resume_backward_branch
- subu rPROFILE, 1
- beqz rPROFILE, .L_add_batch # counted down to zero - report
-.L_resume_backward_branch:
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- REFRESH_IBASE()
- addu a2, rINST, rINST # a2<- byte offset
- FETCH_ADVANCE_INST_RB(a2) # update rPC, load rINST
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- bnez ra, .L_suspend_request_pending
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
-.L_suspend_request_pending:
- EXPORT_PC()
- move a0, rSELF
- JAL(MterpSuspendCheck) # (self)
- bnez v0, MterpFallback
- REFRESH_IBASE() # might have changed during suspend
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
-.L_no_count_backwards:
- li t0, JIT_CHECK_OSR # check for possible OSR re-entry
- bne rPROFILE, t0, .L_resume_backward_branch
-.L_osr_check:
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST
- EXPORT_PC()
- JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- bnez v0, MterpOnStackReplacement
- b .L_resume_backward_branch
-
-.L_forward_branch:
- li t0, JIT_CHECK_OSR # check for possible OSR re-entry
- beq rPROFILE, t0, .L_check_osr_forward
-.L_resume_forward_branch:
- add a2, rINST, rINST # a2<- byte offset
- FETCH_ADVANCE_INST_RB(a2) # update rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
-.L_check_osr_forward:
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST
- EXPORT_PC()
- JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- bnez v0, MterpOnStackReplacement
- b .L_resume_forward_branch
-
-.L_add_batch:
- addu a1, rFP, OFF_FP_SHADOWFRAME
- sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
- lw a0, OFF_FP_METHOD(rFP)
- move a2, rSELF
- JAL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- move rPROFILE, v0 # restore new hotness countdown to rPROFILE
- b .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- li a2, 2
- EXPORT_PC()
- JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- bnez v0, MterpOnStackReplacement
- FETCH_ADVANCE_INST(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST
- JAL(MterpLogOSR)
-#endif
- li v0, 1 # Signal normal return
- b MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
-MterpFallback:
- EXPORT_PC()
-#if MTERP_LOGGING
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- JAL(MterpLogFallback)
-#endif
-MterpCommonFallback:
- move v0, zero # signal retry with reference interpreter.
- b MterpDone
-/*
- * We pushed some registers on the stack in ExecuteMterpImpl, then saved
- * SP and LR. Here we restore SP, restore the registers, and then restore
- * LR to PC.
- *
- * On entry:
- * uint32_t* rFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- li v0, 1 # signal return to caller.
- b MterpDone
-MterpReturn:
- lw a2, OFF_FP_RESULT_REGISTER(rFP)
- sw v0, 0(a2)
- sw v1, 4(a2)
- li v0, 1 # signal return to caller.
-MterpDone:
-/*
- * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- blez rPROFILE, .L_pop_and_return # if > 0, we may have some counts to report.
-
-MterpProfileActive:
- move rINST, v0 # stash return value
- /* Report cached hotness counts */
- lw a0, OFF_FP_METHOD(rFP)
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rSELF
- sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
- JAL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- move v0, rINST # restore return value
-
-.L_pop_and_return:
-/* Restore from the stack and return. Frame size = STACK_SIZE */
- STACK_LOAD_FULL()
- jalr zero, ra
-
- .cfi_endproc
- .end ExecuteMterpImpl
diff --git a/runtime/interpreter/mterp/mips/funop.S b/runtime/interpreter/mterp/mips/funop.S
deleted file mode 100644
index 64f40ac..0000000
--- a/runtime/interpreter/mterp/mips/funop.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def funop(instr=""):
- /*
- * Generic 32-bit floating-point unary operation. Provide an "instr"
- * line that specifies an instruction that performs "fv0 = op fa0".
- * This could be a MIPS instruction or a function call.
- *
- * for: int-to-float
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_VREG_F(fa0, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $instr
- GET_INST_OPCODE(t1) # extract opcode from rINST
- SET_VREG_F_GOTO(fv0, rOBJ, t1) # vA <- fv0
diff --git a/runtime/interpreter/mterp/mips/funopWider.S b/runtime/interpreter/mterp/mips/funopWider.S
deleted file mode 100644
index afc45ee..0000000
--- a/runtime/interpreter/mterp/mips/funopWider.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def funopWider(instr=""):
- /*
- * Generic 32bit-to-64bit floating-point unary operation. Provide an "instr"
- * line that specifies an instruction that performs "fv0 = op fa0".
- *
- * For: int-to-double, float-to-double
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG_F(fa0, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $instr
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- fv0
diff --git a/runtime/interpreter/mterp/mips/header.S b/runtime/interpreter/mterp/mips/header.S
deleted file mode 100644
index 57339d0..0000000
--- a/runtime/interpreter/mterp/mips/header.S
+++ /dev/null
@@ -1,727 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- Art assembly interpreter notes:
-
- First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
- handle invoke, allows higher-level code to create frame & shadow frame.
-
- Once that's working, support direct entry code & eliminate shadow frame (and
- excess locals allocation.
-
- Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
- base of the vreg array within the shadow frame. Access the other fields,
- dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
- the shadow frame mechanism of double-storing object references - via rFP &
- number_of_vregs_.
-
- */
-
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-#if (__mips==32) && (__mips_isa_rev>=2)
-#define MIPS32REVGE2 /* mips32r2 and greater */
-#if (__mips==32) && (__mips_isa_rev>=5)
-#define FPU64 /* 64 bit FPU */
-#if (__mips==32) && (__mips_isa_rev>=6)
-#define MIPS32REVGE6 /* mips32r6 and greater */
-#endif
-#endif
-#endif
-
-/* MIPS definitions and declarations
-
- reg nick purpose
- s0 rPC interpreted program counter, used for fetching instructions
- s1 rFP interpreted frame pointer, used for accessing locals and args
- s2 rSELF self (Thread) pointer
- s3 rIBASE interpreted instruction base pointer, used for computed goto
- s4 rINST first 16-bit code unit of current instruction
- s5 rOBJ object pointer
- s6 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
- s7 rTEMP used as temp storage that can survive a function call
- s8 rPROFILE branch profiling countdown
-
-*/
-
-/* single-purpose registers, given names for clarity */
-#define rPC s0
-#define CFI_DEX 16 // DWARF register number of the register holding dex-pc (s0).
-#define CFI_TMP 4 // DWARF register number of the first argument register (a0).
-#define rFP s1
-#define rSELF s2
-#define rIBASE s3
-#define rINST s4
-#define rOBJ s5
-#define rREFS s6
-#define rTEMP s7
-#define rPROFILE s8
-
-#define rARG0 a0
-#define rARG1 a1
-#define rARG2 a2
-#define rARG3 a3
-#define rRESULT0 v0
-#define rRESULT1 v1
-
-/* GP register definitions */
-#define zero $$0 /* always zero */
-#define AT $$at /* assembler temp */
-#define v0 $$2 /* return value */
-#define v1 $$3
-#define a0 $$4 /* argument registers */
-#define a1 $$5
-#define a2 $$6
-#define a3 $$7
-#define t0 $$8 /* temp registers (not saved across subroutine calls) */
-#define t1 $$9
-#define t2 $$10
-#define t3 $$11
-#define t4 $$12
-#define t5 $$13
-#define t6 $$14
-#define t7 $$15
-#define ta0 $$12 /* alias */
-#define ta1 $$13
-#define ta2 $$14
-#define ta3 $$15
-#define s0 $$16 /* saved across subroutine calls (callee saved) */
-#define s1 $$17
-#define s2 $$18
-#define s3 $$19
-#define s4 $$20
-#define s5 $$21
-#define s6 $$22
-#define s7 $$23
-#define t8 $$24 /* two more temp registers */
-#define t9 $$25
-#define k0 $$26 /* kernel temporary */
-#define k1 $$27
-#define gp $$28 /* global pointer */
-#define sp $$29 /* stack pointer */
-#define s8 $$30 /* one more callee saved */
-#define ra $$31 /* return address */
-
-/* FP register definitions */
-#define fv0 $$f0
-#define fv0f $$f1
-#define fv1 $$f2
-#define fv1f $$f3
-#define fa0 $$f12
-#define fa0f $$f13
-#define fa1 $$f14
-#define fa1f $$f15
-#define ft0 $$f4
-#define ft0f $$f5
-#define ft1 $$f6
-#define ft1f $$f7
-#define ft2 $$f8
-#define ft2f $$f9
-#define ft3 $$f10
-#define ft3f $$f11
-#define ft4 $$f16
-#define ft4f $$f17
-#define ft5 $$f18
-#define ft5f $$f19
-#define fs0 $$f20
-#define fs0f $$f21
-#define fs1 $$f22
-#define fs1f $$f23
-#define fs2 $$f24
-#define fs2f $$f25
-#define fs3 $$f26
-#define fs3f $$f27
-#define fs4 $$f28
-#define fs4f $$f29
-#define fs5 $$f30
-#define fs5f $$f31
-
-#ifndef MIPS32REVGE6
-#define fcc0 $$fcc0
-#define fcc1 $$fcc1
-#endif
-
-#ifdef MIPS32REVGE2
-#define SEB(rd, rt) \
- seb rd, rt
-#define SEH(rd, rt) \
- seh rd, rt
-#define INSERT_HIGH_HALF(rd_lo, rt_hi) \
- ins rd_lo, rt_hi, 16, 16
-#else
-#define SEB(rd, rt) \
- sll rd, rt, 24; \
- sra rd, rd, 24
-#define SEH(rd, rt) \
- sll rd, rt, 16; \
- sra rd, rd, 16
-/* Clobbers rt_hi on pre-R2. */
-#define INSERT_HIGH_HALF(rd_lo, rt_hi) \
- sll rt_hi, rt_hi, 16; \
- or rd_lo, rt_hi
-#endif
-
-#ifdef FPU64
-#define MOVE_TO_FPU_HIGH(r, flo, fhi) \
- mthc1 r, flo
-#else
-#define MOVE_TO_FPU_HIGH(r, flo, fhi) \
- mtc1 r, fhi
-#endif
-
-#ifdef MIPS32REVGE6
-#define JR(rt) \
- jic rt, 0
-#define LSA(rd, rs, rt, sa) \
- .if sa; \
- lsa rd, rs, rt, sa; \
- .else; \
- addu rd, rs, rt; \
- .endif
-#else
-#define JR(rt) \
- jalr zero, rt
-#define LSA(rd, rs, rt, sa) \
- .if sa; \
- .set push; \
- .set noat; \
- sll AT, rs, sa; \
- addu rd, AT, rt; \
- .set pop; \
- .else; \
- addu rd, rs, rt; \
- .endif
-#endif
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_SHADOWFRAME OFF_FP(0)
-
-#define MTERP_PROFILE_BRANCHES 1
-#define MTERP_LOGGING 0
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-#define EXPORT_PC() \
- sw rPC, OFF_FP_DEX_PC_PTR(rFP)
-
-#define EXPORT_DEX_PC(tmp) \
- lw tmp, OFF_FP_DEX_INSTRUCTIONS(rFP); \
- sw rPC, OFF_FP_DEX_PC_PTR(rFP); \
- subu tmp, rPC, tmp; \
- sra tmp, tmp, 1; \
- sw tmp, OFF_FP_DEX_PC(rFP)
-
-/*
- * Fetch the next instruction from rPC into rINST. Does not advance rPC.
- */
-#define FETCH_INST() lhu rINST, (rPC)
-
-/*
- * Fetch the next instruction from the specified offset. Advances rPC
- * to point to the next instruction. "_count" is in 16-bit code units.
- *
- * This must come AFTER anything that can throw an exception, or the
- * exception catch may miss. (This also implies that it must come after
- * EXPORT_PC().)
- */
-#define FETCH_ADVANCE_INST(_count) \
- lhu rINST, ((_count)*2)(rPC); \
- addu rPC, rPC, ((_count) * 2)
-
-/*
- * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
- * rINST ahead of possible exception point. Be sure to manually advance rPC
- * later.
- */
-#define PREFETCH_INST(_count) lhu rINST, ((_count)*2)(rPC)
-
-/* Advance rPC by some number of code units. */
-#define ADVANCE(_count) addu rPC, rPC, ((_count) * 2)
-
-/*
- * Fetch the next instruction from an offset specified by rd. Updates
- * rPC to point to the next instruction. "rd" must specify the distance
- * in bytes, *not* 16-bit code units, and may be a signed value.
- */
-#define FETCH_ADVANCE_INST_RB(rd) \
- addu rPC, rPC, rd; \
- lhu rINST, (rPC)
-
-/*
- * Fetch a half-word code unit from an offset past the current PC. The
- * "_count" value is in 16-bit code units. Does not advance rPC.
- *
- * The "_S" variant works the same but treats the value as signed.
- */
-#define FETCH(rd, _count) lhu rd, ((_count) * 2)(rPC)
-#define FETCH_S(rd, _count) lh rd, ((_count) * 2)(rPC)
-
-/*
- * Fetch one byte from an offset past the current PC. Pass in the same
- * "_count" as you would for FETCH, and an additional 0/1 indicating which
- * byte of the halfword you want (lo/hi).
- */
-#define FETCH_B(rd, _count, _byte) lbu rd, ((_count) * 2 + _byte)(rPC)
-
-/*
- * Put the instruction's opcode field into the specified register.
- */
-#define GET_INST_OPCODE(rd) and rd, rINST, 0xFF
-
-/*
- * Transform opcode into branch target address.
- */
-#define GET_OPCODE_TARGET(rd) \
- sll rd, rd, ${handler_size_bits}; \
- addu rd, rIBASE, rd
-
-/*
- * Begin executing the opcode in rd.
- */
-#define GOTO_OPCODE(rd) \
- GET_OPCODE_TARGET(rd); \
- JR(rd)
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- */
-#define GET_VREG(rd, rix) LOAD_eas2(rd, rFP, rix)
-
-#define GET_VREG_F(rd, rix) \
- .set noat; \
- EAS2(AT, rFP, rix); \
- l.s rd, (AT); \
- .set at
-
-#ifdef MIPS32REVGE6
-#define SET_VREG(rd, rix) \
- lsa t8, rix, rFP, 2; \
- sw rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8)
-#else
-#define SET_VREG(rd, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8)
-#endif
-
-#ifdef MIPS32REVGE6
-#define SET_VREG_OBJECT(rd, rix) \
- lsa t8, rix, rFP, 2; \
- sw rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- sw rd, 0(t8)
-#else
-#define SET_VREG_OBJECT(rd, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw rd, 0(t8)
-#endif
-
-#ifdef MIPS32REVGE6
-#define SET_VREG64(rlo, rhi, rix) \
- lsa t8, rix, rFP, 2; \
- sw rlo, 0(t8); \
- sw rhi, 4(t8); \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8); \
- sw zero, 4(t8)
-#else
-#define SET_VREG64(rlo, rhi, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rlo, 0(t8); \
- sw rhi, 4(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8); \
- sw zero, 4(t8)
-#endif
-
-#ifdef MIPS32REVGE6
-#define SET_VREG_F(rd, rix) \
- lsa t8, rix, rFP, 2; \
- s.s rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8)
-#else
-#define SET_VREG_F(rd, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- s.s rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8)
-#endif
-
-#ifdef MIPS32REVGE6
-#define SET_VREG64_F(rlo, rhi, rix) \
- lsa t8, rix, rFP, 2; \
- .set noat; \
- mfhc1 AT, rlo; \
- s.s rlo, 0(t8); \
- sw AT, 4(t8); \
- .set at; \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8); \
- sw zero, 4(t8)
-#elif defined(FPU64)
-#define SET_VREG64_F(rlo, rhi, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rREFS, AT; \
- sw zero, 0(t8); \
- sw zero, 4(t8); \
- addu t8, rFP, AT; \
- mfhc1 AT, rlo; \
- sw AT, 4(t8); \
- .set at; \
- s.s rlo, 0(t8)
-#else
-#define SET_VREG64_F(rlo, rhi, rix) \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- s.s rlo, 0(t8); \
- s.s rhi, 4(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8); \
- sw zero, 4(t8)
-#endif
-
-/* Combination of the SET_VREG and GOTO_OPCODE functions to save 1 instruction */
-#ifdef MIPS32REVGE6
-#define SET_VREG_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- lsa t8, rix, rFP, 2; \
- sw rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- jalr zero, dst; \
- sw zero, 0(t8); \
- .set reorder
-#else
-#define SET_VREG_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- jalr zero, dst; \
- sw zero, 0(t8); \
- .set reorder
-#endif
-
-/* Combination of the SET_VREG_OBJECT and GOTO_OPCODE functions to save 1 instruction */
-#ifdef MIPS32REVGE6
-#define SET_VREG_OBJECT_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- lsa t8, rix, rFP, 2; \
- sw rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- jalr zero, dst; \
- sw rd, 0(t8); \
- .set reorder
-#else
-#define SET_VREG_OBJECT_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- jalr zero, dst; \
- sw rd, 0(t8); \
- .set reorder
-#endif
-
-/* Combination of the SET_VREG64 and GOTO_OPCODE functions to save 1 instruction */
-#ifdef MIPS32REVGE6
-#define SET_VREG64_GOTO(rlo, rhi, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- lsa t8, rix, rFP, 2; \
- sw rlo, 0(t8); \
- sw rhi, 4(t8); \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8); \
- jalr zero, dst; \
- sw zero, 4(t8); \
- .set reorder
-#else
-#define SET_VREG64_GOTO(rlo, rhi, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- sw rlo, 0(t8); \
- sw rhi, 4(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8); \
- jalr zero, dst; \
- sw zero, 4(t8); \
- .set reorder
-#endif
-
-/* Combination of the SET_VREG_F and GOTO_OPCODE functions to save 1 instruction */
-#ifdef MIPS32REVGE6
-#define SET_VREG_F_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- lsa t8, rix, rFP, 2; \
- s.s rd, 0(t8); \
- lsa t8, rix, rREFS, 2; \
- jalr zero, dst; \
- sw zero, 0(t8); \
- .set reorder
-#else
-#define SET_VREG_F_GOTO(rd, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- s.s rd, 0(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- jalr zero, dst; \
- sw zero, 0(t8); \
- .set reorder
-#endif
-
-/* Combination of the SET_VREG64_F and GOTO_OPCODE functions to save 1 instruction */
-#ifdef MIPS32REVGE6
-#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- lsa t8, rix, rFP, 2; \
- .set noat; \
- mfhc1 AT, rlo; \
- s.s rlo, 0(t8); \
- sw AT, 4(t8); \
- .set at; \
- lsa t8, rix, rREFS, 2; \
- sw zero, 0(t8); \
- jalr zero, dst; \
- sw zero, 4(t8); \
- .set reorder
-#elif defined(FPU64)
-#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rREFS, AT; \
- sw zero, 0(t8); \
- sw zero, 4(t8); \
- addu t8, rFP, AT; \
- mfhc1 AT, rlo; \
- sw AT, 4(t8); \
- .set at; \
- jalr zero, dst; \
- s.s rlo, 0(t8); \
- .set reorder
-#else
-#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
- .set noreorder; \
- GET_OPCODE_TARGET(dst); \
- .set noat; \
- sll AT, rix, 2; \
- addu t8, rFP, AT; \
- s.s rlo, 0(t8); \
- s.s rhi, 4(t8); \
- addu t8, rREFS, AT; \
- .set at; \
- sw zero, 0(t8); \
- jalr zero, dst; \
- sw zero, 4(t8); \
- .set reorder
-#endif
-
-#define GET_OPA(rd) srl rd, rINST, 8
-#ifdef MIPS32REVGE2
-#define GET_OPA4(rd) ext rd, rINST, 8, 4
-#else
-#define GET_OPA4(rd) GET_OPA(rd); and rd, 0xf
-#endif
-#define GET_OPB(rd) srl rd, rINST, 12
-
-/*
- * Form an Effective Address rd = rbase + roff<<shift;
- * Uses reg AT on pre-R6.
- */
-#define EASN(rd, rbase, roff, shift) LSA(rd, roff, rbase, shift)
-
-#define EAS1(rd, rbase, roff) EASN(rd, rbase, roff, 1)
-#define EAS2(rd, rbase, roff) EASN(rd, rbase, roff, 2)
-#define EAS3(rd, rbase, roff) EASN(rd, rbase, roff, 3)
-#define EAS4(rd, rbase, roff) EASN(rd, rbase, roff, 4)
-
-#define LOAD_eas2(rd, rbase, roff) \
- .set noat; \
- EAS2(AT, rbase, roff); \
- lw rd, 0(AT); \
- .set at
-
-#define STORE_eas2(rd, rbase, roff) \
- .set noat; \
- EAS2(AT, rbase, roff); \
- sw rd, 0(AT); \
- .set at
-
-#define LOAD_RB_OFF(rd, rbase, off) lw rd, off(rbase)
-#define STORE_RB_OFF(rd, rbase, off) sw rd, off(rbase)
-
-#define STORE64_off(rlo, rhi, rbase, off) \
- sw rlo, off(rbase); \
- sw rhi, (off+4)(rbase)
-#define LOAD64_off(rlo, rhi, rbase, off) \
- lw rlo, off(rbase); \
- lw rhi, (off+4)(rbase)
-
-#define STORE64(rlo, rhi, rbase) STORE64_off(rlo, rhi, rbase, 0)
-#define LOAD64(rlo, rhi, rbase) LOAD64_off(rlo, rhi, rbase, 0)
-
-#ifdef FPU64
-#define STORE64_off_F(rlo, rhi, rbase, off) \
- s.s rlo, off(rbase); \
- .set noat; \
- mfhc1 AT, rlo; \
- sw AT, (off+4)(rbase); \
- .set at
-#define LOAD64_off_F(rlo, rhi, rbase, off) \
- l.s rlo, off(rbase); \
- .set noat; \
- lw AT, (off+4)(rbase); \
- mthc1 AT, rlo; \
- .set at
-#else
-#define STORE64_off_F(rlo, rhi, rbase, off) \
- s.s rlo, off(rbase); \
- s.s rhi, (off+4)(rbase)
-#define LOAD64_off_F(rlo, rhi, rbase, off) \
- l.s rlo, off(rbase); \
- l.s rhi, (off+4)(rbase)
-#endif
-
-#define STORE64_F(rlo, rhi, rbase) STORE64_off_F(rlo, rhi, rbase, 0)
-#define LOAD64_F(rlo, rhi, rbase) LOAD64_off_F(rlo, rhi, rbase, 0)
-
-#define LOAD_base_offMirrorArray_length(rd, rbase) LOAD_RB_OFF(rd, rbase, MIRROR_ARRAY_LENGTH_OFFSET)
-
-#define STACK_STORE(rd, off) sw rd, off(sp)
-#define STACK_LOAD(rd, off) lw rd, off(sp)
-#define CREATE_STACK(n) subu sp, sp, n
-#define DELETE_STACK(n) addu sp, sp, n
-
-#define LOAD_ADDR(dest, addr) la dest, addr
-#define LOAD_IMM(dest, imm) li dest, imm
-#define MOVE_REG(dest, src) move dest, src
-#define STACK_SIZE 128
-
-#define STACK_OFFSET_ARG04 16
-#define STACK_OFFSET_ARG05 20
-#define STACK_OFFSET_ARG06 24
-#define STACK_OFFSET_ARG07 28
-#define STACK_OFFSET_GP 84
-
-#define JAL(n) jal n
-#define BAL(n) bal n
-
-/*
- * FP register usage restrictions:
- * 1) We don't use the callee save FP registers so we don't have to save them.
- * 2) We don't use the odd FP registers so we can share code with mips32r6.
- */
-#define STACK_STORE_FULL() CREATE_STACK(STACK_SIZE); \
- STACK_STORE(ra, 124); \
- STACK_STORE(s8, 120); \
- STACK_STORE(s0, 116); \
- STACK_STORE(s1, 112); \
- STACK_STORE(s2, 108); \
- STACK_STORE(s3, 104); \
- STACK_STORE(s4, 100); \
- STACK_STORE(s5, 96); \
- STACK_STORE(s6, 92); \
- STACK_STORE(s7, 88);
-
-#define STACK_LOAD_FULL() STACK_LOAD(gp, STACK_OFFSET_GP); \
- STACK_LOAD(s7, 88); \
- STACK_LOAD(s6, 92); \
- STACK_LOAD(s5, 96); \
- STACK_LOAD(s4, 100); \
- STACK_LOAD(s3, 104); \
- STACK_LOAD(s2, 108); \
- STACK_LOAD(s1, 112); \
- STACK_LOAD(s0, 116); \
- STACK_LOAD(s8, 120); \
- STACK_LOAD(ra, 124); \
- DELETE_STACK(STACK_SIZE)
-
-#define REFRESH_IBASE() \
- lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
-
-/* Constants for float/double_to_int/long conversions */
-#define INT_MIN 0x80000000
-#define INT_MIN_AS_FLOAT 0xCF000000
-#define INT_MIN_AS_DOUBLE_HIGH 0xC1E00000
-#define LONG_MIN_HIGH 0x80000000
-#define LONG_MIN_AS_FLOAT 0xDF000000
-#define LONG_MIN_AS_DOUBLE_HIGH 0xC3E00000
diff --git a/runtime/interpreter/mterp/mips/instruction_end.S b/runtime/interpreter/mterp/mips/instruction_end.S
deleted file mode 100644
index 3d44293..0000000
--- a/runtime/interpreter/mterp/mips/instruction_end.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end():
-
- .global artMterpAsmInstructionEnd
-artMterpAsmInstructionEnd:
diff --git a/runtime/interpreter/mterp/mips/instruction_end_alt.S b/runtime/interpreter/mterp/mips/instruction_end_alt.S
deleted file mode 100644
index 86a1068..0000000
--- a/runtime/interpreter/mterp/mips/instruction_end_alt.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end_alt():
-
- .global artMterpAsmAltInstructionEnd
-artMterpAsmAltInstructionEnd:
diff --git a/runtime/interpreter/mterp/mips/instruction_end_sister.S b/runtime/interpreter/mterp/mips/instruction_end_sister.S
deleted file mode 100644
index 8cc4513..0000000
--- a/runtime/interpreter/mterp/mips/instruction_end_sister.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end_sister():
-
- .global artMterpAsmSisterEnd
-artMterpAsmSisterEnd:
diff --git a/runtime/interpreter/mterp/mips/instruction_start.S b/runtime/interpreter/mterp/mips/instruction_start.S
deleted file mode 100644
index 4b777f2..0000000
--- a/runtime/interpreter/mterp/mips/instruction_start.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def instruction_start():
-
- .global artMterpAsmInstructionStart
-artMterpAsmInstructionStart = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/mips/instruction_start_alt.S b/runtime/interpreter/mterp/mips/instruction_start_alt.S
deleted file mode 100644
index e7731b7..0000000
--- a/runtime/interpreter/mterp/mips/instruction_start_alt.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def instruction_start_alt():
-
- .global artMterpAsmAltInstructionStart
-artMterpAsmAltInstructionStart = .L_ALT_op_nop
- .text
diff --git a/runtime/interpreter/mterp/mips/instruction_start_sister.S b/runtime/interpreter/mterp/mips/instruction_start_sister.S
deleted file mode 100644
index e09ea90..0000000
--- a/runtime/interpreter/mterp/mips/instruction_start_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_start_sister():
-
- .global artMterpAsmSisterStart
- .text
- .balign 4
-artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/mips/invoke.S b/runtime/interpreter/mterp/mips/invoke.S
index fa74452..c77d12b 100644
--- a/runtime/interpreter/mterp/mips/invoke.S
+++ b/runtime/interpreter/mterp/mips/invoke.S
@@ -17,3 +17,71 @@
bnez v0, MterpFallback
GET_INST_OPCODE(t0)
GOTO_OPCODE(t0)
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ EXPORT_PC()
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rPC
+ move a3, rINST
+ JAL($helper)
+ beqz v0, MterpException
+ FETCH_ADVANCE_INST(4)
+ JAL(MterpShouldSwitchInterpreters)
+ bnez v0, MterpFallback
+ GET_INST_OPCODE(t0)
+ GOTO_OPCODE(t0)
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/mips/invoke_polymorphic.S b/runtime/interpreter/mterp/mips/invoke_polymorphic.S
deleted file mode 100644
index f2532e7..0000000
--- a/runtime/interpreter/mterp/mips/invoke_polymorphic.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- EXPORT_PC()
- move a0, rSELF
- addu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rPC
- move a3, rINST
- JAL($helper)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(4)
- JAL(MterpShouldSwitchInterpreters)
- bnez v0, MterpFallback
- GET_INST_OPCODE(t0)
- GOTO_OPCODE(t0)
diff --git a/runtime/interpreter/mterp/mips/main.S b/runtime/interpreter/mterp/mips/main.S
new file mode 100644
index 0000000..6e91af8
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/main.S
@@ -0,0 +1,1147 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ Art assembly interpreter notes:
+
+ First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
+ handle invoke, allows higher-level code to create frame & shadow frame.
+
+ Once that's working, support direct entry code & eliminate shadow frame (and
+ excess locals allocation.
+
+ Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
+ base of the vreg array within the shadow frame. Access the other fields,
+ dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
+ the shadow frame mechanism of double-storing object references - via rFP &
+ number_of_vregs_.
+
+ */
+
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+#if (__mips==32) && (__mips_isa_rev>=2)
+#define MIPS32REVGE2 /* mips32r2 and greater */
+#if (__mips==32) && (__mips_isa_rev>=5)
+#define FPU64 /* 64 bit FPU */
+#if (__mips==32) && (__mips_isa_rev>=6)
+#define MIPS32REVGE6 /* mips32r6 and greater */
+#endif
+#endif
+#endif
+
+/* MIPS definitions and declarations
+
+ reg nick purpose
+ s0 rPC interpreted program counter, used for fetching instructions
+ s1 rFP interpreted frame pointer, used for accessing locals and args
+ s2 rSELF self (Thread) pointer
+ s3 rIBASE interpreted instruction base pointer, used for computed goto
+ s4 rINST first 16-bit code unit of current instruction
+ s5 rOBJ object pointer
+ s6 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
+ s7 rTEMP used as temp storage that can survive a function call
+ s8 rPROFILE branch profiling countdown
+
+*/
+
+/* single-purpose registers, given names for clarity */
+#define rPC s0
+#define CFI_DEX 16 // DWARF register number of the register holding dex-pc (s0).
+#define CFI_TMP 4 // DWARF register number of the first argument register (a0).
+#define rFP s1
+#define rSELF s2
+#define rIBASE s3
+#define rINST s4
+#define rOBJ s5
+#define rREFS s6
+#define rTEMP s7
+#define rPROFILE s8
+
+#define rARG0 a0
+#define rARG1 a1
+#define rARG2 a2
+#define rARG3 a3
+#define rRESULT0 v0
+#define rRESULT1 v1
+
+/* GP register definitions */
+#define zero $$0 /* always zero */
+#define AT $$at /* assembler temp */
+#define v0 $$2 /* return value */
+#define v1 $$3
+#define a0 $$4 /* argument registers */
+#define a1 $$5
+#define a2 $$6
+#define a3 $$7
+#define t0 $$8 /* temp registers (not saved across subroutine calls) */
+#define t1 $$9
+#define t2 $$10
+#define t3 $$11
+#define t4 $$12
+#define t5 $$13
+#define t6 $$14
+#define t7 $$15
+#define ta0 $$12 /* alias */
+#define ta1 $$13
+#define ta2 $$14
+#define ta3 $$15
+#define s0 $$16 /* saved across subroutine calls (callee saved) */
+#define s1 $$17
+#define s2 $$18
+#define s3 $$19
+#define s4 $$20
+#define s5 $$21
+#define s6 $$22
+#define s7 $$23
+#define t8 $$24 /* two more temp registers */
+#define t9 $$25
+#define k0 $$26 /* kernel temporary */
+#define k1 $$27
+#define gp $$28 /* global pointer */
+#define sp $$29 /* stack pointer */
+#define s8 $$30 /* one more callee saved */
+#define ra $$31 /* return address */
+
+/* FP register definitions */
+#define fv0 $$f0
+#define fv0f $$f1
+#define fv1 $$f2
+#define fv1f $$f3
+#define fa0 $$f12
+#define fa0f $$f13
+#define fa1 $$f14
+#define fa1f $$f15
+#define ft0 $$f4
+#define ft0f $$f5
+#define ft1 $$f6
+#define ft1f $$f7
+#define ft2 $$f8
+#define ft2f $$f9
+#define ft3 $$f10
+#define ft3f $$f11
+#define ft4 $$f16
+#define ft4f $$f17
+#define ft5 $$f18
+#define ft5f $$f19
+#define fs0 $$f20
+#define fs0f $$f21
+#define fs1 $$f22
+#define fs1f $$f23
+#define fs2 $$f24
+#define fs2f $$f25
+#define fs3 $$f26
+#define fs3f $$f27
+#define fs4 $$f28
+#define fs4f $$f29
+#define fs5 $$f30
+#define fs5f $$f31
+
+#ifndef MIPS32REVGE6
+#define fcc0 $$fcc0
+#define fcc1 $$fcc1
+#endif
+
+#ifdef MIPS32REVGE2
+#define SEB(rd, rt) \
+ seb rd, rt
+#define SEH(rd, rt) \
+ seh rd, rt
+#define INSERT_HIGH_HALF(rd_lo, rt_hi) \
+ ins rd_lo, rt_hi, 16, 16
+#else
+#define SEB(rd, rt) \
+ sll rd, rt, 24; \
+ sra rd, rd, 24
+#define SEH(rd, rt) \
+ sll rd, rt, 16; \
+ sra rd, rd, 16
+/* Clobbers rt_hi on pre-R2. */
+#define INSERT_HIGH_HALF(rd_lo, rt_hi) \
+ sll rt_hi, rt_hi, 16; \
+ or rd_lo, rt_hi
+#endif
+
+#ifdef FPU64
+#define MOVE_TO_FPU_HIGH(r, flo, fhi) \
+ mthc1 r, flo
+#else
+#define MOVE_TO_FPU_HIGH(r, flo, fhi) \
+ mtc1 r, fhi
+#endif
+
+#ifdef MIPS32REVGE6
+#define JR(rt) \
+ jic rt, 0
+#define LSA(rd, rs, rt, sa) \
+ .if sa; \
+ lsa rd, rs, rt, sa; \
+ .else; \
+ addu rd, rs, rt; \
+ .endif
+#else
+#define JR(rt) \
+ jalr zero, rt
+#define LSA(rd, rs, rt, sa) \
+ .if sa; \
+ .set push; \
+ .set noat; \
+ sll AT, rs, sa; \
+ addu rd, AT, rt; \
+ .set pop; \
+ .else; \
+ addu rd, rs, rt; \
+ .endif
+#endif
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_SHADOWFRAME OFF_FP(0)
+
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+#define EXPORT_PC() \
+ sw rPC, OFF_FP_DEX_PC_PTR(rFP)
+
+#define EXPORT_DEX_PC(tmp) \
+ lw tmp, OFF_FP_DEX_INSTRUCTIONS(rFP); \
+ sw rPC, OFF_FP_DEX_PC_PTR(rFP); \
+ subu tmp, rPC, tmp; \
+ sra tmp, tmp, 1; \
+ sw tmp, OFF_FP_DEX_PC(rFP)
+
+/*
+ * Fetch the next instruction from rPC into rINST. Does not advance rPC.
+ */
+#define FETCH_INST() lhu rINST, (rPC)
+
+/*
+ * Fetch the next instruction from the specified offset. Advances rPC
+ * to point to the next instruction. "_count" is in 16-bit code units.
+ *
+ * This must come AFTER anything that can throw an exception, or the
+ * exception catch may miss. (This also implies that it must come after
+ * EXPORT_PC().)
+ */
+#define FETCH_ADVANCE_INST(_count) \
+ lhu rINST, ((_count)*2)(rPC); \
+ addu rPC, rPC, ((_count) * 2)
+
+/*
+ * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
+ * rINST ahead of possible exception point. Be sure to manually advance rPC
+ * later.
+ */
+#define PREFETCH_INST(_count) lhu rINST, ((_count)*2)(rPC)
+
+/* Advance rPC by some number of code units. */
+#define ADVANCE(_count) addu rPC, rPC, ((_count) * 2)
+
+/*
+ * Fetch the next instruction from an offset specified by rd. Updates
+ * rPC to point to the next instruction. "rd" must specify the distance
+ * in bytes, *not* 16-bit code units, and may be a signed value.
+ */
+#define FETCH_ADVANCE_INST_RB(rd) \
+ addu rPC, rPC, rd; \
+ lhu rINST, (rPC)
+
+/*
+ * Fetch a half-word code unit from an offset past the current PC. The
+ * "_count" value is in 16-bit code units. Does not advance rPC.
+ *
+ * The "_S" variant works the same but treats the value as signed.
+ */
+#define FETCH(rd, _count) lhu rd, ((_count) * 2)(rPC)
+#define FETCH_S(rd, _count) lh rd, ((_count) * 2)(rPC)
+
+/*
+ * Fetch one byte from an offset past the current PC. Pass in the same
+ * "_count" as you would for FETCH, and an additional 0/1 indicating which
+ * byte of the halfword you want (lo/hi).
+ */
+#define FETCH_B(rd, _count, _byte) lbu rd, ((_count) * 2 + _byte)(rPC)
+
+/*
+ * Put the instruction's opcode field into the specified register.
+ */
+#define GET_INST_OPCODE(rd) and rd, rINST, 0xFF
+
+/*
+ * Transform opcode into branch target address.
+ */
+#define GET_OPCODE_TARGET(rd) \
+ sll rd, rd, ${handler_size_bits}; \
+ addu rd, rIBASE, rd
+
+/*
+ * Begin executing the opcode in rd.
+ */
+#define GOTO_OPCODE(rd) \
+ GET_OPCODE_TARGET(rd); \
+ JR(rd)
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ */
+#define GET_VREG(rd, rix) LOAD_eas2(rd, rFP, rix)
+
+#define GET_VREG_F(rd, rix) \
+ .set noat; \
+ EAS2(AT, rFP, rix); \
+ l.s rd, (AT); \
+ .set at
+
+#ifdef MIPS32REVGE6
+#define SET_VREG(rd, rix) \
+ lsa t8, rix, rFP, 2; \
+ sw rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8)
+#else
+#define SET_VREG(rd, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8)
+#endif
+
+#ifdef MIPS32REVGE6
+#define SET_VREG_OBJECT(rd, rix) \
+ lsa t8, rix, rFP, 2; \
+ sw rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ sw rd, 0(t8)
+#else
+#define SET_VREG_OBJECT(rd, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw rd, 0(t8)
+#endif
+
+#ifdef MIPS32REVGE6
+#define SET_VREG64(rlo, rhi, rix) \
+ lsa t8, rix, rFP, 2; \
+ sw rlo, 0(t8); \
+ sw rhi, 4(t8); \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8)
+#else
+#define SET_VREG64(rlo, rhi, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rlo, 0(t8); \
+ sw rhi, 4(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8)
+#endif
+
+#ifdef MIPS32REVGE6
+#define SET_VREG_F(rd, rix) \
+ lsa t8, rix, rFP, 2; \
+ s.s rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8)
+#else
+#define SET_VREG_F(rd, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ s.s rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8)
+#endif
+
+#ifdef MIPS32REVGE6
+#define SET_VREG64_F(rlo, rhi, rix) \
+ lsa t8, rix, rFP, 2; \
+ .set noat; \
+ mfhc1 AT, rlo; \
+ s.s rlo, 0(t8); \
+ sw AT, 4(t8); \
+ .set at; \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8)
+#elif defined(FPU64)
+#define SET_VREG64_F(rlo, rhi, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rREFS, AT; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8); \
+ addu t8, rFP, AT; \
+ mfhc1 AT, rlo; \
+ sw AT, 4(t8); \
+ .set at; \
+ s.s rlo, 0(t8)
+#else
+#define SET_VREG64_F(rlo, rhi, rix) \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ s.s rlo, 0(t8); \
+ s.s rhi, 4(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8)
+#endif
+
+/* Combination of the SET_VREG and GOTO_OPCODE functions to save 1 instruction */
+#ifdef MIPS32REVGE6
+#define SET_VREG_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ lsa t8, rix, rFP, 2; \
+ sw rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ jalr zero, dst; \
+ sw zero, 0(t8); \
+ .set reorder
+#else
+#define SET_VREG_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ jalr zero, dst; \
+ sw zero, 0(t8); \
+ .set reorder
+#endif
+
+/* Combination of the SET_VREG_OBJECT and GOTO_OPCODE functions to save 1 instruction */
+#ifdef MIPS32REVGE6
+#define SET_VREG_OBJECT_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ lsa t8, rix, rFP, 2; \
+ sw rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ jalr zero, dst; \
+ sw rd, 0(t8); \
+ .set reorder
+#else
+#define SET_VREG_OBJECT_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ jalr zero, dst; \
+ sw rd, 0(t8); \
+ .set reorder
+#endif
+
+/* Combination of the SET_VREG64 and GOTO_OPCODE functions to save 1 instruction */
+#ifdef MIPS32REVGE6
+#define SET_VREG64_GOTO(rlo, rhi, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ lsa t8, rix, rFP, 2; \
+ sw rlo, 0(t8); \
+ sw rhi, 4(t8); \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8); \
+ jalr zero, dst; \
+ sw zero, 4(t8); \
+ .set reorder
+#else
+#define SET_VREG64_GOTO(rlo, rhi, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ sw rlo, 0(t8); \
+ sw rhi, 4(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8); \
+ jalr zero, dst; \
+ sw zero, 4(t8); \
+ .set reorder
+#endif
+
+/* Combination of the SET_VREG_F and GOTO_OPCODE functions to save 1 instruction */
+#ifdef MIPS32REVGE6
+#define SET_VREG_F_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ lsa t8, rix, rFP, 2; \
+ s.s rd, 0(t8); \
+ lsa t8, rix, rREFS, 2; \
+ jalr zero, dst; \
+ sw zero, 0(t8); \
+ .set reorder
+#else
+#define SET_VREG_F_GOTO(rd, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ s.s rd, 0(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ jalr zero, dst; \
+ sw zero, 0(t8); \
+ .set reorder
+#endif
+
+/* Combination of the SET_VREG64_F and GOTO_OPCODE functions to save 1 instruction */
+#ifdef MIPS32REVGE6
+#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ lsa t8, rix, rFP, 2; \
+ .set noat; \
+ mfhc1 AT, rlo; \
+ s.s rlo, 0(t8); \
+ sw AT, 4(t8); \
+ .set at; \
+ lsa t8, rix, rREFS, 2; \
+ sw zero, 0(t8); \
+ jalr zero, dst; \
+ sw zero, 4(t8); \
+ .set reorder
+#elif defined(FPU64)
+#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rREFS, AT; \
+ sw zero, 0(t8); \
+ sw zero, 4(t8); \
+ addu t8, rFP, AT; \
+ mfhc1 AT, rlo; \
+ sw AT, 4(t8); \
+ .set at; \
+ jalr zero, dst; \
+ s.s rlo, 0(t8); \
+ .set reorder
+#else
+#define SET_VREG64_F_GOTO(rlo, rhi, rix, dst) \
+ .set noreorder; \
+ GET_OPCODE_TARGET(dst); \
+ .set noat; \
+ sll AT, rix, 2; \
+ addu t8, rFP, AT; \
+ s.s rlo, 0(t8); \
+ s.s rhi, 4(t8); \
+ addu t8, rREFS, AT; \
+ .set at; \
+ sw zero, 0(t8); \
+ jalr zero, dst; \
+ sw zero, 4(t8); \
+ .set reorder
+#endif
+
+#define GET_OPA(rd) srl rd, rINST, 8
+#ifdef MIPS32REVGE2
+#define GET_OPA4(rd) ext rd, rINST, 8, 4
+#else
+#define GET_OPA4(rd) GET_OPA(rd); and rd, 0xf
+#endif
+#define GET_OPB(rd) srl rd, rINST, 12
+
+/*
+ * Form an Effective Address rd = rbase + roff<<shift;
+ * Uses reg AT on pre-R6.
+ */
+#define EASN(rd, rbase, roff, shift) LSA(rd, roff, rbase, shift)
+
+#define EAS1(rd, rbase, roff) EASN(rd, rbase, roff, 1)
+#define EAS2(rd, rbase, roff) EASN(rd, rbase, roff, 2)
+#define EAS3(rd, rbase, roff) EASN(rd, rbase, roff, 3)
+#define EAS4(rd, rbase, roff) EASN(rd, rbase, roff, 4)
+
+#define LOAD_eas2(rd, rbase, roff) \
+ .set noat; \
+ EAS2(AT, rbase, roff); \
+ lw rd, 0(AT); \
+ .set at
+
+#define STORE_eas2(rd, rbase, roff) \
+ .set noat; \
+ EAS2(AT, rbase, roff); \
+ sw rd, 0(AT); \
+ .set at
+
+#define LOAD_RB_OFF(rd, rbase, off) lw rd, off(rbase)
+#define STORE_RB_OFF(rd, rbase, off) sw rd, off(rbase)
+
+#define STORE64_off(rlo, rhi, rbase, off) \
+ sw rlo, off(rbase); \
+ sw rhi, (off+4)(rbase)
+#define LOAD64_off(rlo, rhi, rbase, off) \
+ lw rlo, off(rbase); \
+ lw rhi, (off+4)(rbase)
+
+#define STORE64(rlo, rhi, rbase) STORE64_off(rlo, rhi, rbase, 0)
+#define LOAD64(rlo, rhi, rbase) LOAD64_off(rlo, rhi, rbase, 0)
+
+#ifdef FPU64
+#define STORE64_off_F(rlo, rhi, rbase, off) \
+ s.s rlo, off(rbase); \
+ .set noat; \
+ mfhc1 AT, rlo; \
+ sw AT, (off+4)(rbase); \
+ .set at
+#define LOAD64_off_F(rlo, rhi, rbase, off) \
+ l.s rlo, off(rbase); \
+ .set noat; \
+ lw AT, (off+4)(rbase); \
+ mthc1 AT, rlo; \
+ .set at
+#else
+#define STORE64_off_F(rlo, rhi, rbase, off) \
+ s.s rlo, off(rbase); \
+ s.s rhi, (off+4)(rbase)
+#define LOAD64_off_F(rlo, rhi, rbase, off) \
+ l.s rlo, off(rbase); \
+ l.s rhi, (off+4)(rbase)
+#endif
+
+#define STORE64_F(rlo, rhi, rbase) STORE64_off_F(rlo, rhi, rbase, 0)
+#define LOAD64_F(rlo, rhi, rbase) LOAD64_off_F(rlo, rhi, rbase, 0)
+
+#define LOAD_base_offMirrorArray_length(rd, rbase) LOAD_RB_OFF(rd, rbase, MIRROR_ARRAY_LENGTH_OFFSET)
+
+#define STACK_STORE(rd, off) sw rd, off(sp)
+#define STACK_LOAD(rd, off) lw rd, off(sp)
+#define CREATE_STACK(n) subu sp, sp, n
+#define DELETE_STACK(n) addu sp, sp, n
+
+#define LOAD_ADDR(dest, addr) la dest, addr
+#define LOAD_IMM(dest, imm) li dest, imm
+#define MOVE_REG(dest, src) move dest, src
+#define STACK_SIZE 128
+
+#define STACK_OFFSET_ARG04 16
+#define STACK_OFFSET_ARG05 20
+#define STACK_OFFSET_ARG06 24
+#define STACK_OFFSET_ARG07 28
+#define STACK_OFFSET_GP 84
+
+#define JAL(n) jal n
+#define BAL(n) bal n
+
+/*
+ * FP register usage restrictions:
+ * 1) We don't use the callee save FP registers so we don't have to save them.
+ * 2) We don't use the odd FP registers so we can share code with mips32r6.
+ */
+#define STACK_STORE_FULL() CREATE_STACK(STACK_SIZE); \
+ STACK_STORE(ra, 124); \
+ STACK_STORE(s8, 120); \
+ STACK_STORE(s0, 116); \
+ STACK_STORE(s1, 112); \
+ STACK_STORE(s2, 108); \
+ STACK_STORE(s3, 104); \
+ STACK_STORE(s4, 100); \
+ STACK_STORE(s5, 96); \
+ STACK_STORE(s6, 92); \
+ STACK_STORE(s7, 88);
+
+#define STACK_LOAD_FULL() STACK_LOAD(gp, STACK_OFFSET_GP); \
+ STACK_LOAD(s7, 88); \
+ STACK_LOAD(s6, 92); \
+ STACK_LOAD(s5, 96); \
+ STACK_LOAD(s4, 100); \
+ STACK_LOAD(s3, 104); \
+ STACK_LOAD(s2, 108); \
+ STACK_LOAD(s1, 112); \
+ STACK_LOAD(s0, 116); \
+ STACK_LOAD(s8, 120); \
+ STACK_LOAD(ra, 124); \
+ DELETE_STACK(STACK_SIZE)
+
+#define REFRESH_IBASE() \
+ lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
+
+/* Constants for float/double_to_int/long conversions */
+#define INT_MIN 0x80000000
+#define INT_MIN_AS_FLOAT 0xCF000000
+#define INT_MIN_AS_DOUBLE_HIGH 0xC1E00000
+#define LONG_MIN_HIGH 0x80000000
+#define LONG_MIN_AS_FLOAT 0xDF000000
+#define LONG_MIN_AS_DOUBLE_HIGH 0xC3E00000
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Interpreter entry point.
+ */
+
+ .text
+ .align 2
+ .global ExecuteMterpImpl
+ .ent ExecuteMterpImpl
+ .frame sp, STACK_SIZE, ra
+/*
+ * On entry:
+ * a0 Thread* self
+ * a1 dex_instructions
+ * a2 ShadowFrame
+ * a3 JValue* result_register
+ *
+ */
+
+ExecuteMterpImpl:
+ .cfi_startproc
+ .set noreorder
+ .cpload t9
+ .set reorder
+/* Save to the stack. Frame size = STACK_SIZE */
+ STACK_STORE_FULL()
+/* This directive will make sure all subsequent jal restore gp at a known offset */
+ .cprestore STACK_OFFSET_GP
+
+ /* Remember the return register */
+ sw a3, SHADOWFRAME_RESULT_REGISTER_OFFSET(a2)
+
+ /* Remember the dex instruction pointer */
+ sw a1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(a2)
+
+ /* set up "named" registers */
+ move rSELF, a0
+ lw a0, SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(a2)
+ addu rFP, a2, SHADOWFRAME_VREGS_OFFSET # point to vregs.
+ EAS2(rREFS, rFP, a0) # point to reference array in shadow frame
+ lw a0, SHADOWFRAME_DEX_PC_OFFSET(a2) # Get starting dex_pc
+ EAS1(rPC, a1, a0) # Create direct pointer to 1st dex opcode
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+
+ EXPORT_PC()
+
+ /* Starting ibase */
+ lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
+
+ /* Set up for backwards branches & osr profiling */
+ lw a0, OFF_FP_METHOD(rFP)
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rSELF
+ JAL(MterpSetUpHotnessCountdown) # (method, shadow_frame, self)
+ move rPROFILE, v0 # Starting hotness countdown to rPROFILE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST() # load rINST from rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Note that the call to MterpCheckBefore is done as a tail call.
+ */
+ .extern MterpCheckBefore
+ la ra, artMterpAsmInstructionStart + (${opnum} * 128) # Addr of primary handler
+ lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF) # refresh IBASE
+ move a0, rSELF # arg0
+ addu a1, rFP, OFF_FP_SHADOWFRAME # arg1
+ move a2, rPC
+ la t9, MterpCheckBefore
+ jalr zero, t9 # Tail call to Mterp(self, shadow_frame, dex_pc_ptr)
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ b MterpFallback
+
+%def footer():
+/*
+ * ===========================================================================
+ * Common subroutines and data
+ * ===========================================================================
+ */
+
+ .text
+ .align 2
+
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+common_errDivideByZero:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogDivideByZeroException)
+#endif
+ b MterpCommonFallback
+
+common_errArrayIndex:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogArrayIndexException)
+#endif
+ b MterpCommonFallback
+
+common_errNegativeArraySize:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogNegativeArraySizeException)
+#endif
+ b MterpCommonFallback
+
+common_errNoSuchMethod:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogNoSuchMethodException)
+#endif
+ b MterpCommonFallback
+
+common_errNullObject:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogNullObjectException)
+#endif
+ b MterpCommonFallback
+
+common_exceptionThrown:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogExceptionThrownException)
+#endif
+ b MterpCommonFallback
+
+MterpSuspendFallback:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ lw a2, THREAD_FLAGS_OFFSET(rSELF)
+ JAL(MterpLogSuspendFallback)
+#endif
+ b MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ lw a0, THREAD_EXCEPTION_OFFSET(rSELF)
+ beqz a0, MterpFallback # If exception, fall back to reference interpreter.
+ /* intentional fallthrough - handle pending exception. */
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+MterpException:
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpHandleException) # (self, shadow_frame)
+ beqz v0, MterpExceptionReturn # no local catch, back to caller.
+ lw a0, OFF_FP_DEX_INSTRUCTIONS(rFP)
+ lw a1, OFF_FP_DEX_PC(rFP)
+ lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
+ EAS1(rPC, a0, a1) # generate new dex_pc_ptr
+ /* Do we need to switch interpreters? */
+ JAL(MterpShouldSwitchInterpreters)
+ bnez v0, MterpFallback
+ /* resume execution at catch block */
+ EXPORT_PC()
+ FETCH_INST()
+ GET_INST_OPCODE(t0)
+ GOTO_OPCODE(t0)
+ /* NOTE: no fallthrough */
+
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * rINST <= signed offset
+ * rPROFILE <= signed hotness countdown (expanded to 32 bits)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ */
+MterpCommonTakenBranchNoFlags:
+ bgtz rINST, .L_forward_branch # don't add forward branches to hotness
+/*
+ * We need to subtract 1 from positive values and we should not see 0 here,
+ * so we may use the result of the comparison with -1.
+ */
+#if JIT_CHECK_OSR != -1
+# error "JIT_CHECK_OSR must be -1."
+#endif
+ li t0, JIT_CHECK_OSR
+ beq rPROFILE, t0, .L_osr_check
+ blt rPROFILE, t0, .L_resume_backward_branch
+ subu rPROFILE, 1
+ beqz rPROFILE, .L_add_batch # counted down to zero - report
+.L_resume_backward_branch:
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ REFRESH_IBASE()
+ addu a2, rINST, rINST # a2<- byte offset
+ FETCH_ADVANCE_INST_RB(a2) # update rPC, load rINST
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ bnez ra, .L_suspend_request_pending
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+.L_suspend_request_pending:
+ EXPORT_PC()
+ move a0, rSELF
+ JAL(MterpSuspendCheck) # (self)
+ bnez v0, MterpFallback
+ REFRESH_IBASE() # might have changed during suspend
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+.L_no_count_backwards:
+ li t0, JIT_CHECK_OSR # check for possible OSR re-entry
+ bne rPROFILE, t0, .L_resume_backward_branch
+.L_osr_check:
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST
+ EXPORT_PC()
+ JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ bnez v0, MterpOnStackReplacement
+ b .L_resume_backward_branch
+
+.L_forward_branch:
+ li t0, JIT_CHECK_OSR # check for possible OSR re-entry
+ beq rPROFILE, t0, .L_check_osr_forward
+.L_resume_forward_branch:
+ add a2, rINST, rINST # a2<- byte offset
+ FETCH_ADVANCE_INST_RB(a2) # update rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+.L_check_osr_forward:
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST
+ EXPORT_PC()
+ JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ bnez v0, MterpOnStackReplacement
+ b .L_resume_forward_branch
+
+.L_add_batch:
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
+ lw a0, OFF_FP_METHOD(rFP)
+ move a2, rSELF
+ JAL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ move rPROFILE, v0 # restore new hotness countdown to rPROFILE
+ b .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ li a2, 2
+ EXPORT_PC()
+ JAL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ bnez v0, MterpOnStackReplacement
+ FETCH_ADVANCE_INST(2)
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST
+ JAL(MterpLogOSR)
+#endif
+ li v0, 1 # Signal normal return
+ b MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+MterpFallback:
+ EXPORT_PC()
+#if MTERP_LOGGING
+ move a0, rSELF
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ JAL(MterpLogFallback)
+#endif
+MterpCommonFallback:
+ move v0, zero # signal retry with reference interpreter.
+ b MterpDone
+/*
+ * We pushed some registers on the stack in ExecuteMterpImpl, then saved
+ * SP and LR. Here we restore SP, restore the registers, and then restore
+ * LR to PC.
+ *
+ * On entry:
+ * uint32_t* rFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ li v0, 1 # signal return to caller.
+ b MterpDone
+MterpReturn:
+ lw a2, OFF_FP_RESULT_REGISTER(rFP)
+ sw v0, 0(a2)
+ sw v1, 4(a2)
+ li v0, 1 # signal return to caller.
+MterpDone:
+/*
+ * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ blez rPROFILE, .L_pop_and_return # if > 0, we may have some counts to report.
+
+MterpProfileActive:
+ move rINST, v0 # stash return value
+ /* Report cached hotness counts */
+ lw a0, OFF_FP_METHOD(rFP)
+ addu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rSELF
+ sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
+ JAL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ move v0, rINST # restore return value
+
+.L_pop_and_return:
+/* Restore from the stack and return. Frame size = STACK_SIZE */
+ STACK_LOAD_FULL()
+ jalr zero, ra
+
+ .cfi_endproc
+ .end ExecuteMterpImpl
+
+%def instruction_end():
+
+ .global artMterpAsmInstructionEnd
+artMterpAsmInstructionEnd:
+
+%def instruction_end_alt():
+
+ .global artMterpAsmAltInstructionEnd
+artMterpAsmAltInstructionEnd:
+
+%def instruction_end_sister():
+
+ .global artMterpAsmSisterEnd
+artMterpAsmSisterEnd:
+
+%def instruction_start():
+
+ .global artMterpAsmInstructionStart
+artMterpAsmInstructionStart = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ .global artMterpAsmAltInstructionStart
+artMterpAsmAltInstructionStart = .L_ALT_op_nop
+ .text
+
+%def instruction_start_sister():
+
+ .global artMterpAsmSisterStart
+ .text
+ .balign 4
+artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/mips/object.S b/runtime/interpreter/mterp/mips/object.S
new file mode 100644
index 0000000..a987789
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/object.S
@@ -0,0 +1,257 @@
+%def field(helper=""):
+TODO
+
+%def op_check_cast():
+ /*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class@BBBB */
+ EXPORT_PC()
+ FETCH(a0, 1) # a0 <- BBBB
+ GET_OPA(a1) # a1 <- AA
+ EAS2(a1, rFP, a1) # a1 <- &object
+ lw a2, OFF_FP_METHOD(rFP) # a2 <- method
+ move a3, rSELF # a3 <- self
+ JAL(MterpCheckCast) # v0 <- CheckCast(index, &obj, method, self)
+ PREFETCH_INST(2)
+ bnez v0, MterpPossibleException
+ ADVANCE(2)
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="lbu")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="lb")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="lhu")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset@CCCC */
+ GET_OPB(a2) # a2 <- B
+ FETCH(a1, 1) # a1 <- field byte offset
+ EXPORT_PC()
+ GET_VREG(a0, a2) # a0 <- object we're operating on
+ JAL(artIGetObjectFromMterp) # v0 <- GetObj(obj, offset)
+ lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
+ GET_OPA4(a2) # a2<- A+
+ PREFETCH_INST(2) # load rINST
+ bnez a3, MterpPossibleException # bail out
+ ADVANCE(2) # advance rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
+
+%def op_iget_quick(load="lw"):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
+ /* op vA, vB, offset@CCCC */
+ GET_OPB(a2) # a2 <- B
+ GET_VREG(a3, a2) # a3 <- object we're operating on
+ FETCH(a1, 1) # a1 <- field byte offset
+ GET_OPA4(a2) # a2 <- A(+)
+ # check object for null
+ beqz a3, common_errNullObject # object was null
+ addu t0, a3, a1
+ $load a0, 0(t0) # a0 <- obj.field (8/16/32 bits)
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a0, a2, t0) # fp[A] <- a0
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="lh")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+ /* iget-wide-quick vA, vB, offset@CCCC */
+ GET_OPB(a2) # a2 <- B
+ GET_VREG(a3, a2) # a3 <- object we're operating on
+ FETCH(a1, 1) # a1 <- field byte offset
+ GET_OPA4(a2) # a2 <- A(+)
+ # check object for null
+ beqz a3, common_errNullObject # object was null
+ addu t0, a3, a1 # t0 <- a3 + a1
+ LOAD64(a0, a1, t0) # a0 <- obj.field (64 bits, aligned)
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a2, t0) # fp[A] <- a0/a1
+
+%def op_instance_of():
+ /*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class@CCCC */
+ EXPORT_PC()
+ FETCH(a0, 1) # a0 <- CCCC
+ GET_OPB(a1) # a1 <- B
+ EAS2(a1, rFP, a1) # a1 <- &object
+ lw a2, OFF_FP_METHOD(rFP) # a2 <- method
+ move a3, rSELF # a3 <- self
+ GET_OPA4(rOBJ) # rOBJ <- A+
+ JAL(MterpInstanceOf) # v0 <- Mterp(index, &obj, method, self)
+ lw a1, THREAD_EXCEPTION_OFFSET(rSELF)
+ PREFETCH_INST(2) # load rINST
+ bnez a1, MterpException
+ ADVANCE(2) # advance rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(v0, rOBJ, t0) # vA <- v0
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(store="sb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(store="sb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(store="sh")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ /* For: iput-object-quick */
+ /* op vA, vB, offset@CCCC */
+ EXPORT_PC()
+ addu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ JAL(MterpIputObjectQuick)
+ beqz v0, MterpException
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_iput_quick(store="sw"):
+ /* For: iput-quick, iput-object-quick */
+ /* op vA, vB, offset@CCCC */
+ GET_OPB(a2) # a2 <- B
+ GET_VREG(a3, a2) # a3 <- fp[B], the object pointer
+ FETCH(a1, 1) # a1 <- field byte offset
+ GET_OPA4(a2) # a2 <- A(+)
+ beqz a3, common_errNullObject # object was null
+ GET_VREG(a0, a2) # a0 <- fp[A]
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ addu t0, a3, a1
+ GET_INST_OPCODE(t1) # extract opcode from rINST
+ GET_OPCODE_TARGET(t1)
+ $store a0, 0(t0) # obj.field (8/16/32 bits) <- a0
+ JR(t1) # jump to next instruction
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(store="sh")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset@CCCC */
+ GET_OPA4(a0) # a0 <- A(+)
+ GET_OPB(a1) # a1 <- B
+ GET_VREG(a2, a1) # a2 <- fp[B], the object pointer
+ # check object for null
+ beqz a2, common_errNullObject # object was null
+ EAS2(a3, rFP, a0) # a3 <- &fp[A]
+ LOAD64(a0, a1, a3) # a0/a1 <- fp[A]
+ FETCH(a3, 1) # a3 <- field byte offset
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ addu a2, a2, a3 # obj.field (64 bits, aligned) <- a0/a1
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GET_OPCODE_TARGET(t0)
+ STORE64(a0, a1, a2) # obj.field (64 bits, aligned) <- a0/a1
+ JR(t0) # jump to next instruction
+
+%def op_new_instance():
+ /*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class@BBBB */
+ EXPORT_PC()
+ addu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rSELF
+ move a2, rINST
+ JAL(MterpNewInstance)
+ beqz v0, MterpPossibleException
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/mips/op_add_double.S b/runtime/interpreter/mterp/mips/op_add_double.S
deleted file mode 100644
index 8308cdc..0000000
--- a/runtime/interpreter/mterp/mips/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% fbinopWide(instr="add.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_add_double_2addr.S b/runtime/interpreter/mterp/mips/op_add_double_2addr.S
deleted file mode 100644
index 41b0996..0000000
--- a/runtime/interpreter/mterp/mips/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% fbinopWide2addr(instr="add.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_add_float.S b/runtime/interpreter/mterp/mips/op_add_float.S
deleted file mode 100644
index 807ea97..0000000
--- a/runtime/interpreter/mterp/mips/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% fbinop(instr="add.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_add_float_2addr.S b/runtime/interpreter/mterp/mips/op_add_float_2addr.S
deleted file mode 100644
index c5735ae..0000000
--- a/runtime/interpreter/mterp/mips/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% fbinop2addr(instr="add.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_add_int.S b/runtime/interpreter/mterp/mips/op_add_int.S
deleted file mode 100644
index ed0fc01..0000000
--- a/runtime/interpreter/mterp/mips/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_add_int_2addr.S b/runtime/interpreter/mterp/mips/op_add_int_2addr.S
deleted file mode 100644
index ed0b131..0000000
--- a/runtime/interpreter/mterp/mips/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_add_int_lit16.S b/runtime/interpreter/mterp/mips/op_add_int_lit16.S
deleted file mode 100644
index 126807a..0000000
--- a/runtime/interpreter/mterp/mips/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_add_int_lit8.S b/runtime/interpreter/mterp/mips/op_add_int_lit8.S
deleted file mode 100644
index 30184c4..0000000
--- a/runtime/interpreter/mterp/mips/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_add_long.S b/runtime/interpreter/mterp/mips/op_add_long.S
deleted file mode 100644
index 3220506..0000000
--- a/runtime/interpreter/mterp/mips/op_add_long.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_add_long():
-/*
- * The compiler generates the following sequence for
- * [v1 v0] = [a1 a0] + [a3 a2];
- * addu v0,a2,a0
- * addu a1,a3,a1
- * sltu v1,v0,a2
- * addu v1,v1,a1
- */
-% binopWide(result0="v0", result1="v1", preinstr="addu v0, a2, a0", instr="addu a1, a3, a1; sltu v1, v0, a2; addu v1, v1, a1")
diff --git a/runtime/interpreter/mterp/mips/op_add_long_2addr.S b/runtime/interpreter/mterp/mips/op_add_long_2addr.S
deleted file mode 100644
index 3bbc1f3..0000000
--- a/runtime/interpreter/mterp/mips/op_add_long_2addr.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_add_long_2addr():
-/*
- * See op_add_long.S for details
- */
-% binopWide2addr(result0="v0", result1="v1", preinstr="addu v0, a2, a0", instr="addu a1, a3, a1; sltu v1, v0, a2; addu v1, v1, a1")
diff --git a/runtime/interpreter/mterp/mips/op_aget.S b/runtime/interpreter/mterp/mips/op_aget.S
deleted file mode 100644
index 026095f..0000000
--- a/runtime/interpreter/mterp/mips/op_aget.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
- * instructions. We use a pair of FETCH_Bs instead.
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short
- *
- * NOTE: assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B(a2, 1, 0) # a2 <- BB
- GET_OPA(rOBJ) # rOBJ <- AA
- FETCH_B(a3, 1, 1) # a3 <- CC
- GET_VREG(a0, a2) # a0 <- vBB (array object)
- GET_VREG(a1, a3) # a1 <- vCC (requested index)
- # null array object?
- beqz a0, common_errNullObject # yes, bail
- LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
- EASN(a0, a0, a1, $shift) # a0 <- arrayObj + index*width
- # a1 >= a3; compare unsigned index
- bgeu a1, a3, common_errArrayIndex # index >= length, bail
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- $load a2, $data_offset(a0) # a2 <- vBB[vCC]
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a2, rOBJ, t0) # vAA <- a2
diff --git a/runtime/interpreter/mterp/mips/op_aget_boolean.S b/runtime/interpreter/mterp/mips/op_aget_boolean.S
deleted file mode 100644
index 7b28bc8..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aget_byte.S b/runtime/interpreter/mterp/mips/op_aget_byte.S
deleted file mode 100644
index a4a0b7e..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aget_char.S b/runtime/interpreter/mterp/mips/op_aget_char.S
deleted file mode 100644
index 465de09..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aget_object.S b/runtime/interpreter/mterp/mips/op_aget_object.S
deleted file mode 100644
index 17a1e0c..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_object.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_aget_object():
- /*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- FETCH_B(a2, 1, 0) # a2 <- BB
- GET_OPA(rOBJ) # rOBJ <- AA
- FETCH_B(a3, 1, 1) # a3 <- CC
- EXPORT_PC()
- GET_VREG(a0, a2) # a0 <- vBB (array object)
- GET_VREG(a1, a3) # a1 <- vCC (requested index)
- JAL(artAGetObjectFromMterp) # v0 <- GetObj(array, index)
- lw a1, THREAD_EXCEPTION_OFFSET(rSELF)
- PREFETCH_INST(2) # load rINST
- bnez a1, MterpException
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_OBJECT_GOTO(v0, rOBJ, t0) # vAA <- v0
diff --git a/runtime/interpreter/mterp/mips/op_aget_short.S b/runtime/interpreter/mterp/mips/op_aget_short.S
deleted file mode 100644
index 4faa9ad..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aget_wide.S b/runtime/interpreter/mterp/mips/op_aget_wide.S
deleted file mode 100644
index 4045c11..0000000
--- a/runtime/interpreter/mterp/mips/op_aget_wide.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_aget_wide():
- /*
- * Array get, 64 bits. vAA <- vBB[vCC].
- *
- * Arrays of long/double are 64-bit aligned.
- */
- /* aget-wide vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8 # a3 <- CC
- GET_VREG(a0, a2) # a0 <- vBB (array object)
- GET_VREG(a1, a3) # a1 <- vCC (requested index)
- # null array object?
- beqz a0, common_errNullObject # yes, bail
- LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
- EAS3(a0, a0, a1) # a0 <- arrayObj + index*width
- bgeu a1, a3, common_errArrayIndex # index >= length, bail
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- LOAD64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET)
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a2, a3, rOBJ, t0) # vAA/vAA+1 <- a2/a3
diff --git a/runtime/interpreter/mterp/mips/op_and_int.S b/runtime/interpreter/mterp/mips/op_and_int.S
deleted file mode 100644
index 740411d..0000000
--- a/runtime/interpreter/mterp/mips/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_and_int_2addr.S b/runtime/interpreter/mterp/mips/op_and_int_2addr.S
deleted file mode 100644
index 8224e5f..0000000
--- a/runtime/interpreter/mterp/mips/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_and_int_lit16.S b/runtime/interpreter/mterp/mips/op_and_int_lit16.S
deleted file mode 100644
index 5031f50..0000000
--- a/runtime/interpreter/mterp/mips/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_and_int_lit8.S b/runtime/interpreter/mterp/mips/op_and_int_lit8.S
deleted file mode 100644
index 7a7b8b5..0000000
--- a/runtime/interpreter/mterp/mips/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_and_long.S b/runtime/interpreter/mterp/mips/op_and_long.S
deleted file mode 100644
index 210e6a1..0000000
--- a/runtime/interpreter/mterp/mips/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(preinstr="and a0, a0, a2", instr="and a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/op_and_long_2addr.S b/runtime/interpreter/mterp/mips/op_and_long_2addr.S
deleted file mode 100644
index c76a5af..0000000
--- a/runtime/interpreter/mterp/mips/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(preinstr="and a0, a0, a2", instr="and a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/op_aput.S b/runtime/interpreter/mterp/mips/op_aput.S
deleted file mode 100644
index 6561f8f..0000000
--- a/runtime/interpreter/mterp/mips/op_aput.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
-
- /*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short
- *
- * NOTE: this assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- FETCH_B(a2, 1, 0) # a2 <- BB
- GET_OPA(rOBJ) # rOBJ <- AA
- FETCH_B(a3, 1, 1) # a3 <- CC
- GET_VREG(a0, a2) # a0 <- vBB (array object)
- GET_VREG(a1, a3) # a1 <- vCC (requested index)
- # null array object?
- beqz a0, common_errNullObject # yes, bail
- LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
- EASN(a0, a0, a1, $shift) # a0 <- arrayObj + index*width
- bgeu a1, a3, common_errArrayIndex # index >= length, bail
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_VREG(a2, rOBJ) # a2 <- vAA
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GET_OPCODE_TARGET(t0)
- $store a2, $data_offset(a0) # vBB[vCC] <- a2
- JR(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_aput_boolean.S b/runtime/interpreter/mterp/mips/op_aput_boolean.S
deleted file mode 100644
index 098bbcd..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aput_byte.S b/runtime/interpreter/mterp/mips/op_aput_byte.S
deleted file mode 100644
index f4b42ee..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aput_char.S b/runtime/interpreter/mterp/mips/op_aput_char.S
deleted file mode 100644
index 18eedae..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aput_object.S b/runtime/interpreter/mterp/mips/op_aput_object.S
deleted file mode 100644
index 89c72ba..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_object.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_aput_object():
- /*
- * Store an object into an array. vBB[vCC] <- vAA.
- *
- */
- /* op vAA, vBB, vCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- JAL(MterpAputObject)
- beqz v0, MterpPossibleException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_aput_short.S b/runtime/interpreter/mterp/mips/op_aput_short.S
deleted file mode 100644
index 61a3c0d..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips/op_aput_wide.S b/runtime/interpreter/mterp/mips/op_aput_wide.S
deleted file mode 100644
index 2fd0cbb..0000000
--- a/runtime/interpreter/mterp/mips/op_aput_wide.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def op_aput_wide():
- /*
- * Array put, 64 bits. vBB[vCC] <- vAA.
- */
- /* aput-wide vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(t0) # t0 <- AA
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8 # a3 <- CC
- GET_VREG(a0, a2) # a0 <- vBB (array object)
- GET_VREG(a1, a3) # a1 <- vCC (requested index)
- # null array object?
- beqz a0, common_errNullObject # yes, bail
- LOAD_base_offMirrorArray_length(a3, a0) # a3 <- arrayObj->length
- EAS3(a0, a0, a1) # a0 <- arrayObj + index*width
- EAS2(rOBJ, rFP, t0) # rOBJ <- &fp[AA]
- # compare unsigned index, length
- bgeu a1, a3, common_errArrayIndex # index >= length, bail
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- LOAD64(a2, a3, rOBJ) # a2/a3 <- vAA/vAA+1
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GET_OPCODE_TARGET(t0)
- STORE64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET) # a2/a3 <- vBB[vCC]
- JR(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_array_length.S b/runtime/interpreter/mterp/mips/op_array_length.S
deleted file mode 100644
index 12348bd..0000000
--- a/runtime/interpreter/mterp/mips/op_array_length.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_array_length():
- /*
- * Return the length of an array.
- */
- /* array-length vA, vB */
- GET_OPB(a1) # a1 <- B
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a0, a1) # a0 <- vB (object ref)
- # is object null?
- beqz a0, common_errNullObject # yup, fail
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- LOAD_base_offMirrorArray_length(a3, a0) # a3 <- array length
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a3, a2, t0) # vA <- length
diff --git a/runtime/interpreter/mterp/mips/op_check_cast.S b/runtime/interpreter/mterp/mips/op_check_cast.S
deleted file mode 100644
index 4d0f286..0000000
--- a/runtime/interpreter/mterp/mips/op_check_cast.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_check_cast():
- /*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- BBBB
- GET_OPA(a1) # a1 <- AA
- EAS2(a1, rFP, a1) # a1 <- &object
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- JAL(MterpCheckCast) # v0 <- CheckCast(index, &obj, method, self)
- PREFETCH_INST(2)
- bnez v0, MterpPossibleException
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_cmp_long.S b/runtime/interpreter/mterp/mips/op_cmp_long.S
deleted file mode 100644
index 7d40b0e..0000000
--- a/runtime/interpreter/mterp/mips/op_cmp_long.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def op_cmp_long():
- /*
- * Compare two 64-bit values
- * x = y return 0
- * x < y return -1
- * x > y return 1
- *
- * I think I can improve on the ARM code by the following observation
- * slt t0, x.hi, y.hi; # (x.hi < y.hi) ? 1:0
- * sgt t1, x.hi, y.hi; # (y.hi > x.hi) ? 1:0
- * subu v0, t0, t1 # v0= -1:1:0 for [ < > = ]
- */
- /* cmp-long vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8 # a3 <- CC
- EAS2(a2, rFP, a2) # a2 <- &fp[BB]
- EAS2(a3, rFP, a3) # a3 <- &fp[CC]
- LOAD64(a0, a1, a2) # a0/a1 <- vBB/vBB+1
- LOAD64(a2, a3, a3) # a2/a3 <- vCC/vCC+1
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- slt t0, a1, a3 # compare hi
- sgt t1, a1, a3
- subu v0, t1, t0 # v0 <- (-1, 1, 0)
- bnez v0, .L${opcode}_finish
- # at this point x.hi==y.hi
- sltu t0, a0, a2 # compare lo
- sgtu t1, a0, a2
- subu v0, t1, t0 # v0 <- (-1, 1, 0) for [< > =]
-
-.L${opcode}_finish:
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(v0, rOBJ, t0) # vAA <- v0
diff --git a/runtime/interpreter/mterp/mips/op_cmpg_double.S b/runtime/interpreter/mterp/mips/op_cmpg_double.S
deleted file mode 100644
index 8e3d181..0000000
--- a/runtime/interpreter/mterp/mips/op_cmpg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_double():
-% op_cmpl_double(gt_bias="1")
diff --git a/runtime/interpreter/mterp/mips/op_cmpg_float.S b/runtime/interpreter/mterp/mips/op_cmpg_float.S
deleted file mode 100644
index d8afa2a..0000000
--- a/runtime/interpreter/mterp/mips/op_cmpg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_float():
-% op_cmpl_float(gt_bias="1")
diff --git a/runtime/interpreter/mterp/mips/op_cmpl_double.S b/runtime/interpreter/mterp/mips/op_cmpl_double.S
deleted file mode 100644
index ab6dd49..0000000
--- a/runtime/interpreter/mterp/mips/op_cmpl_double.S
+++ /dev/null
@@ -1,52 +0,0 @@
-%def op_cmpl_double(gt_bias="0"):
- /*
- * Compare two floating-point values. Puts 0(==), 1(>), or -1(<)
- * into the destination register based on the comparison results.
- *
- * For: cmpl-double, cmpg-double
- */
- /* op vAA, vBB, vCC */
-
- FETCH(a0, 1) # a0 <- CCBB
- and rOBJ, a0, 255 # rOBJ <- BB
- srl t0, a0, 8 # t0 <- CC
- EAS2(rOBJ, rFP, rOBJ) # rOBJ <- &fp[BB]
- EAS2(t0, rFP, t0) # t0 <- &fp[CC]
- LOAD64_F(ft0, ft0f, rOBJ)
- LOAD64_F(ft1, ft1f, t0)
-#ifdef MIPS32REVGE6
- cmp.eq.d ft2, ft0, ft1
- li rTEMP, 0
- bc1nez ft2, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- cmp.lt.d ft2, ft0, ft1
- li rTEMP, -1
- bc1nez ft2, 1f # done if vBB < vCC (ordered)
- li rTEMP, 1 # vBB > vCC or unordered
- .else
- cmp.lt.d ft2, ft1, ft0
- li rTEMP, 1
- bc1nez ft2, 1f # done if vBB > vCC (ordered)
- li rTEMP, -1 # vBB < vCC or unordered
- .endif
-#else
- c.eq.d fcc0, ft0, ft1
- li rTEMP, 0
- bc1t fcc0, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- c.olt.d fcc0, ft0, ft1
- li rTEMP, -1
- bc1t fcc0, 1f # done if vBB < vCC (ordered)
- li rTEMP, 1 # vBB > vCC or unordered
- .else
- c.olt.d fcc0, ft1, ft0
- li rTEMP, 1
- bc1t fcc0, 1f # done if vBB > vCC (ordered)
- li rTEMP, -1 # vBB < vCC or unordered
- .endif
-#endif
-1:
- GET_OPA(rOBJ)
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(rTEMP, rOBJ, t0) # vAA <- rTEMP
diff --git a/runtime/interpreter/mterp/mips/op_cmpl_float.S b/runtime/interpreter/mterp/mips/op_cmpl_float.S
deleted file mode 100644
index 6542844..0000000
--- a/runtime/interpreter/mterp/mips/op_cmpl_float.S
+++ /dev/null
@@ -1,50 +0,0 @@
-%def op_cmpl_float(gt_bias="0"):
- /*
- * Compare two floating-point values. Puts 0(==), 1(>), or -1(<)
- * into the destination register based on the comparison results.
- *
- * for: cmpl-float, cmpg-float
- */
- /* op vAA, vBB, vCC */
-
- FETCH(a0, 1) # a0 <- CCBB
- and a2, a0, 255 # a2 <- BB
- srl a3, a0, 8
- GET_VREG_F(ft0, a2)
- GET_VREG_F(ft1, a3)
-#ifdef MIPS32REVGE6
- cmp.eq.s ft2, ft0, ft1
- li rTEMP, 0
- bc1nez ft2, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- cmp.lt.s ft2, ft0, ft1
- li rTEMP, -1
- bc1nez ft2, 1f # done if vBB < vCC (ordered)
- li rTEMP, 1 # vBB > vCC or unordered
- .else
- cmp.lt.s ft2, ft1, ft0
- li rTEMP, 1
- bc1nez ft2, 1f # done if vBB > vCC (ordered)
- li rTEMP, -1 # vBB < vCC or unordered
- .endif
-#else
- c.eq.s fcc0, ft0, ft1
- li rTEMP, 0
- bc1t fcc0, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- c.olt.s fcc0, ft0, ft1
- li rTEMP, -1
- bc1t fcc0, 1f # done if vBB < vCC (ordered)
- li rTEMP, 1 # vBB > vCC or unordered
- .else
- c.olt.s fcc0, ft1, ft0
- li rTEMP, 1
- bc1t fcc0, 1f # done if vBB > vCC (ordered)
- li rTEMP, -1 # vBB < vCC or unordered
- .endif
-#endif
-1:
- GET_OPA(rOBJ)
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(rTEMP, rOBJ, t0) # vAA <- rTEMP
diff --git a/runtime/interpreter/mterp/mips/op_const.S b/runtime/interpreter/mterp/mips/op_const.S
deleted file mode 100644
index 5b429d4..0000000
--- a/runtime/interpreter/mterp/mips/op_const.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const():
- /* const vAA, +BBBBbbbb */
- GET_OPA(a3) # a3 <- AA
- FETCH(a0, 1) # a0 <- bbbb (low)
- FETCH(a1, 2) # a1 <- BBBB (high)
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
diff --git a/runtime/interpreter/mterp/mips/op_const_16.S b/runtime/interpreter/mterp/mips/op_const_16.S
deleted file mode 100644
index 85669a9..0000000
--- a/runtime/interpreter/mterp/mips/op_const_16.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, +BBBB */
- FETCH_S(a0, 1) # a0 <- ssssBBBB (sign-extended)
- GET_OPA(a3) # a3 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
diff --git a/runtime/interpreter/mterp/mips/op_const_4.S b/runtime/interpreter/mterp/mips/op_const_4.S
deleted file mode 100644
index 158a246..0000000
--- a/runtime/interpreter/mterp/mips/op_const_4.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_4():
- /* const/4 vA, +B */
- sll a1, rINST, 16 # a1 <- Bxxx0000
- GET_OPA(a0) # a0 <- A+
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- sra a1, a1, 28 # a1 <- sssssssB (sign-extended)
- and a0, a0, 15
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a1, a0, t0) # fp[A] <- a1
diff --git a/runtime/interpreter/mterp/mips/op_const_class.S b/runtime/interpreter/mterp/mips/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/mips/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/mips/op_const_high16.S b/runtime/interpreter/mterp/mips/op_const_high16.S
deleted file mode 100644
index fee5296..0000000
--- a/runtime/interpreter/mterp/mips/op_const_high16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, +BBBB0000 */
- FETCH(a0, 1) # a0 <- 0000BBBB (zero-extended)
- GET_OPA(a3) # a3 <- AA
- sll a0, a0, 16 # a0 <- BBBB0000
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
diff --git a/runtime/interpreter/mterp/mips/op_const_method_handle.S b/runtime/interpreter/mterp/mips/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/mips/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/mips/op_const_method_type.S b/runtime/interpreter/mterp/mips/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/mips/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/mips/op_const_string.S b/runtime/interpreter/mterp/mips/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/mips/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/mips/op_const_string_jumbo.S b/runtime/interpreter/mterp/mips/op_const_string_jumbo.S
deleted file mode 100644
index 0a031f3..0000000
--- a/runtime/interpreter/mterp/mips/op_const_string_jumbo.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, string@BBBBBBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- bbbb (low)
- FETCH(a2, 2) # a2 <- BBBB (high)
- GET_OPA(a1) # a1 <- AA
- INSERT_HIGH_HALF(a0, a2) # a0 <- BBBBbbbb
- addu a2, rFP, OFF_FP_SHADOWFRAME # a2 <- shadow frame
- move a3, rSELF
- JAL(MterpConstString) # v0 <- Mterp(index, tgt_reg, shadow_frame, self)
- PREFETCH_INST(3) # load rINST
- bnez v0, MterpPossibleException
- ADVANCE(3) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_const_wide.S b/runtime/interpreter/mterp/mips/op_const_wide.S
deleted file mode 100644
index b424237..0000000
--- a/runtime/interpreter/mterp/mips/op_const_wide.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, +HHHHhhhhBBBBbbbb */
- FETCH(a0, 1) # a0 <- bbbb (low)
- FETCH(a1, 2) # a1 <- BBBB (low middle)
- FETCH(a2, 3) # a2 <- hhhh (high middle)
- INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb (low word)
- FETCH(a3, 4) # a3 <- HHHH (high)
- GET_OPA(t1) # t1 <- AA
- INSERT_HIGH_HALF(a2, a3) # a2 <- HHHHhhhh (high word)
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a2, t1, t0) # vAA/vAA+1 <- a0/a2
diff --git a/runtime/interpreter/mterp/mips/op_const_wide_16.S b/runtime/interpreter/mterp/mips/op_const_wide_16.S
deleted file mode 100644
index d89a2b6..0000000
--- a/runtime/interpreter/mterp/mips/op_const_wide_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, +BBBB */
- FETCH_S(a0, 1) # a0 <- ssssBBBB (sign-extended)
- GET_OPA(a3) # a3 <- AA
- sra a1, a0, 31 # a1 <- ssssssss
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_const_wide_32.S b/runtime/interpreter/mterp/mips/op_const_wide_32.S
deleted file mode 100644
index f9db953..0000000
--- a/runtime/interpreter/mterp/mips/op_const_wide_32.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, +BBBBbbbb */
- FETCH(a0, 1) # a0 <- 0000bbbb (low)
- GET_OPA(a3) # a3 <- AA
- FETCH_S(a2, 2) # a2 <- ssssBBBB (high)
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- INSERT_HIGH_HALF(a0, a2) # a0 <- BBBBbbbb
- sra a1, a0, 31 # a1 <- ssssssss
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_const_wide_high16.S b/runtime/interpreter/mterp/mips/op_const_wide_high16.S
deleted file mode 100644
index dd0cd94..0000000
--- a/runtime/interpreter/mterp/mips/op_const_wide_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, +BBBB000000000000 */
- FETCH(a1, 1) # a1 <- 0000BBBB (zero-extended)
- GET_OPA(a3) # a3 <- AA
- li a0, 0 # a0 <- 00000000
- sll a1, 16 # a1 <- BBBB0000
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_div_double.S b/runtime/interpreter/mterp/mips/op_div_double.S
deleted file mode 100644
index e1324d0..0000000
--- a/runtime/interpreter/mterp/mips/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% fbinopWide(instr="div.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_div_double_2addr.S b/runtime/interpreter/mterp/mips/op_div_double_2addr.S
deleted file mode 100644
index aa6d16d..0000000
--- a/runtime/interpreter/mterp/mips/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% fbinopWide2addr(instr="div.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_div_float.S b/runtime/interpreter/mterp/mips/op_div_float.S
deleted file mode 100644
index b00c44c..0000000
--- a/runtime/interpreter/mterp/mips/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% fbinop(instr="div.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_div_float_2addr.S b/runtime/interpreter/mterp/mips/op_div_float_2addr.S
deleted file mode 100644
index 5201603..0000000
--- a/runtime/interpreter/mterp/mips/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% fbinop2addr(instr="div.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_div_int.S b/runtime/interpreter/mterp/mips/op_div_int.S
deleted file mode 100644
index 2b49fd2..0000000
--- a/runtime/interpreter/mterp/mips/op_div_int.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_div_int():
-#ifdef MIPS32REVGE6
-% binop(instr="div a0, a0, a1", chkzero="1")
-#else
-% binop(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_div_int_2addr.S b/runtime/interpreter/mterp/mips/op_div_int_2addr.S
deleted file mode 100644
index 325a5e6..0000000
--- a/runtime/interpreter/mterp/mips/op_div_int_2addr.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_div_int_2addr():
-#ifdef MIPS32REVGE6
-% binop2addr(instr="div a0, a0, a1", chkzero="1")
-#else
-% binop2addr(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_div_int_lit16.S b/runtime/interpreter/mterp/mips/op_div_int_lit16.S
deleted file mode 100644
index 7eaf340..0000000
--- a/runtime/interpreter/mterp/mips/op_div_int_lit16.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_div_int_lit16():
-#ifdef MIPS32REVGE6
-% binopLit16(instr="div a0, a0, a1", chkzero="1")
-#else
-% binopLit16(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_div_int_lit8.S b/runtime/interpreter/mterp/mips/op_div_int_lit8.S
deleted file mode 100644
index b6aebb7..0000000
--- a/runtime/interpreter/mterp/mips/op_div_int_lit8.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_div_int_lit8():
-#ifdef MIPS32REVGE6
-% binopLit8(instr="div a0, a0, a1", chkzero="1")
-#else
-% binopLit8(preinstr="div zero, a0, a1", instr="mflo a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_div_long.S b/runtime/interpreter/mterp/mips/op_div_long.S
deleted file mode 100644
index 6311259..0000000
--- a/runtime/interpreter/mterp/mips/op_div_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long():
-% binopWide(result0="v0", result1="v1", instr="JAL(__divdi3)", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips/op_div_long_2addr.S b/runtime/interpreter/mterp/mips/op_div_long_2addr.S
deleted file mode 100644
index b3f7293..0000000
--- a/runtime/interpreter/mterp/mips/op_div_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long_2addr():
-% binopWide2addr(result0="v0", result1="v1", instr="JAL(__divdi3)", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips/op_double_to_float.S b/runtime/interpreter/mterp/mips/op_double_to_float.S
deleted file mode 100644
index c3f2fed..0000000
--- a/runtime/interpreter/mterp/mips/op_double_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_float():
-% unopNarrower(instr="cvt.s.d fv0, fa0")
diff --git a/runtime/interpreter/mterp/mips/op_double_to_int.S b/runtime/interpreter/mterp/mips/op_double_to_int.S
deleted file mode 100644
index a522c9c..0000000
--- a/runtime/interpreter/mterp/mips/op_double_to_int.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_double_to_int():
- /*
- * double-to-int
- *
- * We have to clip values to int min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us
- * for pre-R6.
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
- LOAD64_F(fa0, fa0f, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-#ifndef MIPS32REVGE6
- li t0, INT_MIN_AS_DOUBLE_HIGH
- mtc1 zero, fa1
- MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
- c.ole.d fcc0, fa1, fa0
-#endif
- GET_INST_OPCODE(t1) # extract opcode from rINST
-#ifndef MIPS32REVGE6
- bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
- c.eq.d fcc0, fa0, fa0
- mtc1 zero, fa0
- MOVE_TO_FPU_HIGH(zero, fa0, fa0f)
- movt.d fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
-1:
-#endif
- trunc.w.d fa0, fa0
- SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
diff --git a/runtime/interpreter/mterp/mips/op_double_to_long.S b/runtime/interpreter/mterp/mips/op_double_to_long.S
deleted file mode 100644
index bfc17f5..0000000
--- a/runtime/interpreter/mterp/mips/op_double_to_long.S
+++ /dev/null
@@ -1,51 +0,0 @@
-%def op_double_to_long():
- /*
- * double-to-long
- *
- * We have to clip values to long min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us
- * for pre-R6.
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
- LOAD64_F(fa0, fa0f, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
-#ifdef MIPS32REVGE6
- GET_INST_OPCODE(t1) # extract opcode from rINST
- trunc.l.d fa0, fa0
- SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
-#else
- c.eq.d fcc0, fa0, fa0
- li rRESULT0, 0
- li rRESULT1, 0
- bc1f fcc0, .L${opcode}_get_opcode
-
- li t0, LONG_MIN_AS_DOUBLE_HIGH
- mtc1 zero, fa1
- MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
- c.ole.d fcc0, fa0, fa1
- li rRESULT1, LONG_MIN_HIGH
- bc1t fcc0, .L${opcode}_get_opcode
-
- neg.d fa1, fa1
- c.ole.d fcc0, fa1, fa0
- nor rRESULT0, rRESULT0, zero
- nor rRESULT1, rRESULT1, zero
- bc1t fcc0, .L${opcode}_get_opcode
-
- JAL(__fixdfdi)
- GET_INST_OPCODE(t1) # extract opcode from rINST
- b .L${opcode}_set_vreg
-#endif
-%def op_double_to_long_sister_code():
-
-#ifndef MIPS32REVGE6
-.L${opcode}_get_opcode:
- GET_INST_OPCODE(t1) # extract opcode from rINST
-.L${opcode}_set_vreg:
- SET_VREG64_GOTO(rRESULT0, rRESULT1, rOBJ, t1) # vA/vA+1 <- v0/v1
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_fill_array_data.S b/runtime/interpreter/mterp/mips/op_fill_array_data.S
deleted file mode 100644
index 558f68e..0000000
--- a/runtime/interpreter/mterp/mips/op_fill_array_data.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- EXPORT_PC()
- FETCH(a1, 1) # a1 <- bbbb (lo)
- FETCH(a0, 2) # a0 <- BBBB (hi)
- GET_OPA(a3) # a3 <- AA
- INSERT_HIGH_HALF(a1, a0) # a1 <- BBBBbbbb
- GET_VREG(a0, a3) # a0 <- vAA (array object)
- EAS1(a1, rPC, a1) # a1 <- PC + BBBBbbbb*2 (array data off.)
- JAL(MterpFillArrayData) # v0 <- Mterp(obj, payload)
- beqz v0, MterpPossibleException # has exception
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_filled_new_array.S b/runtime/interpreter/mterp/mips/op_filled_new_array.S
deleted file mode 100644
index 6ac6314..0000000
--- a/runtime/interpreter/mterp/mips/op_filled_new_array.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
- /*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
- .extern $helper
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME # a0 <- shadow frame
- move a1, rPC
- move a2, rSELF
- JAL($helper) # v0 <- helper(shadow_frame, pc, self)
- beqz v0, MterpPossibleException # has exception
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_filled_new_array_range.S b/runtime/interpreter/mterp/mips/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/mips/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/mips/op_float_to_double.S b/runtime/interpreter/mterp/mips/op_float_to_double.S
deleted file mode 100644
index c0235a8..0000000
--- a/runtime/interpreter/mterp/mips/op_float_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_double():
-% funopWider(instr="cvt.d.s fv0, fa0")
diff --git a/runtime/interpreter/mterp/mips/op_float_to_int.S b/runtime/interpreter/mterp/mips/op_float_to_int.S
deleted file mode 100644
index 2c0c418..0000000
--- a/runtime/interpreter/mterp/mips/op_float_to_int.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_float_to_int():
- /*
- * float-to-int
- *
- * We have to clip values to int min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us
- * for pre-R6.
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_VREG_F(fa0, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
-#ifndef MIPS32REVGE6
- li t0, INT_MIN_AS_FLOAT
- mtc1 t0, fa1
- c.ole.s fcc0, fa1, fa0
-#endif
- GET_INST_OPCODE(t1) # extract opcode from rINST
-#ifndef MIPS32REVGE6
- bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
- c.eq.s fcc0, fa0, fa0
- mtc1 zero, fa0
- movt.s fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
-1:
-#endif
- trunc.w.s fa0, fa0
- SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
diff --git a/runtime/interpreter/mterp/mips/op_float_to_long.S b/runtime/interpreter/mterp/mips/op_float_to_long.S
deleted file mode 100644
index 2134e63..0000000
--- a/runtime/interpreter/mterp/mips/op_float_to_long.S
+++ /dev/null
@@ -1,49 +0,0 @@
-%def op_float_to_long():
- /*
- * float-to-long
- *
- * We have to clip values to long min/max per the specification. The
- * expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us
- * for pre-R6.
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG_F(fa0, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
-#ifdef MIPS32REVGE6
- GET_INST_OPCODE(t1) # extract opcode from rINST
- trunc.l.s fa0, fa0
- SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
-#else
- c.eq.s fcc0, fa0, fa0
- li rRESULT0, 0
- li rRESULT1, 0
- bc1f fcc0, .L${opcode}_get_opcode
-
- li t0, LONG_MIN_AS_FLOAT
- mtc1 t0, fa1
- c.ole.s fcc0, fa0, fa1
- li rRESULT1, LONG_MIN_HIGH
- bc1t fcc0, .L${opcode}_get_opcode
-
- neg.s fa1, fa1
- c.ole.s fcc0, fa1, fa0
- nor rRESULT0, rRESULT0, zero
- nor rRESULT1, rRESULT1, zero
- bc1t fcc0, .L${opcode}_get_opcode
-
- JAL(__fixsfdi)
- GET_INST_OPCODE(t1) # extract opcode from rINST
- b .L${opcode}_set_vreg
-#endif
-%def op_float_to_long_sister_code():
-
-#ifndef MIPS32REVGE6
-.L${opcode}_get_opcode:
- GET_INST_OPCODE(t1) # extract opcode from rINST
-.L${opcode}_set_vreg:
- SET_VREG64_GOTO(rRESULT0, rRESULT1, rOBJ, t1) # vA/vA+1 <- v0/v1
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_goto.S b/runtime/interpreter/mterp/mips/op_goto.S
deleted file mode 100644
index 8da1339..0000000
--- a/runtime/interpreter/mterp/mips/op_goto.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto():
- /*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- sll a0, rINST, 16 # a0 <- AAxx0000
- sra rINST, a0, 24 # rINST <- ssssssAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips/op_goto_16.S b/runtime/interpreter/mterp/mips/op_goto_16.S
deleted file mode 100644
index 55a055b..0000000
--- a/runtime/interpreter/mterp/mips/op_goto_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto_16():
- /*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- FETCH_S(rINST, 1) # rINST <- ssssAAAA (sign-extended)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips/op_goto_32.S b/runtime/interpreter/mterp/mips/op_goto_32.S
deleted file mode 100644
index e969bd2..0000000
--- a/runtime/interpreter/mterp/mips/op_goto_32.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_goto_32():
- /*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Unlike most opcodes, this one is allowed to branch to itself, so
- * our "backward branch" test must be "<=0" instead of "<0".
- */
- /* goto/32 +AAAAAAAA */
- FETCH(rINST, 1) # rINST <- aaaa (lo)
- FETCH(a1, 2) # a1 <- AAAA (hi)
- INSERT_HIGH_HALF(rINST, a1) # rINST <- AAAAaaaa
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips/op_if_eq.S b/runtime/interpreter/mterp/mips/op_if_eq.S
deleted file mode 100644
index da58674..0000000
--- a/runtime/interpreter/mterp/mips/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(condition="eq")
diff --git a/runtime/interpreter/mterp/mips/op_if_eqz.S b/runtime/interpreter/mterp/mips/op_if_eqz.S
deleted file mode 100644
index 0639664..0000000
--- a/runtime/interpreter/mterp/mips/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(condition="eq")
diff --git a/runtime/interpreter/mterp/mips/op_if_ge.S b/runtime/interpreter/mterp/mips/op_if_ge.S
deleted file mode 100644
index 5b6ed2f..0000000
--- a/runtime/interpreter/mterp/mips/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(condition="ge")
diff --git a/runtime/interpreter/mterp/mips/op_if_gez.S b/runtime/interpreter/mterp/mips/op_if_gez.S
deleted file mode 100644
index ea6cda7..0000000
--- a/runtime/interpreter/mterp/mips/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(condition="ge")
diff --git a/runtime/interpreter/mterp/mips/op_if_gt.S b/runtime/interpreter/mterp/mips/op_if_gt.S
deleted file mode 100644
index 201decf..0000000
--- a/runtime/interpreter/mterp/mips/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(condition="gt")
diff --git a/runtime/interpreter/mterp/mips/op_if_gtz.S b/runtime/interpreter/mterp/mips/op_if_gtz.S
deleted file mode 100644
index 1fdbb6e..0000000
--- a/runtime/interpreter/mterp/mips/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(condition="gt")
diff --git a/runtime/interpreter/mterp/mips/op_if_le.S b/runtime/interpreter/mterp/mips/op_if_le.S
deleted file mode 100644
index e6024f2..0000000
--- a/runtime/interpreter/mterp/mips/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(condition="le")
diff --git a/runtime/interpreter/mterp/mips/op_if_lez.S b/runtime/interpreter/mterp/mips/op_if_lez.S
deleted file mode 100644
index 62c0d2c..0000000
--- a/runtime/interpreter/mterp/mips/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(condition="le")
diff --git a/runtime/interpreter/mterp/mips/op_if_lt.S b/runtime/interpreter/mterp/mips/op_if_lt.S
deleted file mode 100644
index 4ef22fd..0000000
--- a/runtime/interpreter/mterp/mips/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(condition="lt")
diff --git a/runtime/interpreter/mterp/mips/op_if_ltz.S b/runtime/interpreter/mterp/mips/op_if_ltz.S
deleted file mode 100644
index 84b2d0b..0000000
--- a/runtime/interpreter/mterp/mips/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(condition="lt")
diff --git a/runtime/interpreter/mterp/mips/op_if_ne.S b/runtime/interpreter/mterp/mips/op_if_ne.S
deleted file mode 100644
index ec3a688..0000000
--- a/runtime/interpreter/mterp/mips/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(condition="ne")
diff --git a/runtime/interpreter/mterp/mips/op_if_nez.S b/runtime/interpreter/mterp/mips/op_if_nez.S
deleted file mode 100644
index 7009c3a..0000000
--- a/runtime/interpreter/mterp/mips/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(condition="ne")
diff --git a/runtime/interpreter/mterp/mips/op_iget.S b/runtime/interpreter/mterp/mips/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/mips/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips/op_iget_boolean.S b/runtime/interpreter/mterp/mips/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/mips/op_iget_boolean_quick.S b/runtime/interpreter/mterp/mips/op_iget_boolean_quick.S
deleted file mode 100644
index f3d2cb1..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="lbu")
diff --git a/runtime/interpreter/mterp/mips/op_iget_byte.S b/runtime/interpreter/mterp/mips/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/mips/op_iget_byte_quick.S b/runtime/interpreter/mterp/mips/op_iget_byte_quick.S
deleted file mode 100644
index ddb469b..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="lb")
diff --git a/runtime/interpreter/mterp/mips/op_iget_char.S b/runtime/interpreter/mterp/mips/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/mips/op_iget_char_quick.S b/runtime/interpreter/mterp/mips/op_iget_char_quick.S
deleted file mode 100644
index ef0b350..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="lhu")
diff --git a/runtime/interpreter/mterp/mips/op_iget_object.S b/runtime/interpreter/mterp/mips/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/mips/op_iget_object_quick.S b/runtime/interpreter/mterp/mips/op_iget_object_quick.S
deleted file mode 100644
index 8bfd40b..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_object_quick.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset@CCCC */
- GET_OPB(a2) # a2 <- B
- FETCH(a1, 1) # a1 <- field byte offset
- EXPORT_PC()
- GET_VREG(a0, a2) # a0 <- object we're operating on
- JAL(artIGetObjectFromMterp) # v0 <- GetObj(obj, offset)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
diff --git a/runtime/interpreter/mterp/mips/op_iget_quick.S b/runtime/interpreter/mterp/mips/op_iget_quick.S
deleted file mode 100644
index b8892fd..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iget_quick(load="lw"):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
- /* op vA, vB, offset@CCCC */
- GET_OPB(a2) # a2 <- B
- GET_VREG(a3, a2) # a3 <- object we're operating on
- FETCH(a1, 1) # a1 <- field byte offset
- GET_OPA4(a2) # a2 <- A(+)
- # check object for null
- beqz a3, common_errNullObject # object was null
- addu t0, a3, a1
- $load a0, 0(t0) # a0 <- obj.field (8/16/32 bits)
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a0, a2, t0) # fp[A] <- a0
diff --git a/runtime/interpreter/mterp/mips/op_iget_short.S b/runtime/interpreter/mterp/mips/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/mips/op_iget_short_quick.S b/runtime/interpreter/mterp/mips/op_iget_short_quick.S
deleted file mode 100644
index 5957cb4..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="lh")
diff --git a/runtime/interpreter/mterp/mips/op_iget_wide.S b/runtime/interpreter/mterp/mips/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/mips/op_iget_wide_quick.S b/runtime/interpreter/mterp/mips/op_iget_wide_quick.S
deleted file mode 100644
index 5bc9076..0000000
--- a/runtime/interpreter/mterp/mips/op_iget_wide_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iget_wide_quick():
- /* iget-wide-quick vA, vB, offset@CCCC */
- GET_OPB(a2) # a2 <- B
- GET_VREG(a3, a2) # a3 <- object we're operating on
- FETCH(a1, 1) # a1 <- field byte offset
- GET_OPA4(a2) # a2 <- A(+)
- # check object for null
- beqz a3, common_errNullObject # object was null
- addu t0, a3, a1 # t0 <- a3 + a1
- LOAD64(a0, a1, t0) # a0 <- obj.field (64 bits, aligned)
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a2, t0) # fp[A] <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_instance_of.S b/runtime/interpreter/mterp/mips/op_instance_of.S
deleted file mode 100644
index 9312e72..0000000
--- a/runtime/interpreter/mterp/mips/op_instance_of.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_instance_of():
- /*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- CCCC
- GET_OPB(a1) # a1 <- B
- EAS2(a1, rFP, a1) # a1 <- &object
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- GET_OPA4(rOBJ) # rOBJ <- A+
- JAL(MterpInstanceOf) # v0 <- Mterp(index, &obj, method, self)
- lw a1, THREAD_EXCEPTION_OFFSET(rSELF)
- PREFETCH_INST(2) # load rINST
- bnez a1, MterpException
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(v0, rOBJ, t0) # vA <- v0
diff --git a/runtime/interpreter/mterp/mips/op_int_to_byte.S b/runtime/interpreter/mterp/mips/op_int_to_byte.S
deleted file mode 100644
index 5841725..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="SEB(a0, a0)")
diff --git a/runtime/interpreter/mterp/mips/op_int_to_char.S b/runtime/interpreter/mterp/mips/op_int_to_char.S
deleted file mode 100644
index 7fda637..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(preinstr="", instr="and a0, 0xffff")
diff --git a/runtime/interpreter/mterp/mips/op_int_to_double.S b/runtime/interpreter/mterp/mips/op_int_to_double.S
deleted file mode 100644
index 736ebb3..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_double():
-% funopWider(instr="cvt.d.w fv0, fa0")
diff --git a/runtime/interpreter/mterp/mips/op_int_to_float.S b/runtime/interpreter/mterp/mips/op_int_to_float.S
deleted file mode 100644
index 45ab4c8..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_float():
-% funop(instr="cvt.s.w fv0, fa0")
diff --git a/runtime/interpreter/mterp/mips/op_int_to_long.S b/runtime/interpreter/mterp/mips/op_int_to_long.S
deleted file mode 100644
index 093f181..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_long():
-% unopWider(instr="sra a1, a0, 31")
diff --git a/runtime/interpreter/mterp/mips/op_int_to_short.S b/runtime/interpreter/mterp/mips/op_int_to_short.S
deleted file mode 100644
index 38bc451..0000000
--- a/runtime/interpreter/mterp/mips/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="SEH(a0, a0)")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_custom.S b/runtime/interpreter/mterp/mips/op_invoke_custom.S
deleted file mode 100644
index 4bba9ee..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_custom.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_custom_range.S b/runtime/interpreter/mterp/mips/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_direct.S b/runtime/interpreter/mterp/mips/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_direct_range.S b/runtime/interpreter/mterp/mips/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_interface.S b/runtime/interpreter/mterp/mips/op_invoke_interface.S
deleted file mode 100644
index 2e749aa..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_interface.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_interface_range.S b/runtime/interpreter/mterp/mips/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_polymorphic.S b/runtime/interpreter/mterp/mips/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/mips/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_static.S b/runtime/interpreter/mterp/mips/op_invoke_static.S
deleted file mode 100644
index 8b104a6..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_static.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_static_range.S b/runtime/interpreter/mterp/mips/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_super.S b/runtime/interpreter/mterp/mips/op_invoke_super.S
deleted file mode 100644
index e5921f3..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_super.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_super_range.S b/runtime/interpreter/mterp/mips/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_virtual.S b/runtime/interpreter/mterp/mips/op_invoke_virtual.S
deleted file mode 100644
index 8767741..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_virtual.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/mips/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_virtual_range.S b/runtime/interpreter/mterp/mips/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/mips/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/mips/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/mips/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/mips/op_iput.S b/runtime/interpreter/mterp/mips/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/mips/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips/op_iput_boolean.S b/runtime/interpreter/mterp/mips/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/mips/op_iput_boolean_quick.S b/runtime/interpreter/mterp/mips/op_iput_boolean_quick.S
deleted file mode 100644
index 3d818a5..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(store="sb")
diff --git a/runtime/interpreter/mterp/mips/op_iput_byte.S b/runtime/interpreter/mterp/mips/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/mips/op_iput_byte_quick.S b/runtime/interpreter/mterp/mips/op_iput_byte_quick.S
deleted file mode 100644
index 06dc24e..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(store="sb")
diff --git a/runtime/interpreter/mterp/mips/op_iput_char.S b/runtime/interpreter/mterp/mips/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/mips/op_iput_char_quick.S b/runtime/interpreter/mterp/mips/op_iput_char_quick.S
deleted file mode 100644
index 3b6af5b..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(store="sh")
diff --git a/runtime/interpreter/mterp/mips/op_iput_object.S b/runtime/interpreter/mterp/mips/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/mips/op_iput_object_quick.S b/runtime/interpreter/mterp/mips/op_iput_object_quick.S
deleted file mode 100644
index bb3cbe8..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_object_quick.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_iput_object_quick():
- /* For: iput-object-quick */
- /* op vA, vB, offset@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- JAL(MterpIputObjectQuick)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_iput_quick.S b/runtime/interpreter/mterp/mips/op_iput_quick.S
deleted file mode 100644
index 55067be..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_quick.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_iput_quick(store="sw"):
- /* For: iput-quick, iput-object-quick */
- /* op vA, vB, offset@CCCC */
- GET_OPB(a2) # a2 <- B
- GET_VREG(a3, a2) # a3 <- fp[B], the object pointer
- FETCH(a1, 1) # a1 <- field byte offset
- GET_OPA4(a2) # a2 <- A(+)
- beqz a3, common_errNullObject # object was null
- GET_VREG(a0, a2) # a0 <- fp[A]
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- addu t0, a3, a1
- GET_INST_OPCODE(t1) # extract opcode from rINST
- GET_OPCODE_TARGET(t1)
- $store a0, 0(t0) # obj.field (8/16/32 bits) <- a0
- JR(t1) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_iput_short.S b/runtime/interpreter/mterp/mips/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/mips/op_iput_short_quick.S b/runtime/interpreter/mterp/mips/op_iput_short_quick.S
deleted file mode 100644
index fade093..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(store="sh")
diff --git a/runtime/interpreter/mterp/mips/op_iput_wide.S b/runtime/interpreter/mterp/mips/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/mips/op_iput_wide_quick.S b/runtime/interpreter/mterp/mips/op_iput_wide_quick.S
deleted file mode 100644
index 7b8e632..0000000
--- a/runtime/interpreter/mterp/mips/op_iput_wide_quick.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset@CCCC */
- GET_OPA4(a0) # a0 <- A(+)
- GET_OPB(a1) # a1 <- B
- GET_VREG(a2, a1) # a2 <- fp[B], the object pointer
- # check object for null
- beqz a2, common_errNullObject # object was null
- EAS2(a3, rFP, a0) # a3 <- &fp[A]
- LOAD64(a0, a1, a3) # a0/a1 <- fp[A]
- FETCH(a3, 1) # a3 <- field byte offset
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- addu a2, a2, a3 # obj.field (64 bits, aligned) <- a0/a1
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GET_OPCODE_TARGET(t0)
- STORE64(a0, a1, a2) # obj.field (64 bits, aligned) <- a0/a1
- JR(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_long_to_double.S b/runtime/interpreter/mterp/mips/op_long_to_double.S
deleted file mode 100644
index 5dfc76b..0000000
--- a/runtime/interpreter/mterp/mips/op_long_to_double.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_long_to_double():
- /*
- * long-to-double
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
-
-#ifdef MIPS32REVGE6
- LOAD64_F(fv0, fv0f, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- cvt.d.l fv0, fv0
-#else
- LOAD64(rARG0, rARG1, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- JAL(__floatdidf) # a0/a1 <- op, a2-a3 changed
-#endif
-
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_F_GOTO(fv0, fv0f, rOBJ, t0) # vA/vA+1 <- result
diff --git a/runtime/interpreter/mterp/mips/op_long_to_float.S b/runtime/interpreter/mterp/mips/op_long_to_float.S
deleted file mode 100644
index fcf2a2e..0000000
--- a/runtime/interpreter/mterp/mips/op_long_to_float.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_long_to_float():
- /*
- * long-to-float
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
-
-#ifdef MIPS32REVGE6
- LOAD64_F(fv0, fv0f, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- cvt.s.l fv0, fv0
-#else
- LOAD64(rARG0, rARG1, a3)
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- JAL(__floatdisf)
-#endif
-
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- fv0
diff --git a/runtime/interpreter/mterp/mips/op_long_to_int.S b/runtime/interpreter/mterp/mips/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/mips/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/mips/op_monitor_enter.S b/runtime/interpreter/mterp/mips/op_monitor_enter.S
deleted file mode 100644
index 66e3af5..0000000
--- a/runtime/interpreter/mterp/mips/op_monitor_enter.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_monitor_enter():
- /*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- EXPORT_PC()
- GET_OPA(a2) # a2 <- AA
- GET_VREG(a0, a2) # a0 <- vAA (object)
- move a1, rSELF # a1 <- self
- JAL(artLockObjectFromCode) # v0 <- artLockObject(obj, self)
- bnez v0, MterpException
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_monitor_exit.S b/runtime/interpreter/mterp/mips/op_monitor_exit.S
deleted file mode 100644
index d32d75c..0000000
--- a/runtime/interpreter/mterp/mips/op_monitor_exit.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_monitor_exit():
- /*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- EXPORT_PC()
- GET_OPA(a2) # a2 <- AA
- GET_VREG(a0, a2) # a0 <- vAA (object)
- move a1, rSELF # a1 <- self
- JAL(artUnlockObjectFromCode) # v0 <- artUnlockObject(obj, self)
- bnez v0, MterpException
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_move.S b/runtime/interpreter/mterp/mips/op_move.S
deleted file mode 100644
index a0c1c31..0000000
--- a/runtime/interpreter/mterp/mips/op_move.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- GET_OPB(a1) # a1 <- B from 15:12
- GET_OPA4(a0) # a0 <- A from 11:8
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_VREG(a2, a1) # a2 <- fp[B]
- GET_INST_OPCODE(t0) # t0 <- opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[A] <- a2
- .else
- SET_VREG_GOTO(a2, a0, t0) # fp[A] <- a2
- .endif
diff --git a/runtime/interpreter/mterp/mips/op_move_16.S b/runtime/interpreter/mterp/mips/op_move_16.S
deleted file mode 100644
index 273858e..0000000
--- a/runtime/interpreter/mterp/mips/op_move_16.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- FETCH(a1, 2) # a1 <- BBBB
- FETCH(a0, 1) # a0 <- AAAA
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- GET_VREG(a2, a1) # a2 <- fp[BBBB]
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[AAAA] <- a2
- .else
- SET_VREG_GOTO(a2, a0, t0) # fp[AAAA] <- a2
- .endif
diff --git a/runtime/interpreter/mterp/mips/op_move_exception.S b/runtime/interpreter/mterp/mips/op_move_exception.S
deleted file mode 100644
index 80c554b..0000000
--- a/runtime/interpreter/mterp/mips/op_move_exception.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- GET_OPA(a2) # a2 <- AA
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF) # get exception obj
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GET_OPCODE_TARGET(t0)
- SET_VREG_OBJECT(a3, a2) # fp[AA] <- exception obj
- sw zero, THREAD_EXCEPTION_OFFSET(rSELF) # clear exception
- JR(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_move_from16.S b/runtime/interpreter/mterp/mips/op_move_from16.S
deleted file mode 100644
index 7306ed8..0000000
--- a/runtime/interpreter/mterp/mips/op_move_from16.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- FETCH(a1, 1) # a1 <- BBBB
- GET_OPA(a0) # a0 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_VREG(a2, a1) # a2 <- fp[BBBB]
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[AA] <- a2
- .else
- SET_VREG_GOTO(a2, a0, t0) # fp[AA] <- a2
- .endif
diff --git a/runtime/interpreter/mterp/mips/op_move_object.S b/runtime/interpreter/mterp/mips/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/mips/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/mips/op_move_object_16.S b/runtime/interpreter/mterp/mips/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/mips/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/mips/op_move_object_from16.S b/runtime/interpreter/mterp/mips/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/mips/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/mips/op_move_result.S b/runtime/interpreter/mterp/mips/op_move_result.S
deleted file mode 100644
index 20651d9..0000000
--- a/runtime/interpreter/mterp/mips/op_move_result.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- GET_OPA(a2) # a2 <- AA
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- lw a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
- lw a0, 0(a0) # a0 <- result.i
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(a0, a2, t0) # fp[AA] <- a0
- .else
- SET_VREG_GOTO(a0, a2, t0) # fp[AA] <- a0
- .endif
diff --git a/runtime/interpreter/mterp/mips/op_move_result_object.S b/runtime/interpreter/mterp/mips/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/mips/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/mips/op_move_result_wide.S b/runtime/interpreter/mterp/mips/op_move_result_wide.S
deleted file mode 100644
index 205f174..0000000
--- a/runtime/interpreter/mterp/mips/op_move_result_wide.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_move_result_wide():
- /* move-result-wide vAA */
- GET_OPA(a2) # a2 <- AA
- lw a3, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
- LOAD64(a0, a1, a3) # a0/a1 <- retval.j
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AA] <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_move_wide.S b/runtime/interpreter/mterp/mips/op_move_wide.S
deleted file mode 100644
index ad71022..0000000
--- a/runtime/interpreter/mterp/mips/op_move_wide.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
- GET_OPA4(a2) # a2 <- A(+)
- GET_OPB(a3) # a3 <- B
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
- LOAD64(a0, a1, a3) # a0/a1 <- fp[B]
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a2, t0) # fp[A] <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_move_wide_16.S b/runtime/interpreter/mterp/mips/op_move_wide_16.S
deleted file mode 100644
index 60d41a5..0000000
--- a/runtime/interpreter/mterp/mips/op_move_wide_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
- FETCH(a3, 2) # a3 <- BBBB
- FETCH(a2, 1) # a2 <- AAAA
- EAS2(a3, rFP, a3) # a3 <- &fp[BBBB]
- LOAD64(a0, a1, a3) # a0/a1 <- fp[BBBB]
- FETCH_ADVANCE_INST(3) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AAAA] <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_move_wide_from16.S b/runtime/interpreter/mterp/mips/op_move_wide_from16.S
deleted file mode 100644
index 0a970ef..0000000
--- a/runtime/interpreter/mterp/mips/op_move_wide_from16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
- FETCH(a3, 1) # a3 <- BBBB
- GET_OPA(a2) # a2 <- AA
- EAS2(a3, rFP, a3) # a3 <- &fp[BBBB]
- LOAD64(a0, a1, a3) # a0/a1 <- fp[BBBB]
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AA] <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/op_mul_double.S b/runtime/interpreter/mterp/mips/op_mul_double.S
deleted file mode 100644
index 609a462..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% fbinopWide(instr="mul.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_double_2addr.S b/runtime/interpreter/mterp/mips/op_mul_double_2addr.S
deleted file mode 100644
index ae0b13f..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% fbinopWide2addr(instr="mul.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_float.S b/runtime/interpreter/mterp/mips/op_mul_float.S
deleted file mode 100644
index e4a578e..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% fbinop(instr="mul.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_float_2addr.S b/runtime/interpreter/mterp/mips/op_mul_float_2addr.S
deleted file mode 100644
index 38b2a88..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% fbinop2addr(instr="mul.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_int.S b/runtime/interpreter/mterp/mips/op_mul_int.S
deleted file mode 100644
index 34e42f0..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int():
-% binop(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_int_2addr.S b/runtime/interpreter/mterp/mips/op_mul_int_2addr.S
deleted file mode 100644
index 0224a6e..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_2addr():
-% binop2addr(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_int_lit16.S b/runtime/interpreter/mterp/mips/op_mul_int_lit16.S
deleted file mode 100644
index 935d632..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit16():
-% binopLit16(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_int_lit8.S b/runtime/interpreter/mterp/mips/op_mul_int_lit8.S
deleted file mode 100644
index 4a2bfca..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit8():
-% binopLit8(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_mul_long.S b/runtime/interpreter/mterp/mips/op_mul_long.S
deleted file mode 100644
index ae31e19..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_long.S
+++ /dev/null
@@ -1,43 +0,0 @@
-%def op_mul_long():
- /*
- * Signed 64-bit integer multiply.
- * a1 a0
- * x a3 a2
- * -------------
- * a2a1 a2a0
- * a3a0
- * a3a1 (<= unused)
- * ---------------
- * v1 v0
- */
- /* mul-long vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- and t0, a0, 255 # a2 <- BB
- srl t1, a0, 8 # a3 <- CC
- EAS2(t0, rFP, t0) # t0 <- &fp[BB]
- LOAD64(a0, a1, t0) # a0/a1 <- vBB/vBB+1
-
- EAS2(t1, rFP, t1) # t0 <- &fp[CC]
- LOAD64(a2, a3, t1) # a2/a3 <- vCC/vCC+1
-
- mul v1, a3, a0 # v1= a3a0
-#ifdef MIPS32REVGE6
- mulu v0, a2, a0 # v0= a2a0
- muhu t1, a2, a0
-#else
- multu a2, a0
- mfhi t1
- mflo v0 # v0= a2a0
-#endif
- mul t0, a2, a1 # t0= a2a1
- addu v1, v1, t1 # v1+= hi(a2a0)
- addu v1, v1, t0 # v1= a3a0 + a2a1;
-
- GET_OPA(a0) # a0 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- b .L${opcode}_finish
-%def op_mul_long_sister_code():
-
-.L${opcode}_finish:
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a0, t0) # vAA/vAA+1 <- v0(low)/v1(high)
diff --git a/runtime/interpreter/mterp/mips/op_mul_long_2addr.S b/runtime/interpreter/mterp/mips/op_mul_long_2addr.S
deleted file mode 100644
index ef53254..0000000
--- a/runtime/interpreter/mterp/mips/op_mul_long_2addr.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_mul_long_2addr():
- /*
- * See op_mul_long.S for more details
- */
- /* mul-long/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
-
- EAS2(t0, rFP, rOBJ) # t0 <- &fp[A]
- LOAD64(a0, a1, t0) # vAA.low / high
-
- GET_OPB(t1) # t1 <- B
- EAS2(t1, rFP, t1) # t1 <- &fp[B]
- LOAD64(a2, a3, t1) # vBB.low / high
-
- mul v1, a3, a0 # v1= a3a0
-#ifdef MIPS32REVGE6
- mulu v0, a2, a0 # v0= a2a0
- muhu t1, a2, a0
-#else
- multu a2, a0
- mfhi t1
- mflo v0 # v0= a2a0
- #endif
- mul t2, a2, a1 # t2= a2a1
- addu v1, v1, t1 # v1= a3a0 + hi(a2a0)
- addu v1, v1, t2 # v1= v1 + a2a1;
-
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t1) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, rOBJ, t1) # vA/vA+1 <- v0(low)/v1(high)
diff --git a/runtime/interpreter/mterp/mips/op_neg_double.S b/runtime/interpreter/mterp/mips/op_neg_double.S
deleted file mode 100644
index b53ccbb..0000000
--- a/runtime/interpreter/mterp/mips/op_neg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_double():
-% unopWide(instr="addu a1, a1, 0x80000000")
diff --git a/runtime/interpreter/mterp/mips/op_neg_float.S b/runtime/interpreter/mterp/mips/op_neg_float.S
deleted file mode 100644
index 655d827..0000000
--- a/runtime/interpreter/mterp/mips/op_neg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_float():
-% unop(instr="addu a0, a0, 0x80000000")
diff --git a/runtime/interpreter/mterp/mips/op_neg_int.S b/runtime/interpreter/mterp/mips/op_neg_int.S
deleted file mode 100644
index acc3440..0000000
--- a/runtime/interpreter/mterp/mips/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr="negu a0, a0")
diff --git a/runtime/interpreter/mterp/mips/op_neg_long.S b/runtime/interpreter/mterp/mips/op_neg_long.S
deleted file mode 100644
index 9108b2b..0000000
--- a/runtime/interpreter/mterp/mips/op_neg_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_long():
-% unopWide(result0="v0", result1="v1", preinstr="negu v0, a0", instr="negu v1, a1; sltu a0, zero, v0; subu v1, v1, a0")
diff --git a/runtime/interpreter/mterp/mips/op_new_array.S b/runtime/interpreter/mterp/mips/op_new_array.S
deleted file mode 100644
index 6ae04cc..0000000
--- a/runtime/interpreter/mterp/mips/op_new_array.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_new_array():
- /*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpNewArray)
- beqz v0, MterpPossibleException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_new_instance.S b/runtime/interpreter/mterp/mips/op_new_instance.S
deleted file mode 100644
index 0c98c93..0000000
--- a/runtime/interpreter/mterp/mips/op_new_instance.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_new_instance():
- /*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class@BBBB */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rSELF
- move a2, rINST
- JAL(MterpNewInstance)
- beqz v0, MterpPossibleException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_nop.S b/runtime/interpreter/mterp/mips/op_nop.S
deleted file mode 100644
index 10f6074..0000000
--- a/runtime/interpreter/mterp/mips/op_nop.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_nop():
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips/op_not_int.S b/runtime/interpreter/mterp/mips/op_not_int.S
deleted file mode 100644
index 7dc7aeb..0000000
--- a/runtime/interpreter/mterp/mips/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr="not a0, a0")
diff --git a/runtime/interpreter/mterp/mips/op_not_long.S b/runtime/interpreter/mterp/mips/op_not_long.S
deleted file mode 100644
index 0bca4bd..0000000
--- a/runtime/interpreter/mterp/mips/op_not_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_long():
-% unopWide(preinstr="not a0, a0", instr="not a1, a1")
diff --git a/runtime/interpreter/mterp/mips/op_or_int.S b/runtime/interpreter/mterp/mips/op_or_int.S
deleted file mode 100644
index df60be5..0000000
--- a/runtime/interpreter/mterp/mips/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_or_int_2addr.S b/runtime/interpreter/mterp/mips/op_or_int_2addr.S
deleted file mode 100644
index c202e67..0000000
--- a/runtime/interpreter/mterp/mips/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_or_int_lit16.S b/runtime/interpreter/mterp/mips/op_or_int_lit16.S
deleted file mode 100644
index 09961e8..0000000
--- a/runtime/interpreter/mterp/mips/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_or_int_lit8.S b/runtime/interpreter/mterp/mips/op_or_int_lit8.S
deleted file mode 100644
index 1bd6809..0000000
--- a/runtime/interpreter/mterp/mips/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_or_long.S b/runtime/interpreter/mterp/mips/op_or_long.S
deleted file mode 100644
index 5f53085..0000000
--- a/runtime/interpreter/mterp/mips/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(preinstr="or a0, a0, a2", instr="or a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/op_or_long_2addr.S b/runtime/interpreter/mterp/mips/op_or_long_2addr.S
deleted file mode 100644
index f9b2f9c..0000000
--- a/runtime/interpreter/mterp/mips/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(preinstr="or a0, a0, a2", instr="or a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/op_packed_switch.S b/runtime/interpreter/mterp/mips/op_packed_switch.S
deleted file mode 100644
index e18a652..0000000
--- a/runtime/interpreter/mterp/mips/op_packed_switch.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
- /*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBB */
- FETCH(a0, 1) # a0 <- bbbb (lo)
- FETCH(a1, 2) # a1 <- BBBB (hi)
- GET_OPA(a3) # a3 <- AA
- INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb
- GET_VREG(a1, a3) # a1 <- vAA
- EAS1(a0, rPC, a0) # a0 <- PC + BBBBbbbb*2
- JAL($func) # a0 <- code-unit branch offset
- move rINST, v0
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips/op_rem_double.S b/runtime/interpreter/mterp/mips/op_rem_double.S
deleted file mode 100644
index 99857a3..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_double():
-% fbinopWide(instr="JAL(fmod)")
diff --git a/runtime/interpreter/mterp/mips/op_rem_double_2addr.S b/runtime/interpreter/mterp/mips/op_rem_double_2addr.S
deleted file mode 100644
index cf2d3a7..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_double_2addr():
-% fbinopWide2addr(instr="JAL(fmod)")
diff --git a/runtime/interpreter/mterp/mips/op_rem_float.S b/runtime/interpreter/mterp/mips/op_rem_float.S
deleted file mode 100644
index 2295ae5..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_float():
-% fbinop(instr="JAL(fmodf)")
diff --git a/runtime/interpreter/mterp/mips/op_rem_float_2addr.S b/runtime/interpreter/mterp/mips/op_rem_float_2addr.S
deleted file mode 100644
index 9f6abee..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_float_2addr():
-% fbinop2addr(instr="JAL(fmodf)")
diff --git a/runtime/interpreter/mterp/mips/op_rem_int.S b/runtime/interpreter/mterp/mips/op_rem_int.S
deleted file mode 100644
index 2f67adc..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_int.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_rem_int():
-#ifdef MIPS32REVGE6
-% binop(instr="mod a0, a0, a1", chkzero="1")
-#else
-% binop(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_rem_int_2addr.S b/runtime/interpreter/mterp/mips/op_rem_int_2addr.S
deleted file mode 100644
index 78766a7..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_int_2addr.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_rem_int_2addr():
-#ifdef MIPS32REVGE6
-% binop2addr(instr="mod a0, a0, a1", chkzero="1")
-#else
-% binop2addr(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_rem_int_lit16.S b/runtime/interpreter/mterp/mips/op_rem_int_lit16.S
deleted file mode 100644
index ce136cb..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_int_lit16.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_rem_int_lit16():
-#ifdef MIPS32REVGE6
-% binopLit16(instr="mod a0, a0, a1", chkzero="1")
-#else
-% binopLit16(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_rem_int_lit8.S b/runtime/interpreter/mterp/mips/op_rem_int_lit8.S
deleted file mode 100644
index 0a50844..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_int_lit8.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_rem_int_lit8():
-#ifdef MIPS32REVGE6
-% binopLit8(instr="mod a0, a0, a1", chkzero="1")
-#else
-% binopLit8(preinstr="div zero, a0, a1", instr="mfhi a0", chkzero="1")
-#endif
diff --git a/runtime/interpreter/mterp/mips/op_rem_long.S b/runtime/interpreter/mterp/mips/op_rem_long.S
deleted file mode 100644
index 2403dec..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long():
-% binopWide(result0="v0", result1="v1", instr="JAL(__moddi3)", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips/op_rem_long_2addr.S b/runtime/interpreter/mterp/mips/op_rem_long_2addr.S
deleted file mode 100644
index 6cf3c09..0000000
--- a/runtime/interpreter/mterp/mips/op_rem_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long_2addr():
-% binopWide2addr(result0="v0", result1="v1", instr="JAL(__moddi3)", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips/op_return.S b/runtime/interpreter/mterp/mips/op_return.S
deleted file mode 100644
index 4e422d2..0000000
--- a/runtime/interpreter/mterp/mips/op_return.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_return():
- /*
- * Return a 32-bit value.
- *
- * for: return, return-object
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- JAL(MterpThreadFenceForConstructor)
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqz ra, 1f
- JAL(MterpSuspendCheck) # (self)
-1:
- GET_OPA(a2) # a2 <- AA
- GET_VREG(v0, a2) # v0 <- vAA
- move v1, zero
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips/op_return_object.S b/runtime/interpreter/mterp/mips/op_return_object.S
deleted file mode 100644
index 2eeec0b..0000000
--- a/runtime/interpreter/mterp/mips/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return()
diff --git a/runtime/interpreter/mterp/mips/op_return_void.S b/runtime/interpreter/mterp/mips/op_return_void.S
deleted file mode 100644
index 14e532b..0000000
--- a/runtime/interpreter/mterp/mips/op_return_void.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- JAL(MterpThreadFenceForConstructor)
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqz ra, 1f
- JAL(MterpSuspendCheck) # (self)
-1:
- move v0, zero
- move v1, zero
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips/op_return_void_no_barrier.S b/runtime/interpreter/mterp/mips/op_return_void_no_barrier.S
deleted file mode 100644
index a74f085..0000000
--- a/runtime/interpreter/mterp/mips/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_return_void_no_barrier():
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqz ra, 1f
- JAL(MterpSuspendCheck) # (self)
-1:
- move v0, zero
- move v1, zero
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips/op_return_wide.S b/runtime/interpreter/mterp/mips/op_return_wide.S
deleted file mode 100644
index fb065a5..0000000
--- a/runtime/interpreter/mterp/mips/op_return_wide.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_return_wide():
- /*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- .extern MterpThreadFenceForConstructor
- JAL(MterpThreadFenceForConstructor)
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqz ra, 1f
- JAL(MterpSuspendCheck) # (self)
-1:
- GET_OPA(a2) # a2 <- AA
- EAS2(a2, rFP, a2) # a2 <- &fp[AA]
- LOAD64(v0, v1, a2) # v0/v1 <- vAA/vAA+1
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips/op_rsub_int.S b/runtime/interpreter/mterp/mips/op_rsub_int.S
deleted file mode 100644
index 21ead06..0000000
--- a/runtime/interpreter/mterp/mips/op_rsub_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rsub_int():
-/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
-% binopLit16(instr="subu a0, a1, a0")
diff --git a/runtime/interpreter/mterp/mips/op_rsub_int_lit8.S b/runtime/interpreter/mterp/mips/op_rsub_int_lit8.S
deleted file mode 100644
index b9b214d..0000000
--- a/runtime/interpreter/mterp/mips/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(instr="subu a0, a1, a0")
diff --git a/runtime/interpreter/mterp/mips/op_sget.S b/runtime/interpreter/mterp/mips/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/mips/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips/op_sget_boolean.S b/runtime/interpreter/mterp/mips/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/mips/op_sget_byte.S b/runtime/interpreter/mterp/mips/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/mips/op_sget_char.S b/runtime/interpreter/mterp/mips/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/mips/op_sget_object.S b/runtime/interpreter/mterp/mips/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/mips/op_sget_short.S b/runtime/interpreter/mterp/mips/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/mips/op_sget_wide.S b/runtime/interpreter/mterp/mips/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/mips/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/mips/op_shl_int.S b/runtime/interpreter/mterp/mips/op_shl_int.S
deleted file mode 100644
index efd213c..0000000
--- a/runtime/interpreter/mterp/mips/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shl_int_2addr.S b/runtime/interpreter/mterp/mips/op_shl_int_2addr.S
deleted file mode 100644
index 0901e6b..0000000
--- a/runtime/interpreter/mterp/mips/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% binop2addr(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shl_int_lit8.S b/runtime/interpreter/mterp/mips/op_shl_int_lit8.S
deleted file mode 100644
index 2263ec7..0000000
--- a/runtime/interpreter/mterp/mips/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shl_long.S b/runtime/interpreter/mterp/mips/op_shl_long.S
deleted file mode 100644
index 8bb4216..0000000
--- a/runtime/interpreter/mterp/mips/op_shl_long.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_shl_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* shl-long vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(t2) # t2 <- AA
- and a3, a0, 255 # a3 <- BB
- srl a0, a0, 8 # a0 <- CC
- EAS2(a3, rFP, a3) # a3 <- &fp[BB]
- GET_VREG(a2, a0) # a2 <- vCC
- LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v1, a2, 0x20 # shift< shift & 0x20
- sll v0, a0, a2 # rlo<- alo << (shift&31)
- bnez v1, .L${opcode}_finish
- not v1, a2 # rhi<- 31-shift (shift is 5b)
- srl a0, 1
- srl a0, v1 # alo<- alo >> (32-(shift&31))
- sll v1, a1, a2 # rhi<- ahi << (shift&31)
- or v1, a0 # rhi<- rhi | alo
- SET_VREG64_GOTO(v0, v1, t2, t0) # vAA/vAA+1 <- v0/v1
-%def op_shl_long_sister_code():
-
-.L${opcode}_finish:
- SET_VREG64_GOTO(zero, v0, t2, t0) # vAA/vAA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_shl_long_2addr.S b/runtime/interpreter/mterp/mips/op_shl_long_2addr.S
deleted file mode 100644
index 12015f5..0000000
--- a/runtime/interpreter/mterp/mips/op_shl_long_2addr.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_shl_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shl-long/2addr vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG(a2, a3) # a2 <- vB
- EAS2(t2, rFP, rOBJ) # t2 <- &fp[A]
- LOAD64(a0, a1, t2) # a0/a1 <- vA/vA+1
-
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v1, a2, 0x20 # shift< shift & 0x20
- sll v0, a0, a2 # rlo<- alo << (shift&31)
- bnez v1, .L${opcode}_finish
- not v1, a2 # rhi<- 31-shift (shift is 5b)
- srl a0, 1
- srl a0, v1 # alo<- alo >> (32-(shift&31))
- sll v1, a1, a2 # rhi<- ahi << (shift&31)
- or v1, a0 # rhi<- rhi | alo
- SET_VREG64_GOTO(v0, v1, rOBJ, t0) # vA/vA+1 <- v0/v1
-%def op_shl_long_2addr_sister_code():
-
-.L${opcode}_finish:
- SET_VREG64_GOTO(zero, v0, rOBJ, t0) # vA/vA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_shr_int.S b/runtime/interpreter/mterp/mips/op_shr_int.S
deleted file mode 100644
index 8d55e7a..0000000
--- a/runtime/interpreter/mterp/mips/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shr_int_2addr.S b/runtime/interpreter/mterp/mips/op_shr_int_2addr.S
deleted file mode 100644
index e102baa..0000000
--- a/runtime/interpreter/mterp/mips/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% binop2addr(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shr_int_lit8.S b/runtime/interpreter/mterp/mips/op_shr_int_lit8.S
deleted file mode 100644
index 437c5c4..0000000
--- a/runtime/interpreter/mterp/mips/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_shr_long.S b/runtime/interpreter/mterp/mips/op_shr_long.S
deleted file mode 100644
index adffa61..0000000
--- a/runtime/interpreter/mterp/mips/op_shr_long.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_shr_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* shr-long vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(t3) # t3 <- AA
- and a3, a0, 255 # a3 <- BB
- srl a0, a0, 8 # a0 <- CC
- EAS2(a3, rFP, a3) # a3 <- &fp[BB]
- GET_VREG(a2, a0) # a2 <- vCC
- LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v0, a2, 0x20 # shift & 0x20
- sra v1, a1, a2 # rhi<- ahi >> (shift&31)
- bnez v0, .L${opcode}_finish
- srl v0, a0, a2 # rlo<- alo >> (shift&31)
- not a0, a2 # alo<- 31-shift (shift is 5b)
- sll a1, 1
- sll a1, a0 # ahi<- ahi << (32-(shift&31))
- or v0, a1 # rlo<- rlo | ahi
- SET_VREG64_GOTO(v0, v1, t3, t0) # vAA/VAA+1 <- v0/v1
-%def op_shr_long_sister_code():
-
-.L${opcode}_finish:
- sra a3, a1, 31 # a3<- sign(ah)
- SET_VREG64_GOTO(v1, a3, t3, t0) # vAA/VAA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_shr_long_2addr.S b/runtime/interpreter/mterp/mips/op_shr_long_2addr.S
deleted file mode 100644
index d8acb79..0000000
--- a/runtime/interpreter/mterp/mips/op_shr_long_2addr.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_shr_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shr-long/2addr vA, vB */
- GET_OPA4(t2) # t2 <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG(a2, a3) # a2 <- vB
- EAS2(t0, rFP, t2) # t0 <- &fp[A]
- LOAD64(a0, a1, t0) # a0/a1 <- vA/vA+1
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v0, a2, 0x20 # shift & 0x20
- sra v1, a1, a2 # rhi<- ahi >> (shift&31)
- bnez v0, .L${opcode}_finish
- srl v0, a0, a2 # rlo<- alo >> (shift&31)
- not a0, a2 # alo<- 31-shift (shift is 5b)
- sll a1, 1
- sll a1, a0 # ahi<- ahi << (32-(shift&31))
- or v0, a1 # rlo<- rlo | ahi
- SET_VREG64_GOTO(v0, v1, t2, t0) # vA/vA+1 <- v0/v1
-%def op_shr_long_2addr_sister_code():
-
-.L${opcode}_finish:
- sra a3, a1, 31 # a3<- sign(ah)
- SET_VREG64_GOTO(v1, a3, t2, t0) # vA/vA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_sparse_switch.S b/runtime/interpreter/mterp/mips/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/mips/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/mips/op_sput.S b/runtime/interpreter/mterp/mips/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/mips/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips/op_sput_boolean.S b/runtime/interpreter/mterp/mips/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/mips/op_sput_byte.S b/runtime/interpreter/mterp/mips/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/mips/op_sput_char.S b/runtime/interpreter/mterp/mips/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/mips/op_sput_object.S b/runtime/interpreter/mterp/mips/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/mips/op_sput_short.S b/runtime/interpreter/mterp/mips/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/mips/op_sput_wide.S b/runtime/interpreter/mterp/mips/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/mips/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/mips/op_sub_double.S b/runtime/interpreter/mterp/mips/op_sub_double.S
deleted file mode 100644
index ad8f12c..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% fbinopWide(instr="sub.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_double_2addr.S b/runtime/interpreter/mterp/mips/op_sub_double_2addr.S
deleted file mode 100644
index ed5598d..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% fbinopWide2addr(instr="sub.d fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_float.S b/runtime/interpreter/mterp/mips/op_sub_float.S
deleted file mode 100644
index 402fa2c..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% fbinop(instr="sub.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_float_2addr.S b/runtime/interpreter/mterp/mips/op_sub_float_2addr.S
deleted file mode 100644
index 1d38188..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% fbinop2addr(instr="sub.s fv0, fa0, fa1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_int.S b/runtime/interpreter/mterp/mips/op_sub_int.S
deleted file mode 100644
index 57f618d..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="subu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_int_2addr.S b/runtime/interpreter/mterp/mips/op_sub_int_2addr.S
deleted file mode 100644
index 445ffca..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="subu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_sub_long.S b/runtime/interpreter/mterp/mips/op_sub_long.S
deleted file mode 100644
index a54460b..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_long.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_sub_long():
-/*
- * For little endian the code sequence looks as follows:
- * subu v0,a0,a2
- * subu v1,a1,a3
- * sltu a0,a0,v0
- * subu v1,v1,a0
- */
-% binopWide(result0="v0", result1="v1", preinstr="subu v0, a0, a2", instr="subu v1, a1, a3; sltu a0, a0, v0; subu v1, v1, a0")
diff --git a/runtime/interpreter/mterp/mips/op_sub_long_2addr.S b/runtime/interpreter/mterp/mips/op_sub_long_2addr.S
deleted file mode 100644
index b3dd6b2..0000000
--- a/runtime/interpreter/mterp/mips/op_sub_long_2addr.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_sub_long_2addr():
-/*
- * See op_sub_long.S for more details
- */
-% binopWide2addr(result0="v0", result1="v1", preinstr="subu v0, a0, a2", instr="subu v1, a1, a3; sltu a0, a0, v0; subu v1, v1, a0")
diff --git a/runtime/interpreter/mterp/mips/op_throw.S b/runtime/interpreter/mterp/mips/op_throw.S
deleted file mode 100644
index 84b9e5e..0000000
--- a/runtime/interpreter/mterp/mips/op_throw.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_throw():
- /*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC() # exception handler can throw
- GET_OPA(a2) # a2 <- AA
- GET_VREG(a1, a2) # a1 <- vAA (exception object)
- # null object?
- beqz a1, common_errNullObject # yes, throw an NPE instead
- sw a1, THREAD_EXCEPTION_OFFSET(rSELF) # thread->exception <- obj
- b MterpException
diff --git a/runtime/interpreter/mterp/mips/op_unused_3e.S b/runtime/interpreter/mterp/mips/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_3f.S b/runtime/interpreter/mterp/mips/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_40.S b/runtime/interpreter/mterp/mips/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_41.S b/runtime/interpreter/mterp/mips/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_42.S b/runtime/interpreter/mterp/mips/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_43.S b/runtime/interpreter/mterp/mips/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_73.S b/runtime/interpreter/mterp/mips/op_unused_73.S
deleted file mode 100644
index e3267a3..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_73.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_73():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_79.S b/runtime/interpreter/mterp/mips/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_7a.S b/runtime/interpreter/mterp/mips/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f3.S b/runtime/interpreter/mterp/mips/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f4.S b/runtime/interpreter/mterp/mips/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f5.S b/runtime/interpreter/mterp/mips/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f6.S b/runtime/interpreter/mterp/mips/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f7.S b/runtime/interpreter/mterp/mips/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f8.S b/runtime/interpreter/mterp/mips/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_f9.S b/runtime/interpreter/mterp/mips/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_fc.S b/runtime/interpreter/mterp/mips/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_unused_fd.S b/runtime/interpreter/mterp/mips/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/mips/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/mips/op_ushr_int.S b/runtime/interpreter/mterp/mips/op_ushr_int.S
deleted file mode 100644
index 98d2dfb..0000000
--- a/runtime/interpreter/mterp/mips/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop(instr="srl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_ushr_int_2addr.S b/runtime/interpreter/mterp/mips/op_ushr_int_2addr.S
deleted file mode 100644
index 4b09cac..0000000
--- a/runtime/interpreter/mterp/mips/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% binop2addr(instr="srl a0, a0, a1 ")
diff --git a/runtime/interpreter/mterp/mips/op_ushr_int_lit8.S b/runtime/interpreter/mterp/mips/op_ushr_int_lit8.S
deleted file mode 100644
index 531c30a..0000000
--- a/runtime/interpreter/mterp/mips/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(instr="srl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_ushr_long.S b/runtime/interpreter/mterp/mips/op_ushr_long.S
deleted file mode 100644
index b09e7b3..0000000
--- a/runtime/interpreter/mterp/mips/op_ushr_long.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def op_ushr_long():
- /*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance.
- */
- /* ushr-long vAA, vBB, vCC */
- FETCH(a0, 1) # a0 <- CCBB
- GET_OPA(rOBJ) # rOBJ <- AA
- and a3, a0, 255 # a3 <- BB
- srl a0, a0, 8 # a0 <- CC
- EAS2(a3, rFP, a3) # a3 <- &fp[BB]
- GET_VREG(a2, a0) # a2 <- vCC
- LOAD64(a0, a1, a3) # a0/a1 <- vBB/vBB+1
-
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v0, a2, 0x20 # shift & 0x20
- srl v1, a1, a2 # rhi<- ahi >> (shift&31)
- bnez v0, .L${opcode}_finish
- srl v0, a0, a2 # rlo<- alo >> (shift&31)
- not a0, a2 # alo<- 31-n (shift is 5b)
- sll a1, 1
- sll a1, a0 # ahi<- ahi << (32-(shift&31))
- or v0, a1 # rlo<- rlo | ahi
- SET_VREG64_GOTO(v0, v1, rOBJ, t0) # vAA/vAA+1 <- v0/v1
-%def op_ushr_long_sister_code():
-
-.L${opcode}_finish:
- SET_VREG64_GOTO(v1, zero, rOBJ, t0) # vAA/vAA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_ushr_long_2addr.S b/runtime/interpreter/mterp/mips/op_ushr_long_2addr.S
deleted file mode 100644
index 0da2011..0000000
--- a/runtime/interpreter/mterp/mips/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_ushr_long_2addr():
- /*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* ushr-long/2addr vA, vB */
- GET_OPA4(t3) # t3 <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG(a2, a3) # a2 <- vB
- EAS2(t0, rFP, t3) # t0 <- &fp[A]
- LOAD64(a0, a1, t0) # a0/a1 <- vA/vA+1
-
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
-
- andi v0, a2, 0x20 # shift & 0x20
- srl v1, a1, a2 # rhi<- ahi >> (shift&31)
- bnez v0, .L${opcode}_finish
- srl v0, a0, a2 # rlo<- alo >> (shift&31)
- not a0, a2 # alo<- 31-n (shift is 5b)
- sll a1, 1
- sll a1, a0 # ahi<- ahi << (32-(shift&31))
- or v0, a1 # rlo<- rlo | ahi
- SET_VREG64_GOTO(v0, v1, t3, t0) # vA/vA+1 <- v0/v1
-%def op_ushr_long_2addr_sister_code():
-
-.L${opcode}_finish:
- SET_VREG64_GOTO(v1, zero, t3, t0) # vA/vA+1 <- rlo/rhi
diff --git a/runtime/interpreter/mterp/mips/op_xor_int.S b/runtime/interpreter/mterp/mips/op_xor_int.S
deleted file mode 100644
index 1379a34..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_xor_int_2addr.S b/runtime/interpreter/mterp/mips/op_xor_int_2addr.S
deleted file mode 100644
index 6dbe11c..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_xor_int_lit16.S b/runtime/interpreter/mterp/mips/op_xor_int_lit16.S
deleted file mode 100644
index f8cbce0..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_xor_int_lit8.S b/runtime/interpreter/mterp/mips/op_xor_int_lit8.S
deleted file mode 100644
index 268a43a..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips/op_xor_long.S b/runtime/interpreter/mterp/mips/op_xor_long.S
deleted file mode 100644
index 5c0c641..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(preinstr="xor a0, a0, a2", instr="xor a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/op_xor_long_2addr.S b/runtime/interpreter/mterp/mips/op_xor_long_2addr.S
deleted file mode 100644
index a84e9f0..0000000
--- a/runtime/interpreter/mterp/mips/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(preinstr="xor a0, a0, a2", instr="xor a1, a1, a3")
diff --git a/runtime/interpreter/mterp/mips/other.S b/runtime/interpreter/mterp/mips/other.S
new file mode 100644
index 0000000..5002329
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/other.S
@@ -0,0 +1,345 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC()
+ FETCH(a0, 1) # a0 <- BBBB
+ GET_OPA(a1) # a1 <- AA
+ addu a2, rFP, OFF_FP_SHADOWFRAME # a2 <- shadow frame
+ move a3, rSELF
+ JAL($helper) # v0 <- Mterp(index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST(2) # load rINST
+ bnez v0, MterpPossibleException
+ ADVANCE(2) # advance rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
+%def op_const():
+ /* const vAA, +BBBBbbbb */
+ GET_OPA(a3) # a3 <- AA
+ FETCH(a0, 1) # a0 <- bbbb (low)
+ FETCH(a1, 2) # a1 <- BBBB (high)
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
+
+%def op_const_16():
+ /* const/16 vAA, +BBBB */
+ FETCH_S(a0, 1) # a0 <- ssssBBBB (sign-extended)
+ GET_OPA(a3) # a3 <- AA
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
+
+%def op_const_4():
+ /* const/4 vA, +B */
+ sll a1, rINST, 16 # a1 <- Bxxx0000
+ GET_OPA(a0) # a0 <- A+
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ sra a1, a1, 28 # a1 <- sssssssB (sign-extended)
+ and a0, a0, 15
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a1, a0, t0) # fp[A] <- a1
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, +BBBB0000 */
+ FETCH(a0, 1) # a0 <- 0000BBBB (zero-extended)
+ GET_OPA(a3) # a3 <- AA
+ sll a0, a0, 16 # a0 <- BBBB0000
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG_GOTO(a0, a3, t0) # vAA <- a0
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, string@BBBBBBBB */
+ EXPORT_PC()
+ FETCH(a0, 1) # a0 <- bbbb (low)
+ FETCH(a2, 2) # a2 <- BBBB (high)
+ GET_OPA(a1) # a1 <- AA
+ INSERT_HIGH_HALF(a0, a2) # a0 <- BBBBbbbb
+ addu a2, rFP, OFF_FP_SHADOWFRAME # a2 <- shadow frame
+ move a3, rSELF
+ JAL(MterpConstString) # v0 <- Mterp(index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST(3) # load rINST
+ bnez v0, MterpPossibleException
+ ADVANCE(3) # advance rPC
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_const_wide():
+ /* const-wide vAA, +HHHHhhhhBBBBbbbb */
+ FETCH(a0, 1) # a0 <- bbbb (low)
+ FETCH(a1, 2) # a1 <- BBBB (low middle)
+ FETCH(a2, 3) # a2 <- hhhh (high middle)
+ INSERT_HIGH_HALF(a0, a1) # a0 <- BBBBbbbb (low word)
+ FETCH(a3, 4) # a3 <- HHHH (high)
+ GET_OPA(t1) # t1 <- AA
+ INSERT_HIGH_HALF(a2, a3) # a2 <- HHHHhhhh (high word)
+ FETCH_ADVANCE_INST(5) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a2, t1, t0) # vAA/vAA+1 <- a0/a2
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, +BBBB */
+ FETCH_S(a0, 1) # a0 <- ssssBBBB (sign-extended)
+ GET_OPA(a3) # a3 <- AA
+ sra a1, a0, 31 # a1 <- ssssssss
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, +BBBBbbbb */
+ FETCH(a0, 1) # a0 <- 0000bbbb (low)
+ GET_OPA(a3) # a3 <- AA
+ FETCH_S(a2, 2) # a2 <- ssssBBBB (high)
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ INSERT_HIGH_HALF(a0, a2) # a0 <- BBBBbbbb
+ sra a1, a0, 31 # a1 <- ssssssss
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, +BBBB000000000000 */
+ FETCH(a1, 1) # a1 <- 0000BBBB (zero-extended)
+ GET_OPA(a3) # a3 <- AA
+ li a0, 0 # a0 <- 00000000
+ sll a1, 16 # a1 <- BBBB0000
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a3, t0) # vAA/vAA+1 <- a0/a1
+
+%def op_monitor_enter():
+ /*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ EXPORT_PC()
+ GET_OPA(a2) # a2 <- AA
+ GET_VREG(a0, a2) # a0 <- vAA (object)
+ move a1, rSELF # a1 <- self
+ JAL(artLockObjectFromCode) # v0 <- artLockObject(obj, self)
+ bnez v0, MterpException
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_monitor_exit():
+ /*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ EXPORT_PC()
+ GET_OPA(a2) # a2 <- AA
+ GET_VREG(a0, a2) # a0 <- vAA (object)
+ move a1, rSELF # a1 <- self
+ JAL(artUnlockObjectFromCode) # v0 <- artUnlockObject(obj, self)
+ bnez v0, MterpException
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ GET_OPB(a1) # a1 <- B from 15:12
+ GET_OPA4(a0) # a0 <- A from 11:8
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_VREG(a2, a1) # a2 <- fp[B]
+ GET_INST_OPCODE(t0) # t0 <- opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[A] <- a2
+ .else
+ SET_VREG_GOTO(a2, a0, t0) # fp[A] <- a2
+ .endif
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ FETCH(a1, 2) # a1 <- BBBB
+ FETCH(a0, 1) # a0 <- AAAA
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ GET_VREG(a2, a1) # a2 <- fp[BBBB]
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[AAAA] <- a2
+ .else
+ SET_VREG_GOTO(a2, a0, t0) # fp[AAAA] <- a2
+ .endif
+
+%def op_move_exception():
+ /* move-exception vAA */
+ GET_OPA(a2) # a2 <- AA
+ lw a3, THREAD_EXCEPTION_OFFSET(rSELF) # get exception obj
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GET_OPCODE_TARGET(t0)
+ SET_VREG_OBJECT(a3, a2) # fp[AA] <- exception obj
+ sw zero, THREAD_EXCEPTION_OFFSET(rSELF) # clear exception
+ JR(t0) # jump to next instruction
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ FETCH(a1, 1) # a1 <- BBBB
+ GET_OPA(a0) # a0 <- AA
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_VREG(a2, a1) # a2 <- fp[BBBB]
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT_GOTO(a2, a0, t0) # fp[AA] <- a2
+ .else
+ SET_VREG_GOTO(a2, a0, t0) # fp[AA] <- a2
+ .endif
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ GET_OPA(a2) # a2 <- AA
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ lw a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
+ lw a0, 0(a0) # a0 <- result.i
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT_GOTO(a0, a2, t0) # fp[AA] <- a0
+ .else
+ SET_VREG_GOTO(a0, a2, t0) # fp[AA] <- a0
+ .endif
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* move-result-wide vAA */
+ GET_OPA(a2) # a2 <- AA
+ lw a3, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
+ LOAD64(a0, a1, a3) # a0/a1 <- retval.j
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AA] <- a0/a1
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
+ GET_OPA4(a2) # a2 <- A(+)
+ GET_OPB(a3) # a3 <- B
+ EAS2(a3, rFP, a3) # a3 <- &fp[B]
+ LOAD64(a0, a1, a3) # a0/a1 <- fp[B]
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a2, t0) # fp[A] <- a0/a1
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
+ FETCH(a3, 2) # a3 <- BBBB
+ FETCH(a2, 1) # a2 <- AAAA
+ EAS2(a3, rFP, a3) # a3 <- &fp[BBBB]
+ LOAD64(a0, a1, a3) # a0/a1 <- fp[BBBB]
+ FETCH_ADVANCE_INST(3) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AAAA] <- a0/a1
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6, v7" or "move v7, v6" */
+ FETCH(a3, 1) # a3 <- BBBB
+ GET_OPA(a2) # a2 <- AA
+ EAS2(a3, rFP, a3) # a3 <- &fp[BBBB]
+ LOAD64(a0, a1, a3) # a0/a1 <- fp[BBBB]
+ FETCH_ADVANCE_INST(2) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ SET_VREG64_GOTO(a0, a1, a2, t0) # fp[AA] <- a0/a1
+
+%def op_nop():
+ FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+ GET_INST_OPCODE(t0) # extract opcode from rINST
+ GOTO_OPCODE(t0) # jump to next instruction
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_73():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/mips/unop.S b/runtime/interpreter/mterp/mips/unop.S
deleted file mode 100644
index 34eb118..0000000
--- a/runtime/interpreter/mterp/mips/unop.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def unop(preinstr="", result0="a0", instr=""):
- /*
- * Generic 32-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result0 = op a0".
- * This could be a MIPS instruction or a function call.
- *
- * for: int-to-byte, int-to-char, int-to-short,
- * neg-int, not-int, neg-float
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(t0) # t0 <- A+
- GET_VREG(a0, a3) # a0 <- vB
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $preinstr # optional op
- $instr # a0 <- op, a0-a3 changed
- GET_INST_OPCODE(t1) # extract opcode from rINST
- SET_VREG_GOTO($result0, t0, t1) # vA <- result0
diff --git a/runtime/interpreter/mterp/mips/unopNarrower.S b/runtime/interpreter/mterp/mips/unopNarrower.S
deleted file mode 100644
index 4f0bb1d..0000000
--- a/runtime/interpreter/mterp/mips/unopNarrower.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def unopNarrower(load="LOAD64_F(fa0, fa0f, a3)", instr=""):
- /*
- * Generic 64bit-to-32bit floating-point unary operation. Provide an "instr"
- * line that specifies an instruction that performs "fv0 = op fa0".
- *
- * For: double-to-float
- */
- /* unop vA, vB */
- GET_OPB(a3) # a3 <- B
- GET_OPA4(rOBJ) # rOBJ <- A+
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
- $load
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $instr
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_F_GOTO(fv0, rOBJ, t0) # vA <- fv0
diff --git a/runtime/interpreter/mterp/mips/unopWide.S b/runtime/interpreter/mterp/mips/unopWide.S
deleted file mode 100644
index 269a296..0000000
--- a/runtime/interpreter/mterp/mips/unopWide.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def unopWide(preinstr="", result0="a0", result1="a1", instr=""):
- /*
- * Generic 64-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result0/result1 = op a0/a1".
- * This could be MIPS instruction or a function call.
- *
- * For: neg-long, not-long, neg-double,
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- EAS2(a3, rFP, a3) # a3 <- &fp[B]
- LOAD64(a0, a1, a3) # a0/a1 <- vA
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $preinstr # optional op
- $instr # a0/a1 <- op, a2-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/unopWider.S b/runtime/interpreter/mterp/mips/unopWider.S
deleted file mode 100644
index 7767d6e..0000000
--- a/runtime/interpreter/mterp/mips/unopWider.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def unopWider(preinstr="", result0="a0", result1="a1", instr=""):
- /*
- * Generic 32bit-to-64bit unary operation. Provide an "instr" line
- * that specifies an instruction that performs "result0/result1 = op a0".
- *
- * For: int-to-long
- */
- /* unop vA, vB */
- GET_OPA4(rOBJ) # rOBJ <- A+
- GET_OPB(a3) # a3 <- B
- GET_VREG(a0, a3) # a0 <- vB
- FETCH_ADVANCE_INST(1) # advance rPC, load rINST
- $preinstr # optional op
- $instr # result <- op, a0-a3 changed
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO($result0, $result1, rOBJ, t0) # vA/vA+1 <- a0/a1
diff --git a/runtime/interpreter/mterp/mips/unused.S b/runtime/interpreter/mterp/mips/unused.S
deleted file mode 100644
index 3f37e74..0000000
--- a/runtime/interpreter/mterp/mips/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/mips/zcmp.S b/runtime/interpreter/mterp/mips/zcmp.S
deleted file mode 100644
index eb23eea..0000000
--- a/runtime/interpreter/mterp/mips/zcmp.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def zcmp(condition=""):
- /*
- * Generic one-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform.
- *
- * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- GET_OPA(a0) # a0 <- AA
- GET_VREG(a0, a0) # a0 <- vAA
- FETCH_S(rINST, 1) # rINST <- branch offset, in code units
- b${condition} a0, zero, MterpCommonTakenBranchNoFlags
- li t0, JIT_CHECK_OSR # possible OSR re-entry?
- beq rPROFILE, t0, .L_check_not_taken_osr
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/alt_stub.S b/runtime/interpreter/mterp/mips64/alt_stub.S
deleted file mode 100644
index 17558bb..0000000
--- a/runtime/interpreter/mterp/mips64/alt_stub.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Note that the call to MterpCheckBefore is done as a tail call.
- */
- .extern MterpCheckBefore
- REFRESH_IBASE
- dla ra, artMterpAsmInstructionStart
- dla t9, MterpCheckBefore
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rPC
- daddu ra, ra, (${opnum} * 128) # Addr of primary handler.
- jalr zero, t9 # (self, shadow_frame, dex_pc_ptr) Note: tail call.
diff --git a/runtime/interpreter/mterp/mips64/arithmetic.S b/runtime/interpreter/mterp/mips64/arithmetic.S
new file mode 100644
index 0000000..0b03e02
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/arithmetic.S
@@ -0,0 +1,458 @@
+%def binop(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = a0 op a1".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus. Note that we
+ * *don't* check for (INT_MIN / -1) here, because the CPU handles it
+ * correctly.
+ *
+ * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
+ * xor-int, shl-int, shr-int, ushr-int
+ */
+ /* binop vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG a0, a2 # a0 <- vBB
+ GET_VREG a1, a3 # a1 <- vCC
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG $result, a4 # vAA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def binop2addr(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vB (a1). Useful for integer division and modulus. Note that we
+ * *don't* check for (INT_MIN / -1) here, because the CPU handles it
+ * correctly.
+ *
+ * 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
+ */
+ /* binop/2addr vA, vB */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG a0, a2 # a0 <- vA
+ GET_VREG a1, a3 # a1 <- vB
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG $result, a2 # vA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def binopLit16(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit16" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be an MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * CCCC (a1). Useful for integer division and modulus.
+ *
+ * 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 */
+ lh a1, 2(rPC) # a1 <- sign-extended CCCC
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG a0, a3 # a0 <- vB
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG $result, a2 # vA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+
+%def binopLit8(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 32-bit "lit8" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be an MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * CC (a1). Useful for integer division and modulus.
+ *
+ * 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 */
+ lbu a3, 2(rPC) # a3 <- BB
+ lb a1, 3(rPC) # a1 <- sign-extended CC
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG a0, a3 # a0 <- vBB
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG $result, a2 # vAA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+
+%def binopWide(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 64-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = a0 op a1".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vCC (a1). Useful for integer division and modulus. Note that we
+ * *don't* check for (LONG_MIN / -1) here, because the CPU handles it
+ * correctly.
+ *
+ * For: add-long, sub-long, mul-long, div-long, rem-long, and-long, or-long,
+ * xor-long, shl-long, shr-long, ushr-long
+ */
+ /* binop vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_WIDE a0, a2 # a0 <- vBB
+ GET_VREG_WIDE a1, a3 # a1 <- vCC
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE $result, a4 # vAA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def binopWide2addr(preinstr="", result="a0", chkzero="0", instr=""):
+ /*
+ * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = a0 op a1".
+ * This could be a MIPS instruction or a function call. (If the result
+ * comes back in a register other than a0, you can override "result".)
+ *
+ * If "chkzero" is set to 1, we perform a divide-by-zero check on
+ * vB (a1). Useful for integer division and modulus. Note that we
+ * *don't* check for (LONG_MIN / -1) here, because the CPU handles it
+ * correctly.
+ *
+ * For: add-long/2addr, sub-long/2addr, mul-long/2addr, div-long/2addr,
+ * rem-long/2addr, and-long/2addr, or-long/2addr, xor-long/2addr,
+ * shl-long/2addr, shr-long/2addr, ushr-long/2addr
+ */
+ /* binop/2addr vA, vB */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_WIDE a0, a2 # a0 <- vA
+ GET_VREG_WIDE a1, a3 # a1 <- vB
+ .if $chkzero
+ beqz a1, common_errDivideByZero # is second operand zero?
+ .endif
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ $preinstr # optional op
+ $instr # $result <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE $result, a2 # vA <- $result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def unop(preinstr="", instr=""):
+ /*
+ * Generic 32-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "a0 = op a0".
+ *
+ * for: int-to-byte, int-to-char, int-to-short,
+ * not-int, neg-int
+ */
+ /* unop vA, vB */
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG a0, a3 # a0 <- vB
+ ext a2, rINST, 8, 4 # a2 <- A
+ $preinstr # optional op
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ $instr # a0 <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a2 # vA <- a0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def unopWide(preinstr="", instr=""):
+ /*
+ * Generic 64-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "a0 = op a0".
+ *
+ * For: not-long, neg-long
+ */
+ /* unop vA, vB */
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_WIDE a0, a3 # a0 <- vB
+ ext a2, rINST, 8, 4 # a2 <- A
+ $preinstr # optional op
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ $instr # a0 <- op, a0-a3 changed
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vA <- a0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_add_int():
+% binop(instr="addu a0, a0, a1")
+
+%def op_add_int_2addr():
+% binop2addr(instr="addu a0, a0, a1")
+
+%def op_add_int_lit16():
+% binopLit16(instr="addu a0, a0, a1")
+
+%def op_add_int_lit8():
+% binopLit8(instr="addu a0, a0, a1")
+
+%def op_add_long():
+% binopWide(instr="daddu a0, a0, a1")
+
+%def op_add_long_2addr():
+% binopWide2addr(instr="daddu a0, a0, a1")
+
+%def op_and_int():
+% binop(instr="and a0, a0, a1")
+
+%def op_and_int_2addr():
+% binop2addr(instr="and a0, a0, a1")
+
+%def op_and_int_lit16():
+% binopLit16(instr="and a0, a0, a1")
+
+%def op_and_int_lit8():
+% binopLit8(instr="and a0, a0, a1")
+
+%def op_and_long():
+% binopWide(instr="and a0, a0, a1")
+
+%def op_and_long_2addr():
+% binopWide2addr(instr="and a0, a0, a1")
+
+%def op_cmp_long():
+ /* cmp-long vAA, vBB, vCC */
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ srl a4, rINST, 8 # a4 <- AA
+ GET_VREG_WIDE a0, a2 # a0 <- vBB
+ GET_VREG_WIDE a1, a3 # a1 <- vCC
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ slt a2, a0, a1
+ slt a0, a1, a0
+ subu a0, a0, a2
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a4 # vAA <- result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_div_int():
+% binop(instr="div a0, a0, a1", chkzero="1")
+
+%def op_div_int_2addr():
+% binop2addr(instr="div a0, a0, a1", chkzero="1")
+
+%def op_div_int_lit16():
+% binopLit16(instr="div a0, a0, a1", chkzero="1")
+
+%def op_div_int_lit8():
+% binopLit8(instr="div a0, a0, a1", chkzero="1")
+
+%def op_div_long():
+% binopWide(instr="ddiv a0, a0, a1", chkzero="1")
+
+%def op_div_long_2addr():
+% binopWide2addr(instr="ddiv a0, a0, a1", chkzero="1")
+
+%def op_int_to_byte():
+% unop(instr="seb a0, a0")
+
+%def op_int_to_char():
+% unop(instr="and a0, a0, 0xffff")
+
+%def op_int_to_long():
+ /* int-to-long vA, vB */
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG a0, a3 # a0 <- vB (sign-extended to 64 bits)
+ ext a2, rINST, 8, 4 # a2 <- A
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vA <- vB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_int_to_short():
+% unop(instr="seh a0, a0")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+% binop(instr="mul a0, a0, a1")
+
+%def op_mul_int_2addr():
+% binop2addr(instr="mul a0, a0, a1")
+
+%def op_mul_int_lit16():
+% binopLit16(instr="mul a0, a0, a1")
+
+%def op_mul_int_lit8():
+% binopLit8(instr="mul a0, a0, a1")
+
+%def op_mul_long():
+% binopWide(instr="dmul a0, a0, a1")
+
+%def op_mul_long_2addr():
+% binopWide2addr(instr="dmul a0, a0, a1")
+
+%def op_neg_int():
+% unop(instr="subu a0, zero, a0")
+
+%def op_neg_long():
+% unopWide(instr="dsubu a0, zero, a0")
+
+%def op_not_int():
+% unop(instr="nor a0, zero, a0")
+
+%def op_not_long():
+% unopWide(instr="nor a0, zero, a0")
+
+%def op_or_int():
+% binop(instr="or a0, a0, a1")
+
+%def op_or_int_2addr():
+% binop2addr(instr="or a0, a0, a1")
+
+%def op_or_int_lit16():
+% binopLit16(instr="or a0, a0, a1")
+
+%def op_or_int_lit8():
+% binopLit8(instr="or a0, a0, a1")
+
+%def op_or_long():
+% binopWide(instr="or a0, a0, a1")
+
+%def op_or_long_2addr():
+% binopWide2addr(instr="or a0, a0, a1")
+
+%def op_rem_int():
+% binop(instr="mod a0, a0, a1", chkzero="1")
+
+%def op_rem_int_2addr():
+% binop2addr(instr="mod a0, a0, a1", chkzero="1")
+
+%def op_rem_int_lit16():
+% binopLit16(instr="mod a0, a0, a1", chkzero="1")
+
+%def op_rem_int_lit8():
+% binopLit8(instr="mod a0, a0, a1", chkzero="1")
+
+%def op_rem_long():
+% binopWide(instr="dmod a0, a0, a1", chkzero="1")
+
+%def op_rem_long_2addr():
+% binopWide2addr(instr="dmod a0, a0, a1", chkzero="1")
+
+%def op_rsub_int():
+% binopLit16(instr="subu a0, a1, a0")
+
+%def op_rsub_int_lit8():
+% binopLit8(instr="subu a0, a1, a0")
+
+%def op_shl_int():
+% binop(instr="sll a0, a0, a1")
+
+%def op_shl_int_2addr():
+% binop2addr(instr="sll a0, a0, a1")
+
+%def op_shl_int_lit8():
+% binopLit8(instr="sll a0, a0, a1")
+
+%def op_shl_long():
+% binopWide(instr="dsll a0, a0, a1")
+
+%def op_shl_long_2addr():
+% binopWide2addr(instr="dsll a0, a0, a1")
+
+%def op_shr_int():
+% binop(instr="sra a0, a0, a1")
+
+%def op_shr_int_2addr():
+% binop2addr(instr="sra a0, a0, a1")
+
+%def op_shr_int_lit8():
+% binopLit8(instr="sra a0, a0, a1")
+
+%def op_shr_long():
+% binopWide(instr="dsra a0, a0, a1")
+
+%def op_shr_long_2addr():
+% binopWide2addr(instr="dsra a0, a0, a1")
+
+%def op_sub_int():
+% binop(instr="subu a0, a0, a1")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="subu a0, a0, a1")
+
+%def op_sub_long():
+% binopWide(instr="dsubu a0, a0, a1")
+
+%def op_sub_long_2addr():
+% binopWide2addr(instr="dsubu a0, a0, a1")
+
+%def op_ushr_int():
+% binop(instr="srl a0, a0, a1")
+
+%def op_ushr_int_2addr():
+% binop2addr(instr="srl a0, a0, a1")
+
+%def op_ushr_int_lit8():
+% binopLit8(instr="srl a0, a0, a1")
+
+%def op_ushr_long():
+% binopWide(instr="dsrl a0, a0, a1")
+
+%def op_ushr_long_2addr():
+% binopWide2addr(instr="dsrl a0, a0, a1")
+
+%def op_xor_int():
+% binop(instr="xor a0, a0, a1")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="xor a0, a0, a1")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="xor a0, a0, a1")
+
+%def op_xor_int_lit8():
+% binopLit8(instr="xor a0, a0, a1")
+
+%def op_xor_long():
+% binopWide(instr="xor a0, a0, a1")
+
+%def op_xor_long_2addr():
+% binopWide2addr(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/array.S b/runtime/interpreter/mterp/mips64/array.S
new file mode 100644
index 0000000..9d97f0a
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/array.S
@@ -0,0 +1,241 @@
+%def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short
+ *
+ * NOTE: assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ srl a4, rINST, 8 # a4 <- AA
+ GET_VREG_U a0, a2 # a0 <- vBB (array object)
+ GET_VREG a1, a3 # a1 <- vCC (requested index)
+ beqz a0, common_errNullObject # bail if null array object
+ lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
+ .if $shift
+ # [d]lsa does not support shift count of 0.
+ dlsa a0, a1, a0, $shift # a0 <- arrayObj + index*width
+ .else
+ daddu a0, a1, a0 # a0 <- arrayObj + index*width
+ .endif
+ bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ $load a2, $data_offset(a0) # a2 <- vBB[vCC]
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a2, a4 # vAA <- a2
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_aget_boolean():
+% op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+ /*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ .extern artAGetObjectFromMterp
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ EXPORT_PC
+ GET_VREG_U a0, a2 # a0 <- vBB (array object)
+ GET_VREG a1, a3 # a1 <- vCC (requested index)
+ jal artAGetObjectFromMterp # (array, index)
+ ld a1, THREAD_EXCEPTION_OFFSET(rSELF)
+ srl a4, rINST, 8 # a4 <- AA
+ PREFETCH_INST 2
+ bnez a1, MterpException
+ SET_VREG_OBJECT v0, a4 # vAA <- v0
+ ADVANCE 2
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_aget_short():
+% op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+ /*
+ * Array get, 64 bits. vAA <- vBB[vCC].
+ *
+ */
+ /* aget-wide vAA, vBB, vCC */
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ srl a4, rINST, 8 # a4 <- AA
+ GET_VREG_U a0, a2 # a0 <- vBB (array object)
+ GET_VREG a1, a3 # a1 <- vCC (requested index)
+ beqz a0, common_errNullObject # bail if null array object
+ lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
+ dlsa a0, a1, a0, 3 # a0 <- arrayObj + index*width
+ bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ lw a2, MIRROR_WIDE_ARRAY_DATA_OFFSET(a0)
+ lw a3, (MIRROR_WIDE_ARRAY_DATA_OFFSET+4)(a0)
+ dinsu a2, a3, 32, 32 # a2 <- vBB[vCC]
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a2, a4 # vAA <- a2
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+ /*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short
+ *
+ * NOTE: this assumes data offset for arrays is the same for all non-wide types.
+ * If this changes, specialize.
+ */
+ /* op vAA, vBB, vCC */
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ srl a4, rINST, 8 # a4 <- AA
+ GET_VREG_U a0, a2 # a0 <- vBB (array object)
+ GET_VREG a1, a3 # a1 <- vCC (requested index)
+ beqz a0, common_errNullObject # bail if null array object
+ lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
+ .if $shift
+ # [d]lsa does not support shift count of 0.
+ dlsa a0, a1, a0, $shift # a0 <- arrayObj + index*width
+ .else
+ daddu a0, a1, a0 # a0 <- arrayObj + index*width
+ .endif
+ bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_VREG a2, a4 # a2 <- vAA
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ $store a2, $data_offset(a0) # vBB[vCC] <- a2
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_aput_boolean():
+% op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+ /*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ */
+ /* op vAA, vBB, vCC */
+ .extern MterpAputObject
+ EXPORT_PC
+ daddu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ jal MterpAputObject
+ beqzc v0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_aput_short():
+% op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+ /*
+ * Array put, 64 bits. vBB[vCC] <- vAA.
+ *
+ */
+ /* aput-wide vAA, vBB, vCC */
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ srl a4, rINST, 8 # a4 <- AA
+ GET_VREG_U a0, a2 # a0 <- vBB (array object)
+ GET_VREG a1, a3 # a1 <- vCC (requested index)
+ beqz a0, common_errNullObject # bail if null array object
+ lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
+ dlsa a0, a1, a0, 3 # a0 <- arrayObj + index*width
+ bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
+ GET_VREG_WIDE a2, a4 # a2 <- vAA
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ sw a2, MIRROR_WIDE_ARRAY_DATA_OFFSET(a0)
+ dsrl32 a2, a2, 0
+ sw a2, (MIRROR_WIDE_ARRAY_DATA_OFFSET+4)(a0) # vBB[vCC] <- a2
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_array_length():
+ /*
+ * Return the length of an array.
+ */
+ srl a1, rINST, 12 # a1 <- B
+ GET_VREG_U a0, a1 # a0 <- vB (object ref)
+ ext a2, rINST, 8, 4 # a2 <- A
+ beqz a0, common_errNullObject # yup, fail
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- array length
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a3, a2 # vB <- length
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ .extern MterpFillArrayData
+ EXPORT_PC
+ lh a1, 2(rPC) # a1 <- bbbb (lo)
+ lh a0, 4(rPC) # a0 <- BBBB (hi)
+ srl a3, rINST, 8 # a3 <- AA
+ ins a1, a0, 16, 16 # a1 <- BBBBbbbb
+ GET_VREG_U a0, a3 # a0 <- vAA (array object)
+ dlsa a1, a1, rPC, 1 # a1 <- PC + BBBBbbbb*2 (array data off.)
+ jal MterpFillArrayData # (obj, payload)
+ beqzc v0, MterpPossibleException # exception?
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+ /*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class//CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type//BBBB */
+ .extern $helper
+ EXPORT_PC
+ daddu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rSELF
+ jal $helper
+ beqzc v0, MterpPossibleException
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+ /*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class//CCCC */
+ .extern MterpNewArray
+ EXPORT_PC
+ daddu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ move a3, rSELF
+ jal MterpNewArray
+ beqzc v0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/bincmp.S b/runtime/interpreter/mterp/mips64/bincmp.S
deleted file mode 100644
index bdf01dc..0000000
--- a/runtime/interpreter/mterp/mips64/bincmp.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def bincmp(condition=""):
- /*
- * Generic two-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform, e.g. for
- * "if-le" you would use "le".
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC)
- GET_VREG a0, a2 # a0 <- vA
- GET_VREG a1, a3 # a1 <- vB
- b${condition}c a0, a1, MterpCommonTakenBranchNoFlags
- li v0, JIT_CHECK_OSR # possible OSR re-entry?
- beqc rPROFILE, v0, .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/binop.S b/runtime/interpreter/mterp/mips64/binop.S
deleted file mode 100644
index 9332fad..0000000
--- a/runtime/interpreter/mterp/mips64/binop.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binop(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = a0 op a1".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (INT_MIN / -1) here, because the CPU handles it
- * correctly.
- *
- * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
- * xor-int, shl-int, shr-int, ushr-int
- */
- /* binop vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG a0, a2 # a0 <- vBB
- GET_VREG a1, a3 # a1 <- vCC
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG $result, a4 # vAA <- $result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/binop2addr.S b/runtime/interpreter/mterp/mips64/binop2addr.S
deleted file mode 100644
index 19f1815..0000000
--- a/runtime/interpreter/mterp/mips64/binop2addr.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binop2addr(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vB (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (INT_MIN / -1) here, because the CPU handles it
- * correctly.
- *
- * 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
- */
- /* binop/2addr vA, vB */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG a0, a2 # a0 <- vA
- GET_VREG a1, a3 # a1 <- vB
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG $result, a2 # vA <- $result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/binopLit16.S b/runtime/interpreter/mterp/mips64/binopLit16.S
deleted file mode 100644
index 7cb2b97..0000000
--- a/runtime/interpreter/mterp/mips64/binopLit16.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def binopLit16(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit16" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be an MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * CCCC (a1). Useful for integer division and modulus.
- *
- * 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 */
- lh a1, 2(rPC) # a1 <- sign-extended CCCC
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG a0, a3 # a0 <- vB
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG $result, a2 # vA <- $result
- GOTO_OPCODE v0 # jump to next instruction
-
diff --git a/runtime/interpreter/mterp/mips64/binopLit8.S b/runtime/interpreter/mterp/mips64/binopLit8.S
deleted file mode 100644
index 3c0449f..0000000
--- a/runtime/interpreter/mterp/mips64/binopLit8.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def binopLit8(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 32-bit "lit8" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be an MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * CC (a1). Useful for integer division and modulus.
- *
- * 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 */
- lbu a3, 2(rPC) # a3 <- BB
- lb a1, 3(rPC) # a1 <- sign-extended CC
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG a0, a3 # a0 <- vBB
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG $result, a2 # vAA <- $result
- GOTO_OPCODE v0 # jump to next instruction
-
diff --git a/runtime/interpreter/mterp/mips64/binopWide.S b/runtime/interpreter/mterp/mips64/binopWide.S
deleted file mode 100644
index 2206b31..0000000
--- a/runtime/interpreter/mterp/mips64/binopWide.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binopWide(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 64-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = a0 op a1".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vCC (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (LONG_MIN / -1) here, because the CPU handles it
- * correctly.
- *
- * For: add-long, sub-long, mul-long, div-long, rem-long, and-long, or-long,
- * xor-long, shl-long, shr-long, ushr-long
- */
- /* binop vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_WIDE a0, a2 # a0 <- vBB
- GET_VREG_WIDE a1, a3 # a1 <- vCC
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE $result, a4 # vAA <- $result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/binopWide2addr.S b/runtime/interpreter/mterp/mips64/binopWide2addr.S
deleted file mode 100644
index 8758a80..0000000
--- a/runtime/interpreter/mterp/mips64/binopWide2addr.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def binopWide2addr(preinstr="", result="a0", chkzero="0", instr=""):
- /*
- * Generic 64-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = a0 op a1".
- * This could be a MIPS instruction or a function call. (If the result
- * comes back in a register other than a0, you can override "result".)
- *
- * If "chkzero" is set to 1, we perform a divide-by-zero check on
- * vB (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (LONG_MIN / -1) here, because the CPU handles it
- * correctly.
- *
- * For: add-long/2addr, sub-long/2addr, mul-long/2addr, div-long/2addr,
- * rem-long/2addr, and-long/2addr, or-long/2addr, xor-long/2addr,
- * shl-long/2addr, shr-long/2addr, ushr-long/2addr
- */
- /* binop/2addr vA, vB */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_WIDE a0, a2 # a0 <- vA
- GET_VREG_WIDE a1, a3 # a1 <- vB
- .if $chkzero
- beqz a1, common_errDivideByZero # is second operand zero?
- .endif
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- $preinstr # optional op
- $instr # $result <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE $result, a2 # vA <- $result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/const.S b/runtime/interpreter/mterp/mips64/const.S
deleted file mode 100644
index 5de2404..0000000
--- a/runtime/interpreter/mterp/mips64/const.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- BBBB
- srl a1, rINST, 8 # a1 <- AA
- daddu a2, rFP, OFF_FP_SHADOWFRAME
- move a3, rSELF
- jal $helper # (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 2 # load rINST
- bnez v0, MterpPossibleException # let reference interpreter deal with it.
- ADVANCE 2 # advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/control_flow.S b/runtime/interpreter/mterp/mips64/control_flow.S
new file mode 100644
index 0000000..457b938
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/control_flow.S
@@ -0,0 +1,217 @@
+%def bincmp(condition=""):
+ /*
+ * Generic two-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform, e.g. for
+ * "if-le" you would use "le".
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC)
+ GET_VREG a0, a2 # a0 <- vA
+ GET_VREG a1, a3 # a1 <- vB
+ b${condition}c a0, a1, MterpCommonTakenBranchNoFlags
+ li v0, JIT_CHECK_OSR # possible OSR re-entry?
+ beqc rPROFILE, v0, .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def zcmp(condition=""):
+ /*
+ * Generic one-operand compare-and-branch operation. Provide a "condition"
+ * fragment that specifies the comparison to perform, e.g. for
+ * "if-lez" you would use "le".
+ *
+ * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ srl a2, rINST, 8 # a2 <- AA
+ lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB)
+ GET_VREG a0, a2 # a0 <- vAA
+ b${condition}zc a0, MterpCommonTakenBranchNoFlags
+ li v0, JIT_CHECK_OSR # possible OSR re-entry?
+ beqc rPROFILE, v0, .L_check_not_taken_osr
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_goto():
+ /*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ srl rINST, rINST, 8
+ seb rINST, rINST # rINST <- offset (sign-extended AA)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_16():
+ /*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ lh rINST, 2(rPC) # rINST <- offset (sign-extended AAAA)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_goto_32():
+ /*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Unlike most opcodes, this one is allowed to branch to itself, so
+ * our "backward branch" test must be "<=0" instead of "<0".
+ */
+ /* goto/32 +AAAAAAAA */
+ lh rINST, 2(rPC) # rINST <- aaaa (low)
+ lh a1, 4(rPC) # a1 <- AAAA (high)
+ ins rINST, a1, 16, 16 # rINST <- offset (sign-extended AAAAaaaa)
+ b MterpCommonTakenBranchNoFlags
+
+%def op_if_eq():
+% bincmp(condition="eq")
+
+%def op_if_eqz():
+% zcmp(condition="eq")
+
+%def op_if_ge():
+% bincmp(condition="ge")
+
+%def op_if_gez():
+% zcmp(condition="ge")
+
+%def op_if_gt():
+% bincmp(condition="gt")
+
+%def op_if_gtz():
+% zcmp(condition="gt")
+
+%def op_if_le():
+% bincmp(condition="le")
+
+%def op_if_lez():
+% zcmp(condition="le")
+
+%def op_if_lt():
+% bincmp(condition="lt")
+
+%def op_if_ltz():
+% zcmp(condition="lt")
+
+%def op_if_ne():
+% bincmp(condition="ne")
+
+%def op_if_nez():
+% zcmp(condition="ne")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+ /*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBBBBBB */
+ .extern $func
+ lh a0, 2(rPC) # a0 <- bbbb (lo)
+ lh a1, 4(rPC) # a1 <- BBBB (hi)
+ srl a3, rINST, 8 # a3 <- AA
+ ins a0, a1, 16, 16 # a0 <- BBBBbbbb
+ GET_VREG a1, a3 # a1 <- vAA
+ dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2
+ jal $func # v0 <- code-unit branch offset
+ move rINST, v0
+ b MterpCommonTakenBranchNoFlags
+
+%def op_return(instr="GET_VREG"):
+ /*
+ * Return a 32-bit value.
+ *
+ * for: return (sign-extend), return-object (zero-extend)
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ .extern MterpSuspendCheck
+ jal MterpThreadFenceForConstructor
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqzc ra, 1f
+ jal MterpSuspendCheck # (self)
+1:
+ srl a2, rINST, 8 # a2 <- AA
+ $instr a0, a2 # a0 <- vAA
+ b MterpReturn
+
+%def op_return_object():
+% op_return(instr="GET_VREG_U")
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ .extern MterpSuspendCheck
+ jal MterpThreadFenceForConstructor
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqzc ra, 1f
+ jal MterpSuspendCheck # (self)
+1:
+ li a0, 0
+ b MterpReturn
+
+%def op_return_void_no_barrier():
+ .extern MterpSuspendCheck
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqzc ra, 1f
+ jal MterpSuspendCheck # (self)
+1:
+ li a0, 0
+ b MterpReturn
+
+%def op_return_wide():
+ /*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ .extern MterpSuspendCheck
+ jal MterpThreadFenceForConstructor
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ move a0, rSELF
+ and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ beqzc ra, 1f
+ jal MterpSuspendCheck # (self)
+1:
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG_WIDE a0, a2 # a0 <- vAA
+ b MterpReturn
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+ /*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG_U a0, a2 # a0 <- vAA (exception object)
+ beqzc a0, common_errNullObject
+ sd a0, THREAD_EXCEPTION_OFFSET(rSELF) # thread->exception <- obj
+ b MterpException
diff --git a/runtime/interpreter/mterp/mips64/entry.S b/runtime/interpreter/mterp/mips64/entry.S
deleted file mode 100644
index 0c64137..0000000
--- a/runtime/interpreter/mterp/mips64/entry.S
+++ /dev/null
@@ -1,95 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Interpreter entry point.
- */
-
- .set reorder
-
- .text
- .global ExecuteMterpImpl
- .type ExecuteMterpImpl, %function
- .balign 16
-/*
- * On entry:
- * a0 Thread* self
- * a1 dex_instructions
- * a2 ShadowFrame
- * a3 JValue* result_register
- *
- */
-ExecuteMterpImpl:
- .cfi_startproc
- .cpsetup t9, t8, ExecuteMterpImpl
-
- .cfi_def_cfa sp, 0
- daddu sp, sp, -STACK_SIZE
- .cfi_adjust_cfa_offset STACK_SIZE
-
- sd t8, STACK_OFFSET_GP(sp)
- .cfi_rel_offset 28, STACK_OFFSET_GP
- sd ra, STACK_OFFSET_RA(sp)
- .cfi_rel_offset 31, STACK_OFFSET_RA
-
- sd s0, STACK_OFFSET_S0(sp)
- .cfi_rel_offset 16, STACK_OFFSET_S0
- sd s1, STACK_OFFSET_S1(sp)
- .cfi_rel_offset 17, STACK_OFFSET_S1
- sd s2, STACK_OFFSET_S2(sp)
- .cfi_rel_offset 18, STACK_OFFSET_S2
- sd s3, STACK_OFFSET_S3(sp)
- .cfi_rel_offset 19, STACK_OFFSET_S3
- sd s4, STACK_OFFSET_S4(sp)
- .cfi_rel_offset 20, STACK_OFFSET_S4
- sd s5, STACK_OFFSET_S5(sp)
- .cfi_rel_offset 21, STACK_OFFSET_S5
- sd s6, STACK_OFFSET_S6(sp)
- .cfi_rel_offset 22, STACK_OFFSET_S6
-
- /* Remember the return register */
- sd a3, SHADOWFRAME_RESULT_REGISTER_OFFSET(a2)
-
- /* Remember the dex instruction pointer */
- sd a1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(a2)
-
- /* set up "named" registers */
- move rSELF, a0
- daddu rFP, a2, SHADOWFRAME_VREGS_OFFSET
- lw v0, SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(a2)
- dlsa rREFS, v0, rFP, 2
- lw v0, SHADOWFRAME_DEX_PC_OFFSET(a2)
- dlsa rPC, v0, a1, 1
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
- EXPORT_PC
-
- /* Starting ibase */
- REFRESH_IBASE
-
- /* Set up for backwards branches & osr profiling */
- ld a0, OFF_FP_METHOD(rFP)
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rSELF
- jal MterpSetUpHotnessCountdown
- move rPROFILE, v0 # Starting hotness countdown to rPROFILE
-
- /* start executing the instruction at rPC */
- FETCH_INST
- GET_INST_OPCODE v0
- GOTO_OPCODE v0
-
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/mips64/fallback.S b/runtime/interpreter/mterp/mips64/fallback.S
deleted file mode 100644
index 71abfeb..0000000
--- a/runtime/interpreter/mterp/mips64/fallback.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/mips64/fbinop.S b/runtime/interpreter/mterp/mips64/fbinop.S
deleted file mode 100644
index 5090528..0000000
--- a/runtime/interpreter/mterp/mips64/fbinop.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def fbinop(instr=""):
- /*:
- * Generic 32-bit floating-point operation.
- *
- * For: add-float, sub-float, mul-float, div-float.
- * form: <op> f0, f0, f1
- */
- /* binop vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_FLOAT f0, a2 # f0 <- vBB
- GET_VREG_FLOAT f1, a3 # f1 <- vCC
- $instr # f0 <- f0 op f1
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_FLOAT f0, a4 # vAA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fbinop2addr.S b/runtime/interpreter/mterp/mips64/fbinop2addr.S
deleted file mode 100644
index fe5ad2b..0000000
--- a/runtime/interpreter/mterp/mips64/fbinop2addr.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def fbinop2addr(instr=""):
- /*:
- * Generic 32-bit "/2addr" floating-point operation.
- *
- * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr.
- * form: <op> f0, f0, f1
- */
- /* binop/2addr vA, vB */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_FLOAT f0, a2 # f0 <- vA
- GET_VREG_FLOAT f1, a3 # f1 <- vB
- $instr # f0 <- f0 op f1
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_FLOAT f0, a2 # vA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fbinopWide.S b/runtime/interpreter/mterp/mips64/fbinopWide.S
deleted file mode 100644
index ca7765b..0000000
--- a/runtime/interpreter/mterp/mips64/fbinopWide.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def fbinopWide(instr=""):
- /*:
- * Generic 64-bit floating-point operation.
- *
- * For: add-double, sub-double, mul-double, div-double.
- * form: <op> f0, f0, f1
- */
- /* binop vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_DOUBLE f0, a2 # f0 <- vBB
- GET_VREG_DOUBLE f1, a3 # f1 <- vCC
- $instr # f0 <- f0 op f1
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_DOUBLE f0, a4 # vAA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fbinopWide2addr.S b/runtime/interpreter/mterp/mips64/fbinopWide2addr.S
deleted file mode 100644
index a4dfd4c..0000000
--- a/runtime/interpreter/mterp/mips64/fbinopWide2addr.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def fbinopWide2addr(instr=""):
- /*:
- * Generic 64-bit "/2addr" floating-point operation.
- *
- * For: add-double/2addr, sub-double/2addr, mul-double/2addr, div-double/2addr.
- * form: <op> f0, f0, f1
- */
- /* binop/2addr vA, vB */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_DOUBLE f0, a2 # f0 <- vA
- GET_VREG_DOUBLE f1, a3 # f1 <- vB
- $instr # f0 <- f0 op f1
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_DOUBLE f0, a2 # vA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fcmp.S b/runtime/interpreter/mterp/mips64/fcmp.S
deleted file mode 100644
index bc40f96..0000000
--- a/runtime/interpreter/mterp/mips64/fcmp.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def fcmp(gt_bias=""):
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * For: cmpl-float, cmpg-float
- */
- /* op vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_FLOAT f0, a2 # f0 <- vBB
- GET_VREG_FLOAT f1, a3 # f1 <- vCC
- cmp.eq.s f2, f0, f1
- li a0, 0
- bc1nez f2, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- cmp.lt.s f2, f0, f1
- li a0, -1
- bc1nez f2, 1f # done if vBB < vCC (ordered)
- li a0, 1 # vBB > vCC or unordered
- .else
- cmp.lt.s f2, f1, f0
- li a0, 1
- bc1nez f2, 1f # done if vBB > vCC (ordered)
- li a0, -1 # vBB < vCC or unordered
- .endif
-1:
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a4 # vAA <- a0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fcmpWide.S b/runtime/interpreter/mterp/mips64/fcmpWide.S
deleted file mode 100644
index 05f33e6..0000000
--- a/runtime/interpreter/mterp/mips64/fcmpWide.S
+++ /dev/null
@@ -1,32 +0,0 @@
-%def fcmpWide(gt_bias=""):
- /*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * For: cmpl-double, cmpg-double
- */
- /* op vAA, vBB, vCC */
- srl a4, rINST, 8 # a4 <- AA
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_DOUBLE f0, a2 # f0 <- vBB
- GET_VREG_DOUBLE f1, a3 # f1 <- vCC
- cmp.eq.d f2, f0, f1
- li a0, 0
- bc1nez f2, 1f # done if vBB == vCC (ordered)
- .if $gt_bias
- cmp.lt.d f2, f0, f1
- li a0, -1
- bc1nez f2, 1f # done if vBB < vCC (ordered)
- li a0, 1 # vBB > vCC or unordered
- .else
- cmp.lt.d f2, f1, f0
- li a0, 1
- bc1nez f2, 1f # done if vBB > vCC (ordered)
- li a0, -1 # vBB < vCC or unordered
- .endif
-1:
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a4 # vAA <- a0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fcvtFooter.S b/runtime/interpreter/mterp/mips64/fcvtFooter.S
deleted file mode 100644
index 711f3f3..0000000
--- a/runtime/interpreter/mterp/mips64/fcvtFooter.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def fcvtFooter(suffix="", valreg=""):
- /*
- * Stores a specified register containing the result of conversion
- * from or to a floating-point type and jumps to the next instruction.
- *
- * Expects a1 to contain the destination Dalvik register number.
- * a1 is set up by fcvtHeader.S.
- *
- * For: int-to-float, int-to-double, long-to-float, long-to-double,
- * float-to-int, float-to-long, float-to-double, double-to-int,
- * double-to-long, double-to-float, neg-float, neg-double.
- *
- * Note that this file can't be included after a break in other files
- * and in those files its contents appear as a copy.
- * See: float-to-int, float-to-long, double-to-int, double-to-long.
- */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG$suffix $valreg, a1
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/fcvtHeader.S b/runtime/interpreter/mterp/mips64/fcvtHeader.S
deleted file mode 100644
index 688b6be..0000000
--- a/runtime/interpreter/mterp/mips64/fcvtHeader.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def fcvtHeader(suffix="", valreg=""):
- /*
- * Loads a specified register from vB. Used primarily for conversions
- * from or to a floating-point type.
- *
- * Sets up a1 = A and a2 = B. a2 is later used by fcvtFooter.S to
- * store the result in vA and jump to the next instruction.
- *
- * For: int-to-float, int-to-double, long-to-float, long-to-double,
- * float-to-int, float-to-long, float-to-double, double-to-int,
- * double-to-long, double-to-float, neg-float, neg-double.
- */
- ext a1, rINST, 8, 4 # a1 <- A
- srl a2, rINST, 12 # a2 <- B
- GET_VREG$suffix $valreg, a2
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
diff --git a/runtime/interpreter/mterp/mips64/field.S b/runtime/interpreter/mterp/mips64/field.S
deleted file mode 100644
index d61b06a..0000000
--- a/runtime/interpreter/mterp/mips64/field.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def field(helper=""):
-TODO
diff --git a/runtime/interpreter/mterp/mips64/floating_point.S b/runtime/interpreter/mterp/mips64/floating_point.S
new file mode 100644
index 0000000..1132a09
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/floating_point.S
@@ -0,0 +1,382 @@
+%def fbinop(instr=""):
+ /*:
+ * Generic 32-bit floating-point operation.
+ *
+ * For: add-float, sub-float, mul-float, div-float.
+ * form: <op> f0, f0, f1
+ */
+ /* binop vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_FLOAT f0, a2 # f0 <- vBB
+ GET_VREG_FLOAT f1, a3 # f1 <- vCC
+ $instr # f0 <- f0 op f1
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a4 # vAA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fbinop2addr(instr=""):
+ /*:
+ * Generic 32-bit "/2addr" floating-point operation.
+ *
+ * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr.
+ * form: <op> f0, f0, f1
+ */
+ /* binop/2addr vA, vB */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_FLOAT f0, a2 # f0 <- vA
+ GET_VREG_FLOAT f1, a3 # f1 <- vB
+ $instr # f0 <- f0 op f1
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a2 # vA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fbinopWide(instr=""):
+ /*:
+ * Generic 64-bit floating-point operation.
+ *
+ * For: add-double, sub-double, mul-double, div-double.
+ * form: <op> f0, f0, f1
+ */
+ /* binop vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_DOUBLE f0, a2 # f0 <- vBB
+ GET_VREG_DOUBLE f1, a3 # f1 <- vCC
+ $instr # f0 <- f0 op f1
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a4 # vAA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fbinopWide2addr(instr=""):
+ /*:
+ * Generic 64-bit "/2addr" floating-point operation.
+ *
+ * For: add-double/2addr, sub-double/2addr, mul-double/2addr, div-double/2addr.
+ * form: <op> f0, f0, f1
+ */
+ /* binop/2addr vA, vB */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_DOUBLE f0, a2 # f0 <- vA
+ GET_VREG_DOUBLE f1, a3 # f1 <- vB
+ $instr # f0 <- f0 op f1
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a2 # vA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fcmp(gt_bias=""):
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * For: cmpl-float, cmpg-float
+ */
+ /* op vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_FLOAT f0, a2 # f0 <- vBB
+ GET_VREG_FLOAT f1, a3 # f1 <- vCC
+ cmp.eq.s f2, f0, f1
+ li a0, 0
+ bc1nez f2, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ cmp.lt.s f2, f0, f1
+ li a0, -1
+ bc1nez f2, 1f # done if vBB < vCC (ordered)
+ li a0, 1 # vBB > vCC or unordered
+ .else
+ cmp.lt.s f2, f1, f0
+ li a0, 1
+ bc1nez f2, 1f # done if vBB > vCC (ordered)
+ li a0, -1 # vBB < vCC or unordered
+ .endif
+1:
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a4 # vAA <- a0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fcmpWide(gt_bias=""):
+ /*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * For: cmpl-double, cmpg-double
+ */
+ /* op vAA, vBB, vCC */
+ srl a4, rINST, 8 # a4 <- AA
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_DOUBLE f0, a2 # f0 <- vBB
+ GET_VREG_DOUBLE f1, a3 # f1 <- vCC
+ cmp.eq.d f2, f0, f1
+ li a0, 0
+ bc1nez f2, 1f # done if vBB == vCC (ordered)
+ .if $gt_bias
+ cmp.lt.d f2, f0, f1
+ li a0, -1
+ bc1nez f2, 1f # done if vBB < vCC (ordered)
+ li a0, 1 # vBB > vCC or unordered
+ .else
+ cmp.lt.d f2, f1, f0
+ li a0, 1
+ bc1nez f2, 1f # done if vBB > vCC (ordered)
+ li a0, -1 # vBB < vCC or unordered
+ .endif
+1:
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a4 # vAA <- a0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fcvtFooter(suffix="", valreg=""):
+ /*
+ * Stores a specified register containing the result of conversion
+ * from or to a floating-point type and jumps to the next instruction.
+ *
+ * Expects a1 to contain the destination Dalvik register number.
+ * a1 is set up by fcvtHeader.S.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ *
+ * Note that this file can't be included after a break in other files
+ * and in those files its contents appear as a copy.
+ * See: float-to-int, float-to-long, double-to-int, double-to-long.
+ */
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG$suffix $valreg, a1
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def fcvtHeader(suffix="", valreg=""):
+ /*
+ * Loads a specified register from vB. Used primarily for conversions
+ * from or to a floating-point type.
+ *
+ * Sets up a1 = A and a2 = B. a2 is later used by fcvtFooter.S to
+ * store the result in vA and jump to the next instruction.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ */
+ ext a1, rINST, 8, 4 # a1 <- A
+ srl a2, rINST, 12 # a2 <- B
+ GET_VREG$suffix $valreg, a2
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
+%def op_add_double():
+% fbinopWide(instr="add.d f0, f0, f1")
+
+%def op_add_double_2addr():
+% fbinopWide2addr(instr="add.d f0, f0, f1")
+
+%def op_add_float():
+% fbinop(instr="add.s f0, f0, f1")
+
+%def op_add_float_2addr():
+% fbinop2addr(instr="add.s f0, f0, f1")
+
+%def op_cmpg_double():
+% fcmpWide(gt_bias="1")
+
+%def op_cmpg_float():
+% fcmp(gt_bias="1")
+
+%def op_cmpl_double():
+% fcmpWide(gt_bias="0")
+
+%def op_cmpl_float():
+% fcmp(gt_bias="0")
+
+%def op_div_double():
+% fbinopWide(instr="div.d f0, f0, f1")
+
+%def op_div_double_2addr():
+% fbinopWide2addr(instr="div.d f0, f0, f1")
+
+%def op_div_float():
+% fbinop(instr="div.s f0, f0, f1")
+
+%def op_div_float_2addr():
+% fbinop2addr(instr="div.s f0, f0, f1")
+
+%def op_double_to_float():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ cvt.s.d f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_double_to_int():
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ trunc.w.d f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_double_to_long():
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ trunc.l.d f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_float_to_double():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ cvt.d.s f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_float_to_int():
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ trunc.w.s f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_float_to_long():
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ trunc.l.s f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_int_to_double():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ cvt.d.w f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_int_to_float():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ cvt.s.w f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_long_to_double():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ cvt.d.l f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_long_to_float():
+ /*
+ * Conversion from or to floating-point happens in a floating-point register.
+ * Therefore we load the input and store the output into or from a
+ * floating-point register irrespective of the type.
+ */
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ cvt.s.l f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_mul_double():
+% fbinopWide(instr="mul.d f0, f0, f1")
+
+%def op_mul_double_2addr():
+% fbinopWide2addr(instr="mul.d f0, f0, f1")
+
+%def op_mul_float():
+% fbinop(instr="mul.s f0, f0, f1")
+
+%def op_mul_float_2addr():
+% fbinop2addr(instr="mul.s f0, f0, f1")
+
+%def op_neg_double():
+% fcvtHeader(suffix="_DOUBLE", valreg="f0")
+ neg.d f0, f0
+% fcvtFooter(suffix="_DOUBLE", valreg="f0")
+
+%def op_neg_float():
+% fcvtHeader(suffix="_FLOAT", valreg="f0")
+ neg.s f0, f0
+% fcvtFooter(suffix="_FLOAT", valreg="f0")
+
+%def op_rem_double():
+ /* rem-double vAA, vBB, vCC */
+ .extern fmod
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_DOUBLE f12, a2 # f12 <- vBB
+ GET_VREG_DOUBLE f13, a3 # f13 <- vCC
+ jal fmod # f0 <- f12 op f13
+ srl a4, rINST, 8 # a4 <- AA
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a4 # vAA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_rem_double_2addr():
+ /* rem-double/2addr vA, vB */
+ .extern fmod
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_DOUBLE f12, a2 # f12 <- vA
+ GET_VREG_DOUBLE f13, a3 # f13 <- vB
+ jal fmod # f0 <- f12 op f13
+ ext a2, rINST, 8, 4 # a2 <- A
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a2 # vA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_rem_float():
+ /* rem-float vAA, vBB, vCC */
+ .extern fmodf
+ lbu a2, 2(rPC) # a2 <- BB
+ lbu a3, 3(rPC) # a3 <- CC
+ GET_VREG_FLOAT f12, a2 # f12 <- vBB
+ GET_VREG_FLOAT f13, a3 # f13 <- vCC
+ jal fmodf # f0 <- f12 op f13
+ srl a4, rINST, 8 # a4 <- AA
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a4 # vAA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_rem_float_2addr():
+ /* rem-float/2addr vA, vB */
+ .extern fmodf
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ GET_VREG_FLOAT f12, a2 # f12 <- vA
+ GET_VREG_FLOAT f13, a3 # f13 <- vB
+ jal fmodf # f0 <- f12 op f13
+ ext a2, rINST, 8, 4 # a2 <- A
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a2 # vA <- f0
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_sub_double():
+% fbinopWide(instr="sub.d f0, f0, f1")
+
+%def op_sub_double_2addr():
+% fbinopWide2addr(instr="sub.d f0, f0, f1")
+
+%def op_sub_float():
+% fbinop(instr="sub.s f0, f0, f1")
+
+%def op_sub_float_2addr():
+% fbinop2addr(instr="sub.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/footer.S b/runtime/interpreter/mterp/mips64/footer.S
deleted file mode 100644
index 5673151..0000000
--- a/runtime/interpreter/mterp/mips64/footer.S
+++ /dev/null
@@ -1,277 +0,0 @@
-%def footer():
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-
- .extern MterpLogDivideByZeroException
-common_errDivideByZero:
- EXPORT_PC
-#if MTERP_LOGGING
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- jal MterpLogDivideByZeroException
-#endif
- b MterpCommonFallback
-
- .extern MterpLogArrayIndexException
-common_errArrayIndex:
- EXPORT_PC
-#if MTERP_LOGGING
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- jal MterpLogArrayIndexException
-#endif
- b MterpCommonFallback
-
- .extern MterpLogNullObjectException
-common_errNullObject:
- EXPORT_PC
-#if MTERP_LOGGING
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- jal MterpLogNullObjectException
-#endif
- b MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- ld a0, THREAD_EXCEPTION_OFFSET(rSELF)
- beqzc a0, MterpFallback # If not, fall back to reference interpreter.
- /* intentional fallthrough - handle pending exception. */
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
- .extern MterpHandleException
- .extern MterpShouldSwitchInterpreters
-MterpException:
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- jal MterpHandleException # (self, shadow_frame)
- beqzc v0, MterpExceptionReturn # no local catch, back to caller.
- ld a0, OFF_FP_DEX_INSTRUCTIONS(rFP)
- lwu a1, OFF_FP_DEX_PC(rFP)
- REFRESH_IBASE
- dlsa rPC, a1, a0, 1 # generate new dex_pc_ptr
- /* Do we need to switch interpreters? */
- jal MterpShouldSwitchInterpreters
- bnezc v0, MterpFallback
- /* resume execution at catch block */
- EXPORT_PC
- FETCH_INST
- GET_INST_OPCODE v0
- GOTO_OPCODE v0
- /* NOTE: no fallthrough */
-
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * rINST <= signed offset
- * rPROFILE <= signed hotness countdown (expanded to 64 bits)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- *
- */
-MterpCommonTakenBranchNoFlags:
- bgtzc rINST, .L_forward_branch # don't add forward branches to hotness
-/*
- * We need to subtract 1 from positive values and we should not see 0 here,
- * so we may use the result of the comparison with -1.
- */
- li v0, JIT_CHECK_OSR
- beqc rPROFILE, v0, .L_osr_check
- bltc rPROFILE, v0, .L_resume_backward_branch
- dsubu rPROFILE, 1
- beqzc rPROFILE, .L_add_batch # counted down to zero - report
-.L_resume_backward_branch:
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- REFRESH_IBASE
- daddu a2, rINST, rINST # a2<- byte offset
- FETCH_ADVANCE_INST_RB a2 # update rPC, load rINST
- and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- bnezc ra, .L_suspend_request_pending
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
-
-.L_suspend_request_pending:
- EXPORT_PC
- move a0, rSELF
- jal MterpSuspendCheck # (self)
- bnezc v0, MterpFallback
- REFRESH_IBASE # might have changed during suspend
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
-
-.L_no_count_backwards:
- li v0, JIT_CHECK_OSR # check for possible OSR re-entry
- bnec rPROFILE, v0, .L_resume_backward_branch
-.L_osr_check:
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST
- EXPORT_PC
- jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
- bnezc v0, MterpOnStackReplacement
- b .L_resume_backward_branch
-
-.L_forward_branch:
- li v0, JIT_CHECK_OSR # check for possible OSR re-entry
- beqc rPROFILE, v0, .L_check_osr_forward
-.L_resume_forward_branch:
- daddu a2, rINST, rINST # a2<- byte offset
- FETCH_ADVANCE_INST_RB a2 # update rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
-
-.L_check_osr_forward:
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST
- EXPORT_PC
- jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
- bnezc v0, MterpOnStackReplacement
- b .L_resume_forward_branch
-
-.L_add_batch:
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
- ld a0, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpAddHotnessBatch # (method, shadow_frame, self)
- move rPROFILE, v0 # restore new hotness countdown to rPROFILE
- b .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- li a2, 2
- EXPORT_PC
- jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
- bnezc v0, MterpOnStackReplacement
- FETCH_ADVANCE_INST 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rINST # rINST contains offset
- jal MterpLogOSR
-#endif
- li v0, 1 # Signal normal return
- b MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
- .extern MterpLogFallback
-MterpFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- jal MterpLogFallback
-#endif
-MterpCommonFallback:
- li v0, 0 # signal retry with reference interpreter.
- b MterpDone
-
-/*
- * We pushed some registers on the stack in ExecuteMterpImpl, then saved
- * SP and RA. Here we restore SP, restore the registers, and then restore
- * RA to PC.
- *
- * On entry:
- * uint32_t* rFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- li v0, 1 # signal return to caller.
- b MterpDone
-/*
- * Returned value is expected in a0 and if it's not 64-bit, the 32 most
- * significant bits of a0 must be zero-extended or sign-extended
- * depending on the return type.
- */
-MterpReturn:
- ld a2, OFF_FP_RESULT_REGISTER(rFP)
- sd a0, 0(a2)
- li v0, 1 # signal return to caller.
-MterpDone:
-/*
- * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- blez rPROFILE, .L_pop_and_return # if > 0, we may have some counts to report.
-
-MterpProfileActive:
- move rINST, v0 # stash return value
- /* Report cached hotness counts */
- ld a0, OFF_FP_METHOD(rFP)
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rSELF
- sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
- jal MterpAddHotnessBatch # (method, shadow_frame, self)
- move v0, rINST # restore return value
-
-.L_pop_and_return:
- ld s6, STACK_OFFSET_S6(sp)
- .cfi_restore 22
- ld s5, STACK_OFFSET_S5(sp)
- .cfi_restore 21
- ld s4, STACK_OFFSET_S4(sp)
- .cfi_restore 20
- ld s3, STACK_OFFSET_S3(sp)
- .cfi_restore 19
- ld s2, STACK_OFFSET_S2(sp)
- .cfi_restore 18
- ld s1, STACK_OFFSET_S1(sp)
- .cfi_restore 17
- ld s0, STACK_OFFSET_S0(sp)
- .cfi_restore 16
-
- ld ra, STACK_OFFSET_RA(sp)
- .cfi_restore 31
-
- ld t8, STACK_OFFSET_GP(sp)
- .cpreturn
- .cfi_restore 28
-
- .set noreorder
- jr ra
- daddu sp, sp, STACK_SIZE
- .cfi_adjust_cfa_offset -STACK_SIZE
-
- .cfi_endproc
- .set reorder
- .size ExecuteMterpImpl, .-ExecuteMterpImpl
diff --git a/runtime/interpreter/mterp/mips64/header.S b/runtime/interpreter/mterp/mips64/header.S
deleted file mode 100644
index 42c7126..0000000
--- a/runtime/interpreter/mterp/mips64/header.S
+++ /dev/null
@@ -1,329 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define zero $$0 /* always zero */
-#define AT $$at /* assembler temp */
-#define v0 $$2 /* return value */
-#define v1 $$3
-#define a0 $$4 /* argument registers */
-#define a1 $$5
-#define a2 $$6
-#define a3 $$7
-#define a4 $$8 /* expanded register arguments */
-#define a5 $$9
-#define a6 $$10
-#define a7 $$11
-#define ta0 $$8 /* alias */
-#define ta1 $$9
-#define ta2 $$10
-#define ta3 $$11
-#define t0 $$12 /* temp registers (not saved across subroutine calls) */
-#define t1 $$13
-#define t2 $$14
-#define t3 $$15
-
-#define s0 $$16 /* saved across subroutine calls (callee saved) */
-#define s1 $$17
-#define s2 $$18
-#define s3 $$19
-#define s4 $$20
-#define s5 $$21
-#define s6 $$22
-#define s7 $$23
-#define t8 $$24 /* two more temp registers */
-#define t9 $$25
-#define k0 $$26 /* kernel temporary */
-#define k1 $$27
-#define gp $$28 /* global pointer */
-#define sp $$29 /* stack pointer */
-#define s8 $$30 /* one more callee saved */
-#define ra $$31 /* return address */
-
-#define f0 $$f0
-#define f1 $$f1
-#define f2 $$f2
-#define f3 $$f3
-#define f12 $$f12
-#define f13 $$f13
-
-/*
- * It looks like the GNU assembler currently does not support the blec and bgtc
- * idioms, which should translate into bgec and bltc respectively with swapped
- * left and right register operands.
- * TODO: remove these macros when the assembler is fixed.
- */
-.macro blec lreg, rreg, target
- bgec \rreg, \lreg, \target
-.endm
-.macro bgtc lreg, rreg, target
- bltc \rreg, \lreg, \target
-.endm
-
-/*
-Mterp and MIPS64 notes:
-
-The following registers have fixed assignments:
-
- reg nick purpose
- s0 rPC interpreted program counter, used for fetching instructions
- s1 rFP interpreted frame pointer, used for accessing locals and args
- s2 rSELF self (Thread) pointer
- s3 rINST first 16-bit code unit of current instruction
- s4 rIBASE interpreted instruction base pointer, used for computed goto
- s5 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
- s6 rPROFILE jit profile hotness countdown
-*/
-
-/* During bringup, we'll use the shadow frame model instead of rFP */
-/* single-purpose registers, given names for clarity */
-#define rPC s0
-#define CFI_DEX 16 // DWARF register number of the register holding dex-pc (s0).
-#define CFI_TMP 4 // DWARF register number of the first argument register (a0).
-#define rFP s1
-#define rSELF s2
-#define rINST s3
-#define rIBASE s4
-#define rREFS s5
-#define rPROFILE s6
-
-/*
- * This is a #include, not a %include, because we want the C pre-processor
- * to expand the macros into assembler assignment statements.
- */
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_SHADOWFRAME OFF_FP(0)
-
-#define MTERP_PROFILE_BRANCHES 1
-#define MTERP_LOGGING 0
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-.macro EXPORT_PC
- sd rPC, OFF_FP_DEX_PC_PTR(rFP)
-.endm
-
-/*
- * Refresh handler table.
- */
-.macro REFRESH_IBASE
- ld rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
-.endm
-
-/*
- * Fetch the next instruction from rPC into rINST. Does not advance rPC.
- */
-.macro FETCH_INST
- lhu rINST, 0(rPC)
-.endm
-
-/* Advance rPC by some number of code units. */
-.macro ADVANCE count
- daddu rPC, rPC, (\count) * 2
-.endm
-
-/*
- * Fetch the next instruction from an offset specified by _reg and advance xPC.
- * xPC to point to the next instruction. "_reg" must specify the distance
- * in bytes, *not* 16-bit code units, and may be a signed value. Must not set flags.
- *
- */
-.macro FETCH_ADVANCE_INST_RB reg
- daddu rPC, rPC, \reg
- FETCH_INST
-.endm
-
-/*
- * Fetch the next instruction from the specified offset. Advances rPC
- * to point to the next instruction.
- *
- * This must come AFTER anything that can throw an exception, or the
- * exception catch may miss. (This also implies that it must come after
- * EXPORT_PC.)
- */
-.macro FETCH_ADVANCE_INST count
- ADVANCE \count
- FETCH_INST
-.endm
-
-/*
- * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
- * rINST ahead of possible exception point. Be sure to manually advance rPC
- * later.
- */
-.macro PREFETCH_INST count
- lhu rINST, ((\count) * 2)(rPC)
-.endm
-
-/*
- * Put the instruction's opcode field into the specified register.
- */
-.macro GET_INST_OPCODE reg
- and \reg, rINST, 255
-.endm
-
-/*
- * Begin executing the opcode in _reg.
- */
-.macro GOTO_OPCODE reg
- .set noat
- sll AT, \reg, 7
- daddu AT, rIBASE, AT
- jic AT, 0
- .set at
-.endm
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- * Note, GET_VREG does sign extension to 64 bits while
- * GET_VREG_U does zero extension to 64 bits.
- * One is useful for arithmetic while the other is
- * useful for storing the result value as 64-bit.
- */
-.macro GET_VREG reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- lw \reg, 0(AT)
- .set at
-.endm
-.macro GET_VREG_U reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- lwu \reg, 0(AT)
- .set at
-.endm
-.macro GET_VREG_FLOAT reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- lwc1 \reg, 0(AT)
- .set at
-.endm
-.macro SET_VREG reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- sw \reg, 0(AT)
- dlsa AT, \vreg, rREFS, 2
- sw zero, 0(AT)
- .set at
-.endm
-.macro SET_VREG_OBJECT reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- sw \reg, 0(AT)
- dlsa AT, \vreg, rREFS, 2
- sw \reg, 0(AT)
- .set at
-.endm
-.macro SET_VREG_FLOAT reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- swc1 \reg, 0(AT)
- dlsa AT, \vreg, rREFS, 2
- sw zero, 0(AT)
- .set at
-.endm
-
-/*
- * Get/set the 64-bit value from a Dalvik register.
- * Avoid unaligned memory accesses.
- * Note, SET_VREG_WIDE clobbers the register containing the value being stored.
- * Note, SET_VREG_DOUBLE clobbers the register containing the Dalvik register number.
- */
-.macro GET_VREG_WIDE reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- lw \reg, 0(AT)
- lw AT, 4(AT)
- dinsu \reg, AT, 32, 32
- .set at
-.endm
-.macro GET_VREG_DOUBLE reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- lwc1 \reg, 0(AT)
- lw AT, 4(AT)
- mthc1 AT, \reg
- .set at
-.endm
-.macro SET_VREG_WIDE reg, vreg
- .set noat
- dlsa AT, \vreg, rFP, 2
- sw \reg, 0(AT)
- drotr32 \reg, \reg, 0
- sw \reg, 4(AT)
- dlsa AT, \vreg, rREFS, 2
- sw zero, 0(AT)
- sw zero, 4(AT)
- .set at
-.endm
-.macro SET_VREG_DOUBLE reg, vreg
- .set noat
- dlsa AT, \vreg, rREFS, 2
- sw zero, 0(AT)
- sw zero, 4(AT)
- dlsa AT, \vreg, rFP, 2
- swc1 \reg, 0(AT)
- mfhc1 \vreg, \reg
- sw \vreg, 4(AT)
- .set at
-.endm
-
-/*
- * On-stack offsets for spilling/unspilling callee-saved registers
- * and the frame size.
- */
-#define STACK_OFFSET_RA 0
-#define STACK_OFFSET_GP 8
-#define STACK_OFFSET_S0 16
-#define STACK_OFFSET_S1 24
-#define STACK_OFFSET_S2 32
-#define STACK_OFFSET_S3 40
-#define STACK_OFFSET_S4 48
-#define STACK_OFFSET_S5 56
-#define STACK_OFFSET_S6 64
-#define STACK_SIZE 80 /* needs 16 byte alignment */
-
-/* Constants for float/double_to_int/long conversions */
-#define INT_MIN 0x80000000
-#define INT_MIN_AS_FLOAT 0xCF000000
-#define INT_MIN_AS_DOUBLE 0xC1E0000000000000
-#define LONG_MIN 0x8000000000000000
-#define LONG_MIN_AS_FLOAT 0xDF000000
-#define LONG_MIN_AS_DOUBLE 0xC3E0000000000000
diff --git a/runtime/interpreter/mterp/mips64/instruction_end.S b/runtime/interpreter/mterp/mips64/instruction_end.S
deleted file mode 100644
index 3d44293..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_end.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end():
-
- .global artMterpAsmInstructionEnd
-artMterpAsmInstructionEnd:
diff --git a/runtime/interpreter/mterp/mips64/instruction_end_alt.S b/runtime/interpreter/mterp/mips64/instruction_end_alt.S
deleted file mode 100644
index 86a1068..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_end_alt.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end_alt():
-
- .global artMterpAsmAltInstructionEnd
-artMterpAsmAltInstructionEnd:
diff --git a/runtime/interpreter/mterp/mips64/instruction_end_sister.S b/runtime/interpreter/mterp/mips64/instruction_end_sister.S
deleted file mode 100644
index 8cc4513..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_end_sister.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def instruction_end_sister():
-
- .global artMterpAsmSisterEnd
-artMterpAsmSisterEnd:
diff --git a/runtime/interpreter/mterp/mips64/instruction_start.S b/runtime/interpreter/mterp/mips64/instruction_start.S
deleted file mode 100644
index 4b777f2..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_start.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def instruction_start():
-
- .global artMterpAsmInstructionStart
-artMterpAsmInstructionStart = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/mips64/instruction_start_alt.S b/runtime/interpreter/mterp/mips64/instruction_start_alt.S
deleted file mode 100644
index e7731b7..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_start_alt.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def instruction_start_alt():
-
- .global artMterpAsmAltInstructionStart
-artMterpAsmAltInstructionStart = .L_ALT_op_nop
- .text
diff --git a/runtime/interpreter/mterp/mips64/instruction_start_sister.S b/runtime/interpreter/mterp/mips64/instruction_start_sister.S
deleted file mode 100644
index e09ea90..0000000
--- a/runtime/interpreter/mterp/mips64/instruction_start_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_start_sister():
-
- .global artMterpAsmSisterStart
- .text
- .balign 4
-artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/mips64/invoke.S b/runtime/interpreter/mterp/mips64/invoke.S
index caf5698..c2967cf 100644
--- a/runtime/interpreter/mterp/mips64/invoke.S
+++ b/runtime/interpreter/mterp/mips64/invoke.S
@@ -18,3 +18,93 @@
bnezc v0, MterpFallback
GET_INST_OPCODE v0
GOTO_OPCODE v0
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ .extern MterpShouldSwitchInterpreters
+ EXPORT_PC
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rPC
+ move a3, rINST
+ jal $helper
+ beqzc v0, MterpException
+ FETCH_ADVANCE_INST 4
+ jal MterpShouldSwitchInterpreters
+ bnezc v0, MterpFallback
+ GET_INST_OPCODE v0
+ GOTO_OPCODE v0
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+ /*
+ * Handle an interface method call.
+ *
+ * for: invoke-interface, invoke-interface/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+ /*
+ * Handle a "super" method call.
+ *
+ * for: invoke-super, invoke-super/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+ /*
+ * Handle a virtual method call.
+ *
+ * for: invoke-virtual, invoke-virtual/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/mips64/invoke_polymorphic.S b/runtime/interpreter/mterp/mips64/invoke_polymorphic.S
deleted file mode 100644
index 3a10554..0000000
--- a/runtime/interpreter/mterp/mips64/invoke_polymorphic.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- .extern MterpShouldSwitchInterpreters
- EXPORT_PC
- move a0, rSELF
- daddu a1, rFP, OFF_FP_SHADOWFRAME
- move a2, rPC
- move a3, rINST
- jal $helper
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 4
- jal MterpShouldSwitchInterpreters
- bnezc v0, MterpFallback
- GET_INST_OPCODE v0
- GOTO_OPCODE v0
diff --git a/runtime/interpreter/mterp/mips64/main.S b/runtime/interpreter/mterp/mips64/main.S
new file mode 100644
index 0000000..c2c305a
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/main.S
@@ -0,0 +1,757 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define zero $$0 /* always zero */
+#define AT $$at /* assembler temp */
+#define v0 $$2 /* return value */
+#define v1 $$3
+#define a0 $$4 /* argument registers */
+#define a1 $$5
+#define a2 $$6
+#define a3 $$7
+#define a4 $$8 /* expanded register arguments */
+#define a5 $$9
+#define a6 $$10
+#define a7 $$11
+#define ta0 $$8 /* alias */
+#define ta1 $$9
+#define ta2 $$10
+#define ta3 $$11
+#define t0 $$12 /* temp registers (not saved across subroutine calls) */
+#define t1 $$13
+#define t2 $$14
+#define t3 $$15
+
+#define s0 $$16 /* saved across subroutine calls (callee saved) */
+#define s1 $$17
+#define s2 $$18
+#define s3 $$19
+#define s4 $$20
+#define s5 $$21
+#define s6 $$22
+#define s7 $$23
+#define t8 $$24 /* two more temp registers */
+#define t9 $$25
+#define k0 $$26 /* kernel temporary */
+#define k1 $$27
+#define gp $$28 /* global pointer */
+#define sp $$29 /* stack pointer */
+#define s8 $$30 /* one more callee saved */
+#define ra $$31 /* return address */
+
+#define f0 $$f0
+#define f1 $$f1
+#define f2 $$f2
+#define f3 $$f3
+#define f12 $$f12
+#define f13 $$f13
+
+/*
+ * It looks like the GNU assembler currently does not support the blec and bgtc
+ * idioms, which should translate into bgec and bltc respectively with swapped
+ * left and right register operands.
+ * TODO: remove these macros when the assembler is fixed.
+ */
+.macro blec lreg, rreg, target
+ bgec \rreg, \lreg, \target
+.endm
+.macro bgtc lreg, rreg, target
+ bltc \rreg, \lreg, \target
+.endm
+
+/*
+Mterp and MIPS64 notes:
+
+The following registers have fixed assignments:
+
+ reg nick purpose
+ s0 rPC interpreted program counter, used for fetching instructions
+ s1 rFP interpreted frame pointer, used for accessing locals and args
+ s2 rSELF self (Thread) pointer
+ s3 rINST first 16-bit code unit of current instruction
+ s4 rIBASE interpreted instruction base pointer, used for computed goto
+ s5 rREFS base of object references in shadow frame (ideally, we'll get rid of this later).
+ s6 rPROFILE jit profile hotness countdown
+*/
+
+/* During bringup, we'll use the shadow frame model instead of rFP */
+/* single-purpose registers, given names for clarity */
+#define rPC s0
+#define CFI_DEX 16 // DWARF register number of the register holding dex-pc (s0).
+#define CFI_TMP 4 // DWARF register number of the first argument register (a0).
+#define rFP s1
+#define rSELF s2
+#define rINST s3
+#define rIBASE s4
+#define rREFS s5
+#define rPROFILE s6
+
+/*
+ * This is a #include, not a %include, because we want the C pre-processor
+ * to expand the macros into assembler assignment statements.
+ */
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_SHADOWFRAME OFF_FP(0)
+
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+.macro EXPORT_PC
+ sd rPC, OFF_FP_DEX_PC_PTR(rFP)
+.endm
+
+/*
+ * Refresh handler table.
+ */
+.macro REFRESH_IBASE
+ ld rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
+.endm
+
+/*
+ * Fetch the next instruction from rPC into rINST. Does not advance rPC.
+ */
+.macro FETCH_INST
+ lhu rINST, 0(rPC)
+.endm
+
+/* Advance rPC by some number of code units. */
+.macro ADVANCE count
+ daddu rPC, rPC, (\count) * 2
+.endm
+
+/*
+ * Fetch the next instruction from an offset specified by _reg and advance xPC.
+ * xPC to point to the next instruction. "_reg" must specify the distance
+ * in bytes, *not* 16-bit code units, and may be a signed value. Must not set flags.
+ *
+ */
+.macro FETCH_ADVANCE_INST_RB reg
+ daddu rPC, rPC, \reg
+ FETCH_INST
+.endm
+
+/*
+ * Fetch the next instruction from the specified offset. Advances rPC
+ * to point to the next instruction.
+ *
+ * This must come AFTER anything that can throw an exception, or the
+ * exception catch may miss. (This also implies that it must come after
+ * EXPORT_PC.)
+ */
+.macro FETCH_ADVANCE_INST count
+ ADVANCE \count
+ FETCH_INST
+.endm
+
+/*
+ * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load
+ * rINST ahead of possible exception point. Be sure to manually advance rPC
+ * later.
+ */
+.macro PREFETCH_INST count
+ lhu rINST, ((\count) * 2)(rPC)
+.endm
+
+/*
+ * Put the instruction's opcode field into the specified register.
+ */
+.macro GET_INST_OPCODE reg
+ and \reg, rINST, 255
+.endm
+
+/*
+ * Begin executing the opcode in _reg.
+ */
+.macro GOTO_OPCODE reg
+ .set noat
+ sll AT, \reg, 7
+ daddu AT, rIBASE, AT
+ jic AT, 0
+ .set at
+.endm
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ * Note, GET_VREG does sign extension to 64 bits while
+ * GET_VREG_U does zero extension to 64 bits.
+ * One is useful for arithmetic while the other is
+ * useful for storing the result value as 64-bit.
+ */
+.macro GET_VREG reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ lw \reg, 0(AT)
+ .set at
+.endm
+.macro GET_VREG_U reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ lwu \reg, 0(AT)
+ .set at
+.endm
+.macro GET_VREG_FLOAT reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ lwc1 \reg, 0(AT)
+ .set at
+.endm
+.macro SET_VREG reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ sw \reg, 0(AT)
+ dlsa AT, \vreg, rREFS, 2
+ sw zero, 0(AT)
+ .set at
+.endm
+.macro SET_VREG_OBJECT reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ sw \reg, 0(AT)
+ dlsa AT, \vreg, rREFS, 2
+ sw \reg, 0(AT)
+ .set at
+.endm
+.macro SET_VREG_FLOAT reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ swc1 \reg, 0(AT)
+ dlsa AT, \vreg, rREFS, 2
+ sw zero, 0(AT)
+ .set at
+.endm
+
+/*
+ * Get/set the 64-bit value from a Dalvik register.
+ * Avoid unaligned memory accesses.
+ * Note, SET_VREG_WIDE clobbers the register containing the value being stored.
+ * Note, SET_VREG_DOUBLE clobbers the register containing the Dalvik register number.
+ */
+.macro GET_VREG_WIDE reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ lw \reg, 0(AT)
+ lw AT, 4(AT)
+ dinsu \reg, AT, 32, 32
+ .set at
+.endm
+.macro GET_VREG_DOUBLE reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ lwc1 \reg, 0(AT)
+ lw AT, 4(AT)
+ mthc1 AT, \reg
+ .set at
+.endm
+.macro SET_VREG_WIDE reg, vreg
+ .set noat
+ dlsa AT, \vreg, rFP, 2
+ sw \reg, 0(AT)
+ drotr32 \reg, \reg, 0
+ sw \reg, 4(AT)
+ dlsa AT, \vreg, rREFS, 2
+ sw zero, 0(AT)
+ sw zero, 4(AT)
+ .set at
+.endm
+.macro SET_VREG_DOUBLE reg, vreg
+ .set noat
+ dlsa AT, \vreg, rREFS, 2
+ sw zero, 0(AT)
+ sw zero, 4(AT)
+ dlsa AT, \vreg, rFP, 2
+ swc1 \reg, 0(AT)
+ mfhc1 \vreg, \reg
+ sw \vreg, 4(AT)
+ .set at
+.endm
+
+/*
+ * On-stack offsets for spilling/unspilling callee-saved registers
+ * and the frame size.
+ */
+#define STACK_OFFSET_RA 0
+#define STACK_OFFSET_GP 8
+#define STACK_OFFSET_S0 16
+#define STACK_OFFSET_S1 24
+#define STACK_OFFSET_S2 32
+#define STACK_OFFSET_S3 40
+#define STACK_OFFSET_S4 48
+#define STACK_OFFSET_S5 56
+#define STACK_OFFSET_S6 64
+#define STACK_SIZE 80 /* needs 16 byte alignment */
+
+/* Constants for float/double_to_int/long conversions */
+#define INT_MIN 0x80000000
+#define INT_MIN_AS_FLOAT 0xCF000000
+#define INT_MIN_AS_DOUBLE 0xC1E0000000000000
+#define LONG_MIN 0x8000000000000000
+#define LONG_MIN_AS_FLOAT 0xDF000000
+#define LONG_MIN_AS_DOUBLE 0xC3E0000000000000
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Interpreter entry point.
+ */
+
+ .set reorder
+
+ .text
+ .global ExecuteMterpImpl
+ .type ExecuteMterpImpl, %function
+ .balign 16
+/*
+ * On entry:
+ * a0 Thread* self
+ * a1 dex_instructions
+ * a2 ShadowFrame
+ * a3 JValue* result_register
+ *
+ */
+ExecuteMterpImpl:
+ .cfi_startproc
+ .cpsetup t9, t8, ExecuteMterpImpl
+
+ .cfi_def_cfa sp, 0
+ daddu sp, sp, -STACK_SIZE
+ .cfi_adjust_cfa_offset STACK_SIZE
+
+ sd t8, STACK_OFFSET_GP(sp)
+ .cfi_rel_offset 28, STACK_OFFSET_GP
+ sd ra, STACK_OFFSET_RA(sp)
+ .cfi_rel_offset 31, STACK_OFFSET_RA
+
+ sd s0, STACK_OFFSET_S0(sp)
+ .cfi_rel_offset 16, STACK_OFFSET_S0
+ sd s1, STACK_OFFSET_S1(sp)
+ .cfi_rel_offset 17, STACK_OFFSET_S1
+ sd s2, STACK_OFFSET_S2(sp)
+ .cfi_rel_offset 18, STACK_OFFSET_S2
+ sd s3, STACK_OFFSET_S3(sp)
+ .cfi_rel_offset 19, STACK_OFFSET_S3
+ sd s4, STACK_OFFSET_S4(sp)
+ .cfi_rel_offset 20, STACK_OFFSET_S4
+ sd s5, STACK_OFFSET_S5(sp)
+ .cfi_rel_offset 21, STACK_OFFSET_S5
+ sd s6, STACK_OFFSET_S6(sp)
+ .cfi_rel_offset 22, STACK_OFFSET_S6
+
+ /* Remember the return register */
+ sd a3, SHADOWFRAME_RESULT_REGISTER_OFFSET(a2)
+
+ /* Remember the dex instruction pointer */
+ sd a1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(a2)
+
+ /* set up "named" registers */
+ move rSELF, a0
+ daddu rFP, a2, SHADOWFRAME_VREGS_OFFSET
+ lw v0, SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(a2)
+ dlsa rREFS, v0, rFP, 2
+ lw v0, SHADOWFRAME_DEX_PC_OFFSET(a2)
+ dlsa rPC, v0, a1, 1
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+ EXPORT_PC
+
+ /* Starting ibase */
+ REFRESH_IBASE
+
+ /* Set up for backwards branches & osr profiling */
+ ld a0, OFF_FP_METHOD(rFP)
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rSELF
+ jal MterpSetUpHotnessCountdown
+ move rPROFILE, v0 # Starting hotness countdown to rPROFILE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST
+ GET_INST_OPCODE v0
+ GOTO_OPCODE v0
+
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Note that the call to MterpCheckBefore is done as a tail call.
+ */
+ .extern MterpCheckBefore
+ REFRESH_IBASE
+ dla ra, artMterpAsmInstructionStart
+ dla t9, MterpCheckBefore
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rPC
+ daddu ra, ra, (${opnum} * 128) # Addr of primary handler.
+ jalr zero, t9 # (self, shadow_frame, dex_pc_ptr) Note: tail call.
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ b MterpFallback
+
+%def footer():
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+
+ .extern MterpLogDivideByZeroException
+common_errDivideByZero:
+ EXPORT_PC
+#if MTERP_LOGGING
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ jal MterpLogDivideByZeroException
+#endif
+ b MterpCommonFallback
+
+ .extern MterpLogArrayIndexException
+common_errArrayIndex:
+ EXPORT_PC
+#if MTERP_LOGGING
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ jal MterpLogArrayIndexException
+#endif
+ b MterpCommonFallback
+
+ .extern MterpLogNullObjectException
+common_errNullObject:
+ EXPORT_PC
+#if MTERP_LOGGING
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ jal MterpLogNullObjectException
+#endif
+ b MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ ld a0, THREAD_EXCEPTION_OFFSET(rSELF)
+ beqzc a0, MterpFallback # If not, fall back to reference interpreter.
+ /* intentional fallthrough - handle pending exception. */
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+ .extern MterpHandleException
+ .extern MterpShouldSwitchInterpreters
+MterpException:
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ jal MterpHandleException # (self, shadow_frame)
+ beqzc v0, MterpExceptionReturn # no local catch, back to caller.
+ ld a0, OFF_FP_DEX_INSTRUCTIONS(rFP)
+ lwu a1, OFF_FP_DEX_PC(rFP)
+ REFRESH_IBASE
+ dlsa rPC, a1, a0, 1 # generate new dex_pc_ptr
+ /* Do we need to switch interpreters? */
+ jal MterpShouldSwitchInterpreters
+ bnezc v0, MterpFallback
+ /* resume execution at catch block */
+ EXPORT_PC
+ FETCH_INST
+ GET_INST_OPCODE v0
+ GOTO_OPCODE v0
+ /* NOTE: no fallthrough */
+
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * rINST <= signed offset
+ * rPROFILE <= signed hotness countdown (expanded to 64 bits)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ *
+ */
+MterpCommonTakenBranchNoFlags:
+ bgtzc rINST, .L_forward_branch # don't add forward branches to hotness
+/*
+ * We need to subtract 1 from positive values and we should not see 0 here,
+ * so we may use the result of the comparison with -1.
+ */
+ li v0, JIT_CHECK_OSR
+ beqc rPROFILE, v0, .L_osr_check
+ bltc rPROFILE, v0, .L_resume_backward_branch
+ dsubu rPROFILE, 1
+ beqzc rPROFILE, .L_add_batch # counted down to zero - report
+.L_resume_backward_branch:
+ lw ra, THREAD_FLAGS_OFFSET(rSELF)
+ REFRESH_IBASE
+ daddu a2, rINST, rINST # a2<- byte offset
+ FETCH_ADVANCE_INST_RB a2 # update rPC, load rINST
+ and ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
+ bnezc ra, .L_suspend_request_pending
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+.L_suspend_request_pending:
+ EXPORT_PC
+ move a0, rSELF
+ jal MterpSuspendCheck # (self)
+ bnezc v0, MterpFallback
+ REFRESH_IBASE # might have changed during suspend
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+.L_no_count_backwards:
+ li v0, JIT_CHECK_OSR # check for possible OSR re-entry
+ bnec rPROFILE, v0, .L_resume_backward_branch
+.L_osr_check:
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST
+ EXPORT_PC
+ jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
+ bnezc v0, MterpOnStackReplacement
+ b .L_resume_backward_branch
+
+.L_forward_branch:
+ li v0, JIT_CHECK_OSR # check for possible OSR re-entry
+ beqc rPROFILE, v0, .L_check_osr_forward
+.L_resume_forward_branch:
+ daddu a2, rINST, rINST # a2<- byte offset
+ FETCH_ADVANCE_INST_RB a2 # update rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+.L_check_osr_forward:
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST
+ EXPORT_PC
+ jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
+ bnezc v0, MterpOnStackReplacement
+ b .L_resume_forward_branch
+
+.L_add_batch:
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
+ ld a0, OFF_FP_METHOD(rFP)
+ move a2, rSELF
+ jal MterpAddHotnessBatch # (method, shadow_frame, self)
+ move rPROFILE, v0 # restore new hotness countdown to rPROFILE
+ b .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ li a2, 2
+ EXPORT_PC
+ jal MterpMaybeDoOnStackReplacement # (self, shadow_frame, offset)
+ bnezc v0, MterpOnStackReplacement
+ FETCH_ADVANCE_INST 2
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rINST # rINST contains offset
+ jal MterpLogOSR
+#endif
+ li v0, 1 # Signal normal return
+ b MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+ .extern MterpLogFallback
+MterpFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ move a0, rSELF
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ jal MterpLogFallback
+#endif
+MterpCommonFallback:
+ li v0, 0 # signal retry with reference interpreter.
+ b MterpDone
+
+/*
+ * We pushed some registers on the stack in ExecuteMterpImpl, then saved
+ * SP and RA. Here we restore SP, restore the registers, and then restore
+ * RA to PC.
+ *
+ * On entry:
+ * uint32_t* rFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ li v0, 1 # signal return to caller.
+ b MterpDone
+/*
+ * Returned value is expected in a0 and if it's not 64-bit, the 32 most
+ * significant bits of a0 must be zero-extended or sign-extended
+ * depending on the return type.
+ */
+MterpReturn:
+ ld a2, OFF_FP_RESULT_REGISTER(rFP)
+ sd a0, 0(a2)
+ li v0, 1 # signal return to caller.
+MterpDone:
+/*
+ * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ blez rPROFILE, .L_pop_and_return # if > 0, we may have some counts to report.
+
+MterpProfileActive:
+ move rINST, v0 # stash return value
+ /* Report cached hotness counts */
+ ld a0, OFF_FP_METHOD(rFP)
+ daddu a1, rFP, OFF_FP_SHADOWFRAME
+ move a2, rSELF
+ sh rPROFILE, SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET(a1)
+ jal MterpAddHotnessBatch # (method, shadow_frame, self)
+ move v0, rINST # restore return value
+
+.L_pop_and_return:
+ ld s6, STACK_OFFSET_S6(sp)
+ .cfi_restore 22
+ ld s5, STACK_OFFSET_S5(sp)
+ .cfi_restore 21
+ ld s4, STACK_OFFSET_S4(sp)
+ .cfi_restore 20
+ ld s3, STACK_OFFSET_S3(sp)
+ .cfi_restore 19
+ ld s2, STACK_OFFSET_S2(sp)
+ .cfi_restore 18
+ ld s1, STACK_OFFSET_S1(sp)
+ .cfi_restore 17
+ ld s0, STACK_OFFSET_S0(sp)
+ .cfi_restore 16
+
+ ld ra, STACK_OFFSET_RA(sp)
+ .cfi_restore 31
+
+ ld t8, STACK_OFFSET_GP(sp)
+ .cpreturn
+ .cfi_restore 28
+
+ .set noreorder
+ jr ra
+ daddu sp, sp, STACK_SIZE
+ .cfi_adjust_cfa_offset -STACK_SIZE
+
+ .cfi_endproc
+ .set reorder
+ .size ExecuteMterpImpl, .-ExecuteMterpImpl
+
+%def instruction_end():
+
+ .global artMterpAsmInstructionEnd
+artMterpAsmInstructionEnd:
+
+%def instruction_end_alt():
+
+ .global artMterpAsmAltInstructionEnd
+artMterpAsmAltInstructionEnd:
+
+%def instruction_end_sister():
+
+ .global artMterpAsmSisterEnd
+artMterpAsmSisterEnd:
+
+%def instruction_start():
+
+ .global artMterpAsmInstructionStart
+artMterpAsmInstructionStart = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ .global artMterpAsmAltInstructionStart
+artMterpAsmAltInstructionStart = .L_ALT_op_nop
+ .text
+
+%def instruction_start_sister():
+
+ .global artMterpAsmSisterStart
+ .text
+ .balign 4
+artMterpAsmSisterStart:
diff --git a/runtime/interpreter/mterp/mips64/object.S b/runtime/interpreter/mterp/mips64/object.S
new file mode 100644
index 0000000..a5a2b3d
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/object.S
@@ -0,0 +1,262 @@
+%def field(helper=""):
+TODO
+
+%def op_check_cast():
+ /*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class//BBBB */
+ .extern MterpCheckCast
+ EXPORT_PC
+ lhu a0, 2(rPC) # a0 <- BBBB
+ srl a1, rINST, 8 # a1 <- AA
+ dlsa a1, a1, rFP, 2 # a1 <- &object
+ ld a2, OFF_FP_METHOD(rFP) # a2 <- method
+ move a3, rSELF # a3 <- self
+ jal MterpCheckCast # (index, &obj, method, self)
+ PREFETCH_INST 2
+ bnez v0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="lbu")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="lb")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="lhu")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset//CCCC */
+ .extern artIGetObjectFromMterp
+ srl a2, rINST, 12 # a2 <- B
+ lhu a1, 2(rPC) # a1 <- field byte offset
+ EXPORT_PC
+ GET_VREG_U a0, a2 # a0 <- object we're operating on
+ jal artIGetObjectFromMterp # (obj, offset)
+ ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
+ ext a2, rINST, 8, 4 # a2 <- A
+ PREFETCH_INST 2
+ bnez a3, MterpPossibleException # bail out
+ SET_VREG_OBJECT v0, a2 # fp[A] <- v0
+ ADVANCE 2 # advance rPC
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iget_quick(load="lw"):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
+ /* op vA, vB, offset//CCCC */
+ srl a2, rINST, 12 # a2 <- B
+ lhu a1, 2(rPC) # a1 <- field byte offset
+ GET_VREG_U a3, a2 # a3 <- object we're operating on
+ ext a4, rINST, 8, 4 # a4 <- A
+ daddu a1, a1, a3
+ beqz a3, common_errNullObject # object was null
+ $load a0, 0(a1) # a0 <- obj.field
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ SET_VREG a0, a4 # fp[A] <- a0
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="lh")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+ /* iget-wide-quick vA, vB, offset//CCCC */
+ srl a2, rINST, 12 # a2 <- B
+ lhu a4, 2(rPC) # a4 <- field byte offset
+ GET_VREG_U a3, a2 # a3 <- object we're operating on
+ ext a2, rINST, 8, 4 # a2 <- A
+ beqz a3, common_errNullObject # object was null
+ daddu a4, a3, a4 # create direct pointer
+ lw a0, 0(a4)
+ lw a1, 4(a4)
+ dinsu a0, a1, 32, 32
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ SET_VREG_WIDE a0, a2
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_instance_of():
+ /*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class//CCCC */
+ .extern MterpInstanceOf
+ EXPORT_PC
+ lhu a0, 2(rPC) # a0 <- CCCC
+ srl a1, rINST, 12 # a1 <- B
+ dlsa a1, a1, rFP, 2 # a1 <- &object
+ ld a2, OFF_FP_METHOD(rFP) # a2 <- method
+ move a3, rSELF # a3 <- self
+ jal MterpInstanceOf # (index, &obj, method, self)
+ ld a1, THREAD_EXCEPTION_OFFSET(rSELF)
+ ext a2, rINST, 8, 4 # a2 <- A
+ PREFETCH_INST 2
+ bnez a1, MterpException
+ ADVANCE 2 # advance rPC
+ SET_VREG v0, a2 # vA <- v0
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(store="sb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(store="sb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(store="sh")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ .extern MterpIputObjectQuick
+ EXPORT_PC
+ daddu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rPC
+ move a2, rINST
+ jal MterpIputObjectQuick
+ beqzc v0, MterpException
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iput_quick(store="sw"):
+ /* For: iput-quick, iput-boolean-quick, iput-byte-quick, iput-char-quick, iput-short-quick */
+ /* op vA, vB, offset//CCCC */
+ srl a2, rINST, 12 # a2 <- B
+ lhu a1, 2(rPC) # a1 <- field byte offset
+ GET_VREG_U a3, a2 # a3 <- fp[B], the object pointer
+ ext a2, rINST, 8, 4 # a2 <- A
+ beqz a3, common_errNullObject # object was null
+ GET_VREG a0, a2 # a0 <- fp[A]
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ daddu a1, a1, a3
+ $store a0, 0(a1) # obj.field <- a0
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(store="sh")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset//CCCC */
+ srl a2, rINST, 12 # a2 <- B
+ lhu a3, 2(rPC) # a3 <- field byte offset
+ GET_VREG_U a2, a2 # a2 <- fp[B], the object pointer
+ ext a0, rINST, 8, 4 # a0 <- A
+ beqz a2, common_errNullObject # object was null
+ GET_VREG_WIDE a0, a0 # a0 <- fp[A]
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ daddu a1, a2, a3 # create a direct pointer
+ sw a0, 0(a1)
+ dsrl32 a0, a0, 0
+ sw a0, 4(a1)
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_new_instance():
+ /*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class//BBBB */
+ .extern MterpNewInstance
+ EXPORT_PC
+ daddu a0, rFP, OFF_FP_SHADOWFRAME
+ move a1, rSELF
+ move a2, rINST
+ jal MterpNewInstance # (shadow_frame, self, inst_data)
+ beqzc v0, MterpPossibleException
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/mips64/op_add_double.S b/runtime/interpreter/mterp/mips64/op_add_double.S
deleted file mode 100644
index 0c1f6a2..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% fbinopWide(instr="add.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_double_2addr.S b/runtime/interpreter/mterp/mips64/op_add_double_2addr.S
deleted file mode 100644
index f667996..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% fbinopWide2addr(instr="add.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_float.S b/runtime/interpreter/mterp/mips64/op_add_float.S
deleted file mode 100644
index 4c0f88c..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% fbinop(instr="add.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_float_2addr.S b/runtime/interpreter/mterp/mips64/op_add_float_2addr.S
deleted file mode 100644
index 0bcc91a..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% fbinop2addr(instr="add.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_int.S b/runtime/interpreter/mterp/mips64/op_add_int.S
deleted file mode 100644
index ed0fc01..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_int_2addr.S b/runtime/interpreter/mterp/mips64/op_add_int_2addr.S
deleted file mode 100644
index ed0b131..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_int_lit16.S b/runtime/interpreter/mterp/mips64/op_add_int_lit16.S
deleted file mode 100644
index 126807a..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_int_lit8.S b/runtime/interpreter/mterp/mips64/op_add_int_lit8.S
deleted file mode 100644
index 30184c4..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(instr="addu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_long.S b/runtime/interpreter/mterp/mips64/op_add_long.S
deleted file mode 100644
index 72a1f24..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long():
-% binopWide(instr="daddu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_add_long_2addr.S b/runtime/interpreter/mterp/mips64/op_add_long_2addr.S
deleted file mode 100644
index caf29e2..0000000
--- a/runtime/interpreter/mterp/mips64/op_add_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long_2addr():
-% binopWide2addr(instr="daddu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_aget.S b/runtime/interpreter/mterp/mips64/op_aget.S
deleted file mode 100644
index 60be23d..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short
- *
- * NOTE: assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- srl a4, rINST, 8 # a4 <- AA
- GET_VREG_U a0, a2 # a0 <- vBB (array object)
- GET_VREG a1, a3 # a1 <- vCC (requested index)
- beqz a0, common_errNullObject # bail if null array object
- lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
- .if $shift
- # [d]lsa does not support shift count of 0.
- dlsa a0, a1, a0, $shift # a0 <- arrayObj + index*width
- .else
- daddu a0, a1, a0 # a0 <- arrayObj + index*width
- .endif
- bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- $load a2, $data_offset(a0) # a2 <- vBB[vCC]
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a2, a4 # vAA <- a2
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_aget_boolean.S b/runtime/interpreter/mterp/mips64/op_aget_boolean.S
deleted file mode 100644
index 7b28bc8..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aget_byte.S b/runtime/interpreter/mterp/mips64/op_aget_byte.S
deleted file mode 100644
index a4a0b7e..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aget_char.S b/runtime/interpreter/mterp/mips64/op_aget_char.S
deleted file mode 100644
index 465de09..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aget_object.S b/runtime/interpreter/mterp/mips64/op_aget_object.S
deleted file mode 100644
index 48d751b..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_object.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aget_object():
- /*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- .extern artAGetObjectFromMterp
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- EXPORT_PC
- GET_VREG_U a0, a2 # a0 <- vBB (array object)
- GET_VREG a1, a3 # a1 <- vCC (requested index)
- jal artAGetObjectFromMterp # (array, index)
- ld a1, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a4, rINST, 8 # a4 <- AA
- PREFETCH_INST 2
- bnez a1, MterpException
- SET_VREG_OBJECT v0, a4 # vAA <- v0
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_aget_short.S b/runtime/interpreter/mterp/mips64/op_aget_short.S
deleted file mode 100644
index 4faa9ad..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aget_wide.S b/runtime/interpreter/mterp/mips64/op_aget_wide.S
deleted file mode 100644
index 99b0de9..0000000
--- a/runtime/interpreter/mterp/mips64/op_aget_wide.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aget_wide():
- /*
- * Array get, 64 bits. vAA <- vBB[vCC].
- *
- */
- /* aget-wide vAA, vBB, vCC */
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- srl a4, rINST, 8 # a4 <- AA
- GET_VREG_U a0, a2 # a0 <- vBB (array object)
- GET_VREG a1, a3 # a1 <- vCC (requested index)
- beqz a0, common_errNullObject # bail if null array object
- lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
- dlsa a0, a1, a0, 3 # a0 <- arrayObj + index*width
- bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- lw a2, MIRROR_WIDE_ARRAY_DATA_OFFSET(a0)
- lw a3, (MIRROR_WIDE_ARRAY_DATA_OFFSET+4)(a0)
- dinsu a2, a3, 32, 32 # a2 <- vBB[vCC]
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a2, a4 # vAA <- a2
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_and_int.S b/runtime/interpreter/mterp/mips64/op_and_int.S
deleted file mode 100644
index 740411d..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_and_int_2addr.S b/runtime/interpreter/mterp/mips64/op_and_int_2addr.S
deleted file mode 100644
index 8224e5f..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_and_int_lit16.S b/runtime/interpreter/mterp/mips64/op_and_int_lit16.S
deleted file mode 100644
index 5031f50..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_and_int_lit8.S b/runtime/interpreter/mterp/mips64/op_and_int_lit8.S
deleted file mode 100644
index 7a7b8b5..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_and_long.S b/runtime/interpreter/mterp/mips64/op_and_long.S
deleted file mode 100644
index 242ddf2..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_and_long_2addr.S b/runtime/interpreter/mterp/mips64/op_and_long_2addr.S
deleted file mode 100644
index 64b5a7e..0000000
--- a/runtime/interpreter/mterp/mips64/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(instr="and a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_aput.S b/runtime/interpreter/mterp/mips64/op_aput.S
deleted file mode 100644
index f4c04d0..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
- /*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short
- *
- * NOTE: this assumes data offset for arrays is the same for all non-wide types.
- * If this changes, specialize.
- */
- /* op vAA, vBB, vCC */
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- srl a4, rINST, 8 # a4 <- AA
- GET_VREG_U a0, a2 # a0 <- vBB (array object)
- GET_VREG a1, a3 # a1 <- vCC (requested index)
- beqz a0, common_errNullObject # bail if null array object
- lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
- .if $shift
- # [d]lsa does not support shift count of 0.
- dlsa a0, a1, a0, $shift # a0 <- arrayObj + index*width
- .else
- daddu a0, a1, a0 # a0 <- arrayObj + index*width
- .endif
- bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_VREG a2, a4 # a2 <- vAA
- GET_INST_OPCODE v0 # extract opcode from rINST
- $store a2, $data_offset(a0) # vBB[vCC] <- a2
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_aput_boolean.S b/runtime/interpreter/mterp/mips64/op_aput_boolean.S
deleted file mode 100644
index 098bbcd..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aput_byte.S b/runtime/interpreter/mterp/mips64/op_aput_byte.S
deleted file mode 100644
index f4b42ee..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aput_char.S b/runtime/interpreter/mterp/mips64/op_aput_char.S
deleted file mode 100644
index 18eedae..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aput_object.S b/runtime/interpreter/mterp/mips64/op_aput_object.S
deleted file mode 100644
index 6b23e90..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_object.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_aput_object():
- /*
- * Store an object into an array. vBB[vCC] <- vAA.
- */
- /* op vAA, vBB, vCC */
- .extern MterpAputObject
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- jal MterpAputObject
- beqzc v0, MterpPossibleException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_aput_short.S b/runtime/interpreter/mterp/mips64/op_aput_short.S
deleted file mode 100644
index 61a3c0d..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/mips64/op_aput_wide.S b/runtime/interpreter/mterp/mips64/op_aput_wide.S
deleted file mode 100644
index 4fad5c4..0000000
--- a/runtime/interpreter/mterp/mips64/op_aput_wide.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_aput_wide():
- /*
- * Array put, 64 bits. vBB[vCC] <- vAA.
- *
- */
- /* aput-wide vAA, vBB, vCC */
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- srl a4, rINST, 8 # a4 <- AA
- GET_VREG_U a0, a2 # a0 <- vBB (array object)
- GET_VREG a1, a3 # a1 <- vCC (requested index)
- beqz a0, common_errNullObject # bail if null array object
- lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- arrayObj->length
- dlsa a0, a1, a0, 3 # a0 <- arrayObj + index*width
- bgeu a1, a3, common_errArrayIndex # unsigned compare: index >= length, bail
- GET_VREG_WIDE a2, a4 # a2 <- vAA
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- sw a2, MIRROR_WIDE_ARRAY_DATA_OFFSET(a0)
- dsrl32 a2, a2, 0
- sw a2, (MIRROR_WIDE_ARRAY_DATA_OFFSET+4)(a0) # vBB[vCC] <- a2
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_array_length.S b/runtime/interpreter/mterp/mips64/op_array_length.S
deleted file mode 100644
index 13b9a13..0000000
--- a/runtime/interpreter/mterp/mips64/op_array_length.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_array_length():
- /*
- * Return the length of an array.
- */
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a0, a1 # a0 <- vB (object ref)
- ext a2, rINST, 8, 4 # a2 <- A
- beqz a0, common_errNullObject # yup, fail
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- lw a3, MIRROR_ARRAY_LENGTH_OFFSET(a0) # a3 <- array length
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a3, a2 # vB <- length
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_check_cast.S b/runtime/interpreter/mterp/mips64/op_check_cast.S
deleted file mode 100644
index b5f0f1f..0000000
--- a/runtime/interpreter/mterp/mips64/op_check_cast.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_check_cast():
- /*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class//BBBB */
- .extern MterpCheckCast
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- BBBB
- srl a1, rINST, 8 # a1 <- AA
- dlsa a1, a1, rFP, 2 # a1 <- &object
- ld a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- jal MterpCheckCast # (index, &obj, method, self)
- PREFETCH_INST 2
- bnez v0, MterpPossibleException
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_cmp_long.S b/runtime/interpreter/mterp/mips64/op_cmp_long.S
deleted file mode 100644
index 87eba44..0000000
--- a/runtime/interpreter/mterp/mips64/op_cmp_long.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_cmp_long():
- /* cmp-long vAA, vBB, vCC */
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- srl a4, rINST, 8 # a4 <- AA
- GET_VREG_WIDE a0, a2 # a0 <- vBB
- GET_VREG_WIDE a1, a3 # a1 <- vCC
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- slt a2, a0, a1
- slt a0, a1, a0
- subu a0, a0, a2
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a4 # vAA <- result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_cmpg_double.S b/runtime/interpreter/mterp/mips64/op_cmpg_double.S
deleted file mode 100644
index 4c3117b..0000000
--- a/runtime/interpreter/mterp/mips64/op_cmpg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_double():
-% fcmpWide(gt_bias="1")
diff --git a/runtime/interpreter/mterp/mips64/op_cmpg_float.S b/runtime/interpreter/mterp/mips64/op_cmpg_float.S
deleted file mode 100644
index 99c4530..0000000
--- a/runtime/interpreter/mterp/mips64/op_cmpg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_float():
-% fcmp(gt_bias="1")
diff --git a/runtime/interpreter/mterp/mips64/op_cmpl_double.S b/runtime/interpreter/mterp/mips64/op_cmpl_double.S
deleted file mode 100644
index 4900bdd..0000000
--- a/runtime/interpreter/mterp/mips64/op_cmpl_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_double():
-% fcmpWide(gt_bias="0")
diff --git a/runtime/interpreter/mterp/mips64/op_cmpl_float.S b/runtime/interpreter/mterp/mips64/op_cmpl_float.S
deleted file mode 100644
index 159c66d..0000000
--- a/runtime/interpreter/mterp/mips64/op_cmpl_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_float():
-% fcmp(gt_bias="0")
diff --git a/runtime/interpreter/mterp/mips64/op_const.S b/runtime/interpreter/mterp/mips64/op_const.S
deleted file mode 100644
index 6193042..0000000
--- a/runtime/interpreter/mterp/mips64/op_const.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const():
- /* const vAA, #+BBBBbbbb */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- bbbb (low)
- lh a1, 4(rPC) # a1 <- BBBB (high)
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- ins a0, a1, 16, 16 # a0 = BBBBbbbb
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a2 # vAA <- +BBBBbbbb
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_16.S b/runtime/interpreter/mterp/mips64/op_const_16.S
deleted file mode 100644
index aac542d..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, #+BBBB */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- sign-extended BBBB
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a2 # vAA <- +BBBB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_4.S b/runtime/interpreter/mterp/mips64/op_const_4.S
deleted file mode 100644
index d26f4e5..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_4.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_4():
- /* const/4 vA, #+B */
- ext a2, rINST, 8, 4 # a2 <- A
- seh a0, rINST # sign extend B in rINST
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- sra a0, a0, 12 # shift B into its final position
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a2 # vA <- +B
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_class.S b/runtime/interpreter/mterp/mips64/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/mips64/op_const_high16.S b/runtime/interpreter/mterp/mips64/op_const_high16.S
deleted file mode 100644
index bf14ab6..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, #+BBBB0000 */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- BBBB
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- sll a0, a0, 16 # a0 <- BBBB0000
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a2 # vAA <- +BBBB0000
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_method_handle.S b/runtime/interpreter/mterp/mips64/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/mips64/op_const_method_type.S b/runtime/interpreter/mterp/mips64/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/mips64/op_const_string.S b/runtime/interpreter/mterp/mips64/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/mips64/op_const_string_jumbo.S b/runtime/interpreter/mterp/mips64/op_const_string_jumbo.S
deleted file mode 100644
index 25ec0e2..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_string_jumbo.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, String//BBBBBBBB */
- .extern MterpConstString
- EXPORT_PC
- lh a0, 2(rPC) # a0 <- bbbb (low)
- lh a4, 4(rPC) # a4 <- BBBB (high)
- srl a1, rINST, 8 # a1 <- AA
- ins a0, a4, 16, 16 # a0 <- BBBBbbbb
- daddu a2, rFP, OFF_FP_SHADOWFRAME
- move a3, rSELF
- jal MterpConstString # (index, tgt_reg, shadow_frame, self)
- PREFETCH_INST 3 # load rINST
- bnez v0, MterpPossibleException # let reference interpreter deal with it.
- ADVANCE 3 # advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_wide.S b/runtime/interpreter/mterp/mips64/op_const_wide.S
deleted file mode 100644
index 7c4a99a..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_wide.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
- srl a4, rINST, 8 # a4 <- AA
- lh a0, 2(rPC) # a0 <- bbbb (low)
- lh a1, 4(rPC) # a1 <- BBBB (low middle)
- lh a2, 6(rPC) # a2 <- hhhh (high middle)
- lh a3, 8(rPC) # a3 <- HHHH (high)
- FETCH_ADVANCE_INST 5 # advance rPC, load rINST
- ins a0, a1, 16, 16 # a0 = BBBBbbbb
- ins a2, a3, 16, 16 # a2 = HHHHhhhh
- dinsu a0, a2, 32, 32 # a0 = HHHHhhhhBBBBbbbb
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a4 # vAA <- +HHHHhhhhBBBBbbbb
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_wide_16.S b/runtime/interpreter/mterp/mips64/op_const_wide_16.S
deleted file mode 100644
index 65f3068..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_wide_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, #+BBBB */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- sign-extended BBBB
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAA <- +BBBB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_wide_32.S b/runtime/interpreter/mterp/mips64/op_const_wide_32.S
deleted file mode 100644
index 39fa0f9..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_wide_32.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, #+BBBBbbbb */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- bbbb (low)
- lh a1, 4(rPC) # a1 <- BBBB (high)
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- ins a0, a1, 16, 16 # a0 = BBBBbbbb
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAA <- +BBBBbbbb
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_const_wide_high16.S b/runtime/interpreter/mterp/mips64/op_const_wide_high16.S
deleted file mode 100644
index 7c538c1..0000000
--- a/runtime/interpreter/mterp/mips64/op_const_wide_high16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, #+BBBB000000000000 */
- srl a2, rINST, 8 # a2 <- AA
- lh a0, 2(rPC) # a0 <- BBBB
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- dsll32 a0, a0, 16 # a0 <- BBBB000000000000
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAA <- +BBBB000000000000
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_div_double.S b/runtime/interpreter/mterp/mips64/op_div_double.S
deleted file mode 100644
index c134dfb..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% fbinopWide(instr="div.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_double_2addr.S b/runtime/interpreter/mterp/mips64/op_div_double_2addr.S
deleted file mode 100644
index 6ac1d75..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% fbinopWide2addr(instr="div.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_float.S b/runtime/interpreter/mterp/mips64/op_div_float.S
deleted file mode 100644
index 9753032..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% fbinop(instr="div.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_float_2addr.S b/runtime/interpreter/mterp/mips64/op_div_float_2addr.S
deleted file mode 100644
index 53421ce..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% fbinop2addr(instr="div.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_int.S b/runtime/interpreter/mterp/mips64/op_div_int.S
deleted file mode 100644
index da9bfcb..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int():
-% binop(instr="div a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_int_2addr.S b/runtime/interpreter/mterp/mips64/op_div_int_2addr.S
deleted file mode 100644
index 7c94442..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_2addr():
-% binop2addr(instr="div a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_int_lit16.S b/runtime/interpreter/mterp/mips64/op_div_int_lit16.S
deleted file mode 100644
index 4afe80e..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit16():
-% binopLit16(instr="div a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_int_lit8.S b/runtime/interpreter/mterp/mips64/op_div_int_lit8.S
deleted file mode 100644
index 7e2df1b..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit8():
-% binopLit8(instr="div a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_long.S b/runtime/interpreter/mterp/mips64/op_div_long.S
deleted file mode 100644
index 93c2187..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long():
-% binopWide(instr="ddiv a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_div_long_2addr.S b/runtime/interpreter/mterp/mips64/op_div_long_2addr.S
deleted file mode 100644
index 74ecb20..0000000
--- a/runtime/interpreter/mterp/mips64/op_div_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long_2addr():
-% binopWide2addr(instr="ddiv a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_double_to_float.S b/runtime/interpreter/mterp/mips64/op_double_to_float.S
deleted file mode 100644
index f19b47f..0000000
--- a/runtime/interpreter/mterp/mips64/op_double_to_float.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_double_to_float():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- cvt.s.d f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_double_to_int.S b/runtime/interpreter/mterp/mips64/op_double_to_int.S
deleted file mode 100644
index ba370a2..0000000
--- a/runtime/interpreter/mterp/mips64/op_double_to_int.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_double_to_int():
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- trunc.w.d f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_double_to_long.S b/runtime/interpreter/mterp/mips64/op_double_to_long.S
deleted file mode 100644
index 1050a72..0000000
--- a/runtime/interpreter/mterp/mips64/op_double_to_long.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_double_to_long():
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- trunc.l.d f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_fill_array_data.S b/runtime/interpreter/mterp/mips64/op_fill_array_data.S
deleted file mode 100644
index 5ccff91..0000000
--- a/runtime/interpreter/mterp/mips64/op_fill_array_data.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- .extern MterpFillArrayData
- EXPORT_PC
- lh a1, 2(rPC) # a1 <- bbbb (lo)
- lh a0, 4(rPC) # a0 <- BBBB (hi)
- srl a3, rINST, 8 # a3 <- AA
- ins a1, a0, 16, 16 # a1 <- BBBBbbbb
- GET_VREG_U a0, a3 # a0 <- vAA (array object)
- dlsa a1, a1, rPC, 1 # a1 <- PC + BBBBbbbb*2 (array data off.)
- jal MterpFillArrayData # (obj, payload)
- beqzc v0, MterpPossibleException # exception?
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_filled_new_array.S b/runtime/interpreter/mterp/mips64/op_filled_new_array.S
deleted file mode 100644
index d86ce16..0000000
--- a/runtime/interpreter/mterp/mips64/op_filled_new_array.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
- /*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class//CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type//BBBB */
- .extern $helper
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rSELF
- jal $helper
- beqzc v0, MterpPossibleException
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_filled_new_array_range.S b/runtime/interpreter/mterp/mips64/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/mips64/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/mips64/op_float_to_double.S b/runtime/interpreter/mterp/mips64/op_float_to_double.S
deleted file mode 100644
index feebdd8..0000000
--- a/runtime/interpreter/mterp/mips64/op_float_to_double.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_float_to_double():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- cvt.d.s f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_float_to_int.S b/runtime/interpreter/mterp/mips64/op_float_to_int.S
deleted file mode 100644
index cbfe853..0000000
--- a/runtime/interpreter/mterp/mips64/op_float_to_int.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_float_to_int():
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- trunc.w.s f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_float_to_long.S b/runtime/interpreter/mterp/mips64/op_float_to_long.S
deleted file mode 100644
index ccf23b1..0000000
--- a/runtime/interpreter/mterp/mips64/op_float_to_long.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_float_to_long():
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- trunc.l.s f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_goto.S b/runtime/interpreter/mterp/mips64/op_goto.S
deleted file mode 100644
index 371bae7..0000000
--- a/runtime/interpreter/mterp/mips64/op_goto.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto():
- /*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- srl rINST, rINST, 8
- seb rINST, rINST # rINST <- offset (sign-extended AA)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips64/op_goto_16.S b/runtime/interpreter/mterp/mips64/op_goto_16.S
deleted file mode 100644
index 3b0b52a..0000000
--- a/runtime/interpreter/mterp/mips64/op_goto_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_goto_16():
- /*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- lh rINST, 2(rPC) # rINST <- offset (sign-extended AAAA)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips64/op_goto_32.S b/runtime/interpreter/mterp/mips64/op_goto_32.S
deleted file mode 100644
index d48f0a0..0000000
--- a/runtime/interpreter/mterp/mips64/op_goto_32.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_goto_32():
- /*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Unlike most opcodes, this one is allowed to branch to itself, so
- * our "backward branch" test must be "<=0" instead of "<0".
- */
- /* goto/32 +AAAAAAAA */
- lh rINST, 2(rPC) # rINST <- aaaa (low)
- lh a1, 4(rPC) # a1 <- AAAA (high)
- ins rINST, a1, 16, 16 # rINST <- offset (sign-extended AAAAaaaa)
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips64/op_if_eq.S b/runtime/interpreter/mterp/mips64/op_if_eq.S
deleted file mode 100644
index da58674..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(condition="eq")
diff --git a/runtime/interpreter/mterp/mips64/op_if_eqz.S b/runtime/interpreter/mterp/mips64/op_if_eqz.S
deleted file mode 100644
index 0639664..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(condition="eq")
diff --git a/runtime/interpreter/mterp/mips64/op_if_ge.S b/runtime/interpreter/mterp/mips64/op_if_ge.S
deleted file mode 100644
index 5b6ed2f..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(condition="ge")
diff --git a/runtime/interpreter/mterp/mips64/op_if_gez.S b/runtime/interpreter/mterp/mips64/op_if_gez.S
deleted file mode 100644
index ea6cda7..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(condition="ge")
diff --git a/runtime/interpreter/mterp/mips64/op_if_gt.S b/runtime/interpreter/mterp/mips64/op_if_gt.S
deleted file mode 100644
index 201decf..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(condition="gt")
diff --git a/runtime/interpreter/mterp/mips64/op_if_gtz.S b/runtime/interpreter/mterp/mips64/op_if_gtz.S
deleted file mode 100644
index 1fdbb6e..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(condition="gt")
diff --git a/runtime/interpreter/mterp/mips64/op_if_le.S b/runtime/interpreter/mterp/mips64/op_if_le.S
deleted file mode 100644
index e6024f2..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(condition="le")
diff --git a/runtime/interpreter/mterp/mips64/op_if_lez.S b/runtime/interpreter/mterp/mips64/op_if_lez.S
deleted file mode 100644
index 62c0d2c..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(condition="le")
diff --git a/runtime/interpreter/mterp/mips64/op_if_lt.S b/runtime/interpreter/mterp/mips64/op_if_lt.S
deleted file mode 100644
index 4ef22fd..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(condition="lt")
diff --git a/runtime/interpreter/mterp/mips64/op_if_ltz.S b/runtime/interpreter/mterp/mips64/op_if_ltz.S
deleted file mode 100644
index 84b2d0b..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(condition="lt")
diff --git a/runtime/interpreter/mterp/mips64/op_if_ne.S b/runtime/interpreter/mterp/mips64/op_if_ne.S
deleted file mode 100644
index ec3a688..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(condition="ne")
diff --git a/runtime/interpreter/mterp/mips64/op_if_nez.S b/runtime/interpreter/mterp/mips64/op_if_nez.S
deleted file mode 100644
index 7009c3a..0000000
--- a/runtime/interpreter/mterp/mips64/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(condition="ne")
diff --git a/runtime/interpreter/mterp/mips64/op_iget.S b/runtime/interpreter/mterp/mips64/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips64/op_iget_boolean.S b/runtime/interpreter/mterp/mips64/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_boolean_quick.S b/runtime/interpreter/mterp/mips64/op_iget_boolean_quick.S
deleted file mode 100644
index f3d2cb1..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="lbu")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_byte.S b/runtime/interpreter/mterp/mips64/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_byte_quick.S b/runtime/interpreter/mterp/mips64/op_iget_byte_quick.S
deleted file mode 100644
index ddb469b..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="lb")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_char.S b/runtime/interpreter/mterp/mips64/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_char_quick.S b/runtime/interpreter/mterp/mips64/op_iget_char_quick.S
deleted file mode 100644
index ef0b350..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="lhu")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_object.S b/runtime/interpreter/mterp/mips64/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_object_quick.S b/runtime/interpreter/mterp/mips64/op_iget_object_quick.S
deleted file mode 100644
index 518b747..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_object_quick.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset//CCCC */
- .extern artIGetObjectFromMterp
- srl a2, rINST, 12 # a2 <- B
- lhu a1, 2(rPC) # a1 <- field byte offset
- EXPORT_PC
- GET_VREG_U a0, a2 # a0 <- object we're operating on
- jal artIGetObjectFromMterp # (obj, offset)
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- ADVANCE 2 # advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_iget_quick.S b/runtime/interpreter/mterp/mips64/op_iget_quick.S
deleted file mode 100644
index eb59796..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iget_quick(load="lw"):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
- /* op vA, vB, offset//CCCC */
- srl a2, rINST, 12 # a2 <- B
- lhu a1, 2(rPC) # a1 <- field byte offset
- GET_VREG_U a3, a2 # a3 <- object we're operating on
- ext a4, rINST, 8, 4 # a4 <- A
- daddu a1, a1, a3
- beqz a3, common_errNullObject # object was null
- $load a0, 0(a1) # a0 <- obj.field
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG a0, a4 # fp[A] <- a0
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_iget_short.S b/runtime/interpreter/mterp/mips64/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_short_quick.S b/runtime/interpreter/mterp/mips64/op_iget_short_quick.S
deleted file mode 100644
index 5957cb4..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="lh")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_wide.S b/runtime/interpreter/mterp/mips64/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/mips64/op_iget_wide_quick.S b/runtime/interpreter/mterp/mips64/op_iget_wide_quick.S
deleted file mode 100644
index e914e0d..0000000
--- a/runtime/interpreter/mterp/mips64/op_iget_wide_quick.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_iget_wide_quick():
- /* iget-wide-quick vA, vB, offset//CCCC */
- srl a2, rINST, 12 # a2 <- B
- lhu a4, 2(rPC) # a4 <- field byte offset
- GET_VREG_U a3, a2 # a3 <- object we're operating on
- ext a2, rINST, 8, 4 # a2 <- A
- beqz a3, common_errNullObject # object was null
- daddu a4, a3, a4 # create direct pointer
- lw a0, 0(a4)
- lw a1, 4(a4)
- dinsu a0, a1, 32, 32
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG_WIDE a0, a2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_instance_of.S b/runtime/interpreter/mterp/mips64/op_instance_of.S
deleted file mode 100644
index 1929944..0000000
--- a/runtime/interpreter/mterp/mips64/op_instance_of.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def op_instance_of():
- /*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class//CCCC */
- .extern MterpInstanceOf
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- CCCC
- srl a1, rINST, 12 # a1 <- B
- dlsa a1, a1, rFP, 2 # a1 <- &object
- ld a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- jal MterpInstanceOf # (index, &obj, method, self)
- ld a1, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a1, MterpException
- ADVANCE 2 # advance rPC
- SET_VREG v0, a2 # vA <- v0
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_byte.S b/runtime/interpreter/mterp/mips64/op_int_to_byte.S
deleted file mode 100644
index 47440c6..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="seb a0, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_char.S b/runtime/interpreter/mterp/mips64/op_int_to_char.S
deleted file mode 100644
index bea4e9e..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(instr="and a0, a0, 0xffff")
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_double.S b/runtime/interpreter/mterp/mips64/op_int_to_double.S
deleted file mode 100644
index 6cc83ae..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_double.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_int_to_double():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- cvt.d.w f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_float.S b/runtime/interpreter/mterp/mips64/op_int_to_float.S
deleted file mode 100644
index 837f8f9..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_float.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_int_to_float():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- cvt.s.w f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_long.S b/runtime/interpreter/mterp/mips64/op_int_to_long.S
deleted file mode 100644
index c0cfd72..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_long.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_int_to_long():
- /* int-to-long vA, vB */
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG a0, a3 # a0 <- vB (sign-extended to 64 bits)
- ext a2, rINST, 8, 4 # a2 <- A
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vA <- vB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_int_to_short.S b/runtime/interpreter/mterp/mips64/op_int_to_short.S
deleted file mode 100644
index 3d90de3..0000000
--- a/runtime/interpreter/mterp/mips64/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="seh a0, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_custom.S b/runtime/interpreter/mterp/mips64/op_invoke_custom.S
deleted file mode 100644
index 4bba9ee..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_custom.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_custom_range.S b/runtime/interpreter/mterp/mips64/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_direct.S b/runtime/interpreter/mterp/mips64/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_direct_range.S b/runtime/interpreter/mterp/mips64/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_interface.S b/runtime/interpreter/mterp/mips64/op_invoke_interface.S
deleted file mode 100644
index b064126..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_interface.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
- /*
- * Handle an interface method call.
- *
- * for: invoke-interface, invoke-interface/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_interface_range.S b/runtime/interpreter/mterp/mips64/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_polymorphic.S b/runtime/interpreter/mterp/mips64/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/mips64/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_static.S b/runtime/interpreter/mterp/mips64/op_invoke_static.S
deleted file mode 100644
index 8b104a6..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_static.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_static_range.S b/runtime/interpreter/mterp/mips64/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_super.S b/runtime/interpreter/mterp/mips64/op_invoke_super.S
deleted file mode 100644
index 3c34c99..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_super.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
- /*
- * Handle a "super" method call.
- *
- * for: invoke-super, invoke-super/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_super_range.S b/runtime/interpreter/mterp/mips64/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_virtual.S b/runtime/interpreter/mterp/mips64/op_invoke_virtual.S
deleted file mode 100644
index 249177b..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_virtual.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
- /*
- * Handle a virtual method call.
- *
- * for: invoke-virtual, invoke-virtual/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/mips64/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_virtual_range.S b/runtime/interpreter/mterp/mips64/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/mips64/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/mips64/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/mips64/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/mips64/op_iput.S b/runtime/interpreter/mterp/mips64/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips64/op_iput_boolean.S b/runtime/interpreter/mterp/mips64/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_boolean_quick.S b/runtime/interpreter/mterp/mips64/op_iput_boolean_quick.S
deleted file mode 100644
index 3d818a5..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(store="sb")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_byte.S b/runtime/interpreter/mterp/mips64/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_byte_quick.S b/runtime/interpreter/mterp/mips64/op_iput_byte_quick.S
deleted file mode 100644
index 06dc24e..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(store="sb")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_char.S b/runtime/interpreter/mterp/mips64/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_char_quick.S b/runtime/interpreter/mterp/mips64/op_iput_char_quick.S
deleted file mode 100644
index 3b6af5b..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(store="sh")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_object.S b/runtime/interpreter/mterp/mips64/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_object_quick.S b/runtime/interpreter/mterp/mips64/op_iput_object_quick.S
deleted file mode 100644
index 0a15857..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_object_quick.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_iput_object_quick():
- .extern MterpIputObjectQuick
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- jal MterpIputObjectQuick
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_iput_quick.S b/runtime/interpreter/mterp/mips64/op_iput_quick.S
deleted file mode 100644
index b38b753..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_quick.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_iput_quick(store="sw"):
- /* For: iput-quick, iput-boolean-quick, iput-byte-quick, iput-char-quick, iput-short-quick */
- /* op vA, vB, offset//CCCC */
- srl a2, rINST, 12 # a2 <- B
- lhu a1, 2(rPC) # a1 <- field byte offset
- GET_VREG_U a3, a2 # a3 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- beqz a3, common_errNullObject # object was null
- GET_VREG a0, a2 # a0 <- fp[A]
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- daddu a1, a1, a3
- $store a0, 0(a1) # obj.field <- a0
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_iput_short.S b/runtime/interpreter/mterp/mips64/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_short_quick.S b/runtime/interpreter/mterp/mips64/op_iput_short_quick.S
deleted file mode 100644
index fade093..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(store="sh")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_wide.S b/runtime/interpreter/mterp/mips64/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/mips64/op_iput_wide_quick.S b/runtime/interpreter/mterp/mips64/op_iput_wide_quick.S
deleted file mode 100644
index 240f902..0000000
--- a/runtime/interpreter/mterp/mips64/op_iput_wide_quick.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset//CCCC */
- srl a2, rINST, 12 # a2 <- B
- lhu a3, 2(rPC) # a3 <- field byte offset
- GET_VREG_U a2, a2 # a2 <- fp[B], the object pointer
- ext a0, rINST, 8, 4 # a0 <- A
- beqz a2, common_errNullObject # object was null
- GET_VREG_WIDE a0, a0 # a0 <- fp[A]
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- daddu a1, a2, a3 # create a direct pointer
- sw a0, 0(a1)
- dsrl32 a0, a0, 0
- sw a0, 4(a1)
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_long_to_double.S b/runtime/interpreter/mterp/mips64/op_long_to_double.S
deleted file mode 100644
index f4d346c..0000000
--- a/runtime/interpreter/mterp/mips64/op_long_to_double.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_long_to_double():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- cvt.d.l f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_long_to_float.S b/runtime/interpreter/mterp/mips64/op_long_to_float.S
deleted file mode 100644
index 3c616d1..0000000
--- a/runtime/interpreter/mterp/mips64/op_long_to_float.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_long_to_float():
- /*
- * Conversion from or to floating-point happens in a floating-point register.
- * Therefore we load the input and store the output into or from a
- * floating-point register irrespective of the type.
- */
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- cvt.s.l f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_long_to_int.S b/runtime/interpreter/mterp/mips64/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/mips64/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/mips64/op_monitor_enter.S b/runtime/interpreter/mterp/mips64/op_monitor_enter.S
deleted file mode 100644
index 47184f9..0000000
--- a/runtime/interpreter/mterp/mips64/op_monitor_enter.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_monitor_enter():
- /*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- .extern artLockObjectFromCode
- EXPORT_PC
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG_U a0, a2 # a0 <- vAA (object)
- move a1, rSELF # a1 <- self
- jal artLockObjectFromCode
- bnezc v0, MterpException
- FETCH_ADVANCE_INST 1
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_monitor_exit.S b/runtime/interpreter/mterp/mips64/op_monitor_exit.S
deleted file mode 100644
index 58f8541..0000000
--- a/runtime/interpreter/mterp/mips64/op_monitor_exit.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_monitor_exit():
- /*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- .extern artUnlockObjectFromCode
- EXPORT_PC
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG_U a0, a2 # a0 <- vAA (object)
- move a1, rSELF # a1 <- self
- jal artUnlockObjectFromCode # v0 <- success for unlock(self, obj)
- bnezc v0, MterpException
- FETCH_ADVANCE_INST 1 # before throw: advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move.S b/runtime/interpreter/mterp/mips64/op_move.S
deleted file mode 100644
index c6de44c..0000000
--- a/runtime/interpreter/mterp/mips64/op_move.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_VREG a0, a3 # a0 <- vB
- GET_INST_OPCODE v0 # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT a0, a2 # vA <- vB
- .else
- SET_VREG a0, a2 # vA <- vB
- .endif
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_16.S b/runtime/interpreter/mterp/mips64/op_move_16.S
deleted file mode 100644
index 68b7037..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- lhu a3, 4(rPC) # a3 <- BBBB
- lhu a2, 2(rPC) # a2 <- AAAA
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- GET_VREG a0, a3 # a0 <- vBBBB
- GET_INST_OPCODE v0 # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT a0, a2 # vAAAA <- vBBBB
- .else
- SET_VREG a0, a2 # vAAAA <- vBBBB
- .endif
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_exception.S b/runtime/interpreter/mterp/mips64/op_move_exception.S
deleted file mode 100644
index 8f441c7..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_exception.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- srl a2, rINST, 8 # a2 <- AA
- ld a0, THREAD_EXCEPTION_OFFSET(rSELF) # load exception obj
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- SET_VREG_OBJECT a0, a2 # vAA <- exception obj
- GET_INST_OPCODE v0 # extract opcode from rINST
- sd zero, THREAD_EXCEPTION_OFFSET(rSELF) # clear exception
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_from16.S b/runtime/interpreter/mterp/mips64/op_move_from16.S
deleted file mode 100644
index f4c254c..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_from16.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- lhu a3, 2(rPC) # a3 <- BBBB
- srl a2, rINST, 8 # a2 <- AA
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_VREG a0, a3 # a0 <- vBBBB
- GET_INST_OPCODE v0 # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT a0, a2 # vAA <- vBBBB
- .else
- SET_VREG a0, a2 # vAA <- vBBBB
- .endif
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_object.S b/runtime/interpreter/mterp/mips64/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/mips64/op_move_object_16.S b/runtime/interpreter/mterp/mips64/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/mips64/op_move_object_from16.S b/runtime/interpreter/mterp/mips64/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/mips64/op_move_result.S b/runtime/interpreter/mterp/mips64/op_move_result.S
deleted file mode 100644
index 9d4bdfe..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_result.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- srl a2, rINST, 8 # a2 <- AA
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- ld a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
- lw a0, 0(a0) # a0 <- result.i
- GET_INST_OPCODE v0 # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT a0, a2 # vAA <- result
- .else
- SET_VREG a0, a2 # vAA <- result
- .endif
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_result_object.S b/runtime/interpreter/mterp/mips64/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/mips64/op_move_result_wide.S b/runtime/interpreter/mterp/mips64/op_move_result_wide.S
deleted file mode 100644
index 048ab3f..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_result_wide.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_result_wide():
- /* for: move-result-wide */
- /* op vAA */
- srl a2, rINST, 8 # a2 <- AA
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- ld a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
- ld a0, 0(a0) # a0 <- result.j
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAA <- result
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_wide.S b/runtime/interpreter/mterp/mips64/op_move_wide.S
deleted file mode 100644
index 94cfa47..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_wide.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- ext a3, rINST, 12, 4 # a3 <- B
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG_WIDE a0, a3 # a0 <- vB
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vA <- vB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_wide_16.S b/runtime/interpreter/mterp/mips64/op_move_wide_16.S
deleted file mode 100644
index f3a923e..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_wide_16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- lhu a3, 4(rPC) # a3 <- BBBB
- lhu a2, 2(rPC) # a2 <- AAAA
- GET_VREG_WIDE a0, a3 # a0 <- vBBBB
- FETCH_ADVANCE_INST 3 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAAAA <- vBBBB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_move_wide_from16.S b/runtime/interpreter/mterp/mips64/op_move_wide_from16.S
deleted file mode 100644
index 822035e..0000000
--- a/runtime/interpreter/mterp/mips64/op_move_wide_from16.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- lhu a3, 2(rPC) # a3 <- BBBB
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG_WIDE a0, a3 # a0 <- vBBBB
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vAA <- vBBBB
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_mul_double.S b/runtime/interpreter/mterp/mips64/op_mul_double.S
deleted file mode 100644
index 84cf5af..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% fbinopWide(instr="mul.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_double_2addr.S b/runtime/interpreter/mterp/mips64/op_mul_double_2addr.S
deleted file mode 100644
index 1ba6740..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% fbinopWide2addr(instr="mul.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_float.S b/runtime/interpreter/mterp/mips64/op_mul_float.S
deleted file mode 100644
index 16594ed..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% fbinop(instr="mul.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_float_2addr.S b/runtime/interpreter/mterp/mips64/op_mul_float_2addr.S
deleted file mode 100644
index 318ddab..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% fbinop2addr(instr="mul.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_int.S b/runtime/interpreter/mterp/mips64/op_mul_int.S
deleted file mode 100644
index 34e42f0..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int():
-% binop(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_int_2addr.S b/runtime/interpreter/mterp/mips64/op_mul_int_2addr.S
deleted file mode 100644
index 0224a6e..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_2addr():
-% binop2addr(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_int_lit16.S b/runtime/interpreter/mterp/mips64/op_mul_int_lit16.S
deleted file mode 100644
index 935d632..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit16():
-% binopLit16(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_int_lit8.S b/runtime/interpreter/mterp/mips64/op_mul_int_lit8.S
deleted file mode 100644
index 4a2bfca..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit8():
-% binopLit8(instr="mul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_long.S b/runtime/interpreter/mterp/mips64/op_mul_long.S
deleted file mode 100644
index 296138d..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_long():
-% binopWide(instr="dmul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_mul_long_2addr.S b/runtime/interpreter/mterp/mips64/op_mul_long_2addr.S
deleted file mode 100644
index a99eaa4..0000000
--- a/runtime/interpreter/mterp/mips64/op_mul_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_long_2addr():
-% binopWide2addr(instr="dmul a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_neg_double.S b/runtime/interpreter/mterp/mips64/op_neg_double.S
deleted file mode 100644
index aa24c32..0000000
--- a/runtime/interpreter/mterp/mips64/op_neg_double.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_neg_double():
-% fcvtHeader(suffix="_DOUBLE", valreg="f0")
- neg.d f0, f0
-% fcvtFooter(suffix="_DOUBLE", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_neg_float.S b/runtime/interpreter/mterp/mips64/op_neg_float.S
deleted file mode 100644
index 1554a4d..0000000
--- a/runtime/interpreter/mterp/mips64/op_neg_float.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_neg_float():
-% fcvtHeader(suffix="_FLOAT", valreg="f0")
- neg.s f0, f0
-% fcvtFooter(suffix="_FLOAT", valreg="f0")
diff --git a/runtime/interpreter/mterp/mips64/op_neg_int.S b/runtime/interpreter/mterp/mips64/op_neg_int.S
deleted file mode 100644
index 9243a21..0000000
--- a/runtime/interpreter/mterp/mips64/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr="subu a0, zero, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_neg_long.S b/runtime/interpreter/mterp/mips64/op_neg_long.S
deleted file mode 100644
index ad9d559..0000000
--- a/runtime/interpreter/mterp/mips64/op_neg_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_long():
-% unopWide(instr="dsubu a0, zero, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_new_array.S b/runtime/interpreter/mterp/mips64/op_new_array.S
deleted file mode 100644
index 8da7d83..0000000
--- a/runtime/interpreter/mterp/mips64/op_new_array.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_new_array():
- /*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class//CCCC */
- .extern MterpNewArray
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpNewArray
- beqzc v0, MterpPossibleException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_new_instance.S b/runtime/interpreter/mterp/mips64/op_new_instance.S
deleted file mode 100644
index a14fd8f..0000000
--- a/runtime/interpreter/mterp/mips64/op_new_instance.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_new_instance():
- /*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class//BBBB */
- .extern MterpNewInstance
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rSELF
- move a2, rINST
- jal MterpNewInstance # (shadow_frame, self, inst_data)
- beqzc v0, MterpPossibleException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_nop.S b/runtime/interpreter/mterp/mips64/op_nop.S
deleted file mode 100644
index 925fe4c..0000000
--- a/runtime/interpreter/mterp/mips64/op_nop.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def op_nop():
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_not_int.S b/runtime/interpreter/mterp/mips64/op_not_int.S
deleted file mode 100644
index 2fc1dd7..0000000
--- a/runtime/interpreter/mterp/mips64/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr="nor a0, zero, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_not_long.S b/runtime/interpreter/mterp/mips64/op_not_long.S
deleted file mode 100644
index a551b31..0000000
--- a/runtime/interpreter/mterp/mips64/op_not_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_long():
-% unopWide(instr="nor a0, zero, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_or_int.S b/runtime/interpreter/mterp/mips64/op_or_int.S
deleted file mode 100644
index df60be5..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_or_int_2addr.S b/runtime/interpreter/mterp/mips64/op_or_int_2addr.S
deleted file mode 100644
index c202e67..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_or_int_lit16.S b/runtime/interpreter/mterp/mips64/op_or_int_lit16.S
deleted file mode 100644
index 09961e8..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_or_int_lit8.S b/runtime/interpreter/mterp/mips64/op_or_int_lit8.S
deleted file mode 100644
index 1bd6809..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_or_long.S b/runtime/interpreter/mterp/mips64/op_or_long.S
deleted file mode 100644
index 65d4c44c..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_or_long_2addr.S b/runtime/interpreter/mterp/mips64/op_or_long_2addr.S
deleted file mode 100644
index 5ad0113..0000000
--- a/runtime/interpreter/mterp/mips64/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(instr="or a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_packed_switch.S b/runtime/interpreter/mterp/mips64/op_packed_switch.S
deleted file mode 100644
index 36c2107..0000000
--- a/runtime/interpreter/mterp/mips64/op_packed_switch.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
- /*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBBBBBB */
- .extern $func
- lh a0, 2(rPC) # a0 <- bbbb (lo)
- lh a1, 4(rPC) # a1 <- BBBB (hi)
- srl a3, rINST, 8 # a3 <- AA
- ins a0, a1, 16, 16 # a0 <- BBBBbbbb
- GET_VREG a1, a3 # a1 <- vAA
- dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2
- jal $func # v0 <- code-unit branch offset
- move rINST, v0
- b MterpCommonTakenBranchNoFlags
diff --git a/runtime/interpreter/mterp/mips64/op_rem_double.S b/runtime/interpreter/mterp/mips64/op_rem_double.S
deleted file mode 100644
index 16ad357..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_double.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_rem_double():
- /* rem-double vAA, vBB, vCC */
- .extern fmod
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_DOUBLE f12, a2 # f12 <- vBB
- GET_VREG_DOUBLE f13, a3 # f13 <- vCC
- jal fmod # f0 <- f12 op f13
- srl a4, rINST, 8 # a4 <- AA
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_DOUBLE f0, a4 # vAA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_rem_double_2addr.S b/runtime/interpreter/mterp/mips64/op_rem_double_2addr.S
deleted file mode 100644
index 230d70b..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_double_2addr.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_rem_double_2addr():
- /* rem-double/2addr vA, vB */
- .extern fmod
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_DOUBLE f12, a2 # f12 <- vA
- GET_VREG_DOUBLE f13, a3 # f13 <- vB
- jal fmod # f0 <- f12 op f13
- ext a2, rINST, 8, 4 # a2 <- A
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_DOUBLE f0, a2 # vA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_rem_float.S b/runtime/interpreter/mterp/mips64/op_rem_float.S
deleted file mode 100644
index 08c6516..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_float.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_rem_float():
- /* rem-float vAA, vBB, vCC */
- .extern fmodf
- lbu a2, 2(rPC) # a2 <- BB
- lbu a3, 3(rPC) # a3 <- CC
- GET_VREG_FLOAT f12, a2 # f12 <- vBB
- GET_VREG_FLOAT f13, a3 # f13 <- vCC
- jal fmodf # f0 <- f12 op f13
- srl a4, rINST, 8 # a4 <- AA
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_FLOAT f0, a4 # vAA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_rem_float_2addr.S b/runtime/interpreter/mterp/mips64/op_rem_float_2addr.S
deleted file mode 100644
index d35a0f4..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_float_2addr.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_rem_float_2addr():
- /* rem-float/2addr vA, vB */
- .extern fmodf
- ext a2, rINST, 8, 4 # a2 <- A
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_FLOAT f12, a2 # f12 <- vA
- GET_VREG_FLOAT f13, a3 # f13 <- vB
- jal fmodf # f0 <- f12 op f13
- ext a2, rINST, 8, 4 # a2 <- A
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_FLOAT f0, a2 # vA <- f0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/op_rem_int.S b/runtime/interpreter/mterp/mips64/op_rem_int.S
deleted file mode 100644
index 542fe28..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int():
-% binop(instr="mod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_rem_int_2addr.S b/runtime/interpreter/mterp/mips64/op_rem_int_2addr.S
deleted file mode 100644
index da40576..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_2addr():
-% binop2addr(instr="mod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_rem_int_lit16.S b/runtime/interpreter/mterp/mips64/op_rem_int_lit16.S
deleted file mode 100644
index 2dc5173..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit16():
-% binopLit16(instr="mod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_rem_int_lit8.S b/runtime/interpreter/mterp/mips64/op_rem_int_lit8.S
deleted file mode 100644
index 4ea0ace..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit8():
-% binopLit8(instr="mod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_rem_long.S b/runtime/interpreter/mterp/mips64/op_rem_long.S
deleted file mode 100644
index a10984a..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long():
-% binopWide(instr="dmod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_rem_long_2addr.S b/runtime/interpreter/mterp/mips64/op_rem_long_2addr.S
deleted file mode 100644
index 3cac4fb..0000000
--- a/runtime/interpreter/mterp/mips64/op_rem_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long_2addr():
-% binopWide2addr(instr="dmod a0, a0, a1", chkzero="1")
diff --git a/runtime/interpreter/mterp/mips64/op_return.S b/runtime/interpreter/mterp/mips64/op_return.S
deleted file mode 100644
index bfdf76a..0000000
--- a/runtime/interpreter/mterp/mips64/op_return.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_return(instr="GET_VREG"):
- /*
- * Return a 32-bit value.
- *
- * for: return (sign-extend), return-object (zero-extend)
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- .extern MterpSuspendCheck
- jal MterpThreadFenceForConstructor
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqzc ra, 1f
- jal MterpSuspendCheck # (self)
-1:
- srl a2, rINST, 8 # a2 <- AA
- $instr a0, a2 # a0 <- vAA
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips64/op_return_object.S b/runtime/interpreter/mterp/mips64/op_return_object.S
deleted file mode 100644
index 074c321..0000000
--- a/runtime/interpreter/mterp/mips64/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return(instr="GET_VREG_U")
diff --git a/runtime/interpreter/mterp/mips64/op_return_void.S b/runtime/interpreter/mterp/mips64/op_return_void.S
deleted file mode 100644
index b5aa76c..0000000
--- a/runtime/interpreter/mterp/mips64/op_return_void.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- .extern MterpSuspendCheck
- jal MterpThreadFenceForConstructor
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqzc ra, 1f
- jal MterpSuspendCheck # (self)
-1:
- li a0, 0
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips64/op_return_void_no_barrier.S b/runtime/interpreter/mterp/mips64/op_return_void_no_barrier.S
deleted file mode 100644
index 0baddbb..0000000
--- a/runtime/interpreter/mterp/mips64/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_return_void_no_barrier():
- .extern MterpSuspendCheck
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqzc ra, 1f
- jal MterpSuspendCheck # (self)
-1:
- li a0, 0
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips64/op_return_wide.S b/runtime/interpreter/mterp/mips64/op_return_wide.S
deleted file mode 100644
index dbcb704..0000000
--- a/runtime/interpreter/mterp/mips64/op_return_wide.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_return_wide():
- /*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- .extern MterpSuspendCheck
- jal MterpThreadFenceForConstructor
- lw ra, THREAD_FLAGS_OFFSET(rSELF)
- move a0, rSELF
- and ra, ra, THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
- beqzc ra, 1f
- jal MterpSuspendCheck # (self)
-1:
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG_WIDE a0, a2 # a0 <- vAA
- b MterpReturn
diff --git a/runtime/interpreter/mterp/mips64/op_rsub_int.S b/runtime/interpreter/mterp/mips64/op_rsub_int.S
deleted file mode 100644
index 2d61e86..0000000
--- a/runtime/interpreter/mterp/mips64/op_rsub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int():
-% binopLit16(instr="subu a0, a1, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_rsub_int_lit8.S b/runtime/interpreter/mterp/mips64/op_rsub_int_lit8.S
deleted file mode 100644
index b9b214d..0000000
--- a/runtime/interpreter/mterp/mips64/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(instr="subu a0, a1, a0")
diff --git a/runtime/interpreter/mterp/mips64/op_sget.S b/runtime/interpreter/mterp/mips64/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips64/op_sget_boolean.S b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/mips64/op_sget_byte.S b/runtime/interpreter/mterp/mips64/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/mips64/op_sget_char.S b/runtime/interpreter/mterp/mips64/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/mips64/op_sget_object.S b/runtime/interpreter/mterp/mips64/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/mips64/op_sget_short.S b/runtime/interpreter/mterp/mips64/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/mips64/op_sget_wide.S b/runtime/interpreter/mterp/mips64/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/mips64/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/mips64/op_shl_int.S b/runtime/interpreter/mterp/mips64/op_shl_int.S
deleted file mode 100644
index efd213c..0000000
--- a/runtime/interpreter/mterp/mips64/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shl_int_2addr.S b/runtime/interpreter/mterp/mips64/op_shl_int_2addr.S
deleted file mode 100644
index 0901e6b..0000000
--- a/runtime/interpreter/mterp/mips64/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% binop2addr(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shl_int_lit8.S b/runtime/interpreter/mterp/mips64/op_shl_int_lit8.S
deleted file mode 100644
index 2263ec7..0000000
--- a/runtime/interpreter/mterp/mips64/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(instr="sll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shl_long.S b/runtime/interpreter/mterp/mips64/op_shl_long.S
deleted file mode 100644
index 9ef03d8..0000000
--- a/runtime/interpreter/mterp/mips64/op_shl_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long():
-% binopWide(instr="dsll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shl_long_2addr.S b/runtime/interpreter/mterp/mips64/op_shl_long_2addr.S
deleted file mode 100644
index f748c3b..0000000
--- a/runtime/interpreter/mterp/mips64/op_shl_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long_2addr():
-% binopWide2addr(instr="dsll a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shr_int.S b/runtime/interpreter/mterp/mips64/op_shr_int.S
deleted file mode 100644
index 8d55e7a..0000000
--- a/runtime/interpreter/mterp/mips64/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shr_int_2addr.S b/runtime/interpreter/mterp/mips64/op_shr_int_2addr.S
deleted file mode 100644
index e102baa..0000000
--- a/runtime/interpreter/mterp/mips64/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% binop2addr(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shr_int_lit8.S b/runtime/interpreter/mterp/mips64/op_shr_int_lit8.S
deleted file mode 100644
index 437c5c4..0000000
--- a/runtime/interpreter/mterp/mips64/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(instr="sra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shr_long.S b/runtime/interpreter/mterp/mips64/op_shr_long.S
deleted file mode 100644
index 1be48f2..0000000
--- a/runtime/interpreter/mterp/mips64/op_shr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long():
-% binopWide(instr="dsra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_shr_long_2addr.S b/runtime/interpreter/mterp/mips64/op_shr_long_2addr.S
deleted file mode 100644
index a15861f..0000000
--- a/runtime/interpreter/mterp/mips64/op_shr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long_2addr():
-% binopWide2addr(instr="dsra a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_sparse_switch.S b/runtime/interpreter/mterp/mips64/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/mips64/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/mips64/op_sput.S b/runtime/interpreter/mterp/mips64/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/mips64/op_sput_boolean.S b/runtime/interpreter/mterp/mips64/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/mips64/op_sput_byte.S b/runtime/interpreter/mterp/mips64/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/mips64/op_sput_char.S b/runtime/interpreter/mterp/mips64/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/mips64/op_sput_object.S b/runtime/interpreter/mterp/mips64/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/mips64/op_sput_short.S b/runtime/interpreter/mterp/mips64/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/mips64/op_sput_wide.S b/runtime/interpreter/mterp/mips64/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/mips64/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_double.S b/runtime/interpreter/mterp/mips64/op_sub_double.S
deleted file mode 100644
index aeb1b0f..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% fbinopWide(instr="sub.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_double_2addr.S b/runtime/interpreter/mterp/mips64/op_sub_double_2addr.S
deleted file mode 100644
index 03457ac..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% fbinopWide2addr(instr="sub.d f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_float.S b/runtime/interpreter/mterp/mips64/op_sub_float.S
deleted file mode 100644
index 4afd1ad..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% fbinop(instr="sub.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_float_2addr.S b/runtime/interpreter/mterp/mips64/op_sub_float_2addr.S
deleted file mode 100644
index b4ade2c..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% fbinop2addr(instr="sub.s f0, f0, f1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_int.S b/runtime/interpreter/mterp/mips64/op_sub_int.S
deleted file mode 100644
index 57f618d..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="subu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_int_2addr.S b/runtime/interpreter/mterp/mips64/op_sub_int_2addr.S
deleted file mode 100644
index 445ffca..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="subu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_long.S b/runtime/interpreter/mterp/mips64/op_sub_long.S
deleted file mode 100644
index ba5fe49..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long():
-% binopWide(instr="dsubu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_sub_long_2addr.S b/runtime/interpreter/mterp/mips64/op_sub_long_2addr.S
deleted file mode 100644
index e22b4f6..0000000
--- a/runtime/interpreter/mterp/mips64/op_sub_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long_2addr():
-% binopWide2addr(instr="dsubu a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_throw.S b/runtime/interpreter/mterp/mips64/op_throw.S
deleted file mode 100644
index 7f26d88..0000000
--- a/runtime/interpreter/mterp/mips64/op_throw.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_throw():
- /*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC
- srl a2, rINST, 8 # a2 <- AA
- GET_VREG_U a0, a2 # a0 <- vAA (exception object)
- beqzc a0, common_errNullObject
- sd a0, THREAD_EXCEPTION_OFFSET(rSELF) # thread->exception <- obj
- b MterpException
diff --git a/runtime/interpreter/mterp/mips64/op_unused_3e.S b/runtime/interpreter/mterp/mips64/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_3f.S b/runtime/interpreter/mterp/mips64/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_40.S b/runtime/interpreter/mterp/mips64/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_41.S b/runtime/interpreter/mterp/mips64/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_42.S b/runtime/interpreter/mterp/mips64/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_43.S b/runtime/interpreter/mterp/mips64/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_79.S b/runtime/interpreter/mterp/mips64/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_7a.S b/runtime/interpreter/mterp/mips64/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f3.S b/runtime/interpreter/mterp/mips64/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f4.S b/runtime/interpreter/mterp/mips64/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f5.S b/runtime/interpreter/mterp/mips64/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f6.S b/runtime/interpreter/mterp/mips64/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f7.S b/runtime/interpreter/mterp/mips64/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f8.S b/runtime/interpreter/mterp/mips64/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_f9.S b/runtime/interpreter/mterp/mips64/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_fc.S b/runtime/interpreter/mterp/mips64/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_unused_fd.S b/runtime/interpreter/mterp/mips64/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/mips64/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/mips64/op_ushr_int.S b/runtime/interpreter/mterp/mips64/op_ushr_int.S
deleted file mode 100644
index 98d2dfb..0000000
--- a/runtime/interpreter/mterp/mips64/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop(instr="srl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_ushr_int_2addr.S b/runtime/interpreter/mterp/mips64/op_ushr_int_2addr.S
deleted file mode 100644
index 9b89e21..0000000
--- a/runtime/interpreter/mterp/mips64/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% binop2addr(instr="srl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_ushr_int_lit8.S b/runtime/interpreter/mterp/mips64/op_ushr_int_lit8.S
deleted file mode 100644
index 531c30a..0000000
--- a/runtime/interpreter/mterp/mips64/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(instr="srl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_ushr_long.S b/runtime/interpreter/mterp/mips64/op_ushr_long.S
deleted file mode 100644
index e900f76..0000000
--- a/runtime/interpreter/mterp/mips64/op_ushr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long():
-% binopWide(instr="dsrl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_ushr_long_2addr.S b/runtime/interpreter/mterp/mips64/op_ushr_long_2addr.S
deleted file mode 100644
index e13fc75..0000000
--- a/runtime/interpreter/mterp/mips64/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long_2addr():
-% binopWide2addr(instr="dsrl a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_int.S b/runtime/interpreter/mterp/mips64/op_xor_int.S
deleted file mode 100644
index 1379a34..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_int_2addr.S b/runtime/interpreter/mterp/mips64/op_xor_int_2addr.S
deleted file mode 100644
index 6dbe11c..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_int_lit16.S b/runtime/interpreter/mterp/mips64/op_xor_int_lit16.S
deleted file mode 100644
index f8cbce0..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_int_lit8.S b/runtime/interpreter/mterp/mips64/op_xor_int_lit8.S
deleted file mode 100644
index 268a43a..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_long.S b/runtime/interpreter/mterp/mips64/op_xor_long.S
deleted file mode 100644
index 75d4c07..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/op_xor_long_2addr.S b/runtime/interpreter/mterp/mips64/op_xor_long_2addr.S
deleted file mode 100644
index 2e76613..0000000
--- a/runtime/interpreter/mterp/mips64/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(instr="xor a0, a0, a1")
diff --git a/runtime/interpreter/mterp/mips64/other.S b/runtime/interpreter/mterp/mips64/other.S
new file mode 100644
index 0000000..789efee
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/other.S
@@ -0,0 +1,355 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC
+ lhu a0, 2(rPC) # a0 <- BBBB
+ srl a1, rINST, 8 # a1 <- AA
+ daddu a2, rFP, OFF_FP_SHADOWFRAME
+ move a3, rSELF
+ jal $helper # (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 2 # load rINST
+ bnez v0, MterpPossibleException # let reference interpreter deal with it.
+ ADVANCE 2 # advance rPC
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ b MterpFallback
+
+%def op_const():
+ /* const vAA, #+BBBBbbbb */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- bbbb (low)
+ lh a1, 4(rPC) # a1 <- BBBB (high)
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ ins a0, a1, 16, 16 # a0 = BBBBbbbb
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a2 # vAA <- +BBBBbbbb
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_16():
+ /* const/16 vAA, #+BBBB */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- sign-extended BBBB
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a2 # vAA <- +BBBB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_4():
+ /* const/4 vA, #+B */
+ ext a2, rINST, 8, 4 # a2 <- A
+ seh a0, rINST # sign extend B in rINST
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ sra a0, a0, 12 # shift B into its final position
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a2 # vA <- +B
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, #+BBBB0000 */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- BBBB
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ sll a0, a0, 16 # a0 <- BBBB0000
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG a0, a2 # vAA <- +BBBB0000
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, String//BBBBBBBB */
+ .extern MterpConstString
+ EXPORT_PC
+ lh a0, 2(rPC) # a0 <- bbbb (low)
+ lh a4, 4(rPC) # a4 <- BBBB (high)
+ srl a1, rINST, 8 # a1 <- AA
+ ins a0, a4, 16, 16 # a0 <- BBBBbbbb
+ daddu a2, rFP, OFF_FP_SHADOWFRAME
+ move a3, rSELF
+ jal MterpConstString # (index, tgt_reg, shadow_frame, self)
+ PREFETCH_INST 3 # load rINST
+ bnez v0, MterpPossibleException # let reference interpreter deal with it.
+ ADVANCE 3 # advance rPC
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_wide():
+ /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
+ srl a4, rINST, 8 # a4 <- AA
+ lh a0, 2(rPC) # a0 <- bbbb (low)
+ lh a1, 4(rPC) # a1 <- BBBB (low middle)
+ lh a2, 6(rPC) # a2 <- hhhh (high middle)
+ lh a3, 8(rPC) # a3 <- HHHH (high)
+ FETCH_ADVANCE_INST 5 # advance rPC, load rINST
+ ins a0, a1, 16, 16 # a0 = BBBBbbbb
+ ins a2, a3, 16, 16 # a2 = HHHHhhhh
+ dinsu a0, a2, 32, 32 # a0 = HHHHhhhhBBBBbbbb
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a4 # vAA <- +HHHHhhhhBBBBbbbb
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, #+BBBB */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- sign-extended BBBB
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAA <- +BBBB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, #+BBBBbbbb */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- bbbb (low)
+ lh a1, 4(rPC) # a1 <- BBBB (high)
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ ins a0, a1, 16, 16 # a0 = BBBBbbbb
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAA <- +BBBBbbbb
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, #+BBBB000000000000 */
+ srl a2, rINST, 8 # a2 <- AA
+ lh a0, 2(rPC) # a0 <- BBBB
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ dsll32 a0, a0, 16 # a0 <- BBBB000000000000
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAA <- +BBBB000000000000
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_monitor_enter():
+ /*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ .extern artLockObjectFromCode
+ EXPORT_PC
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG_U a0, a2 # a0 <- vAA (object)
+ move a1, rSELF # a1 <- self
+ jal artLockObjectFromCode
+ bnezc v0, MterpException
+ FETCH_ADVANCE_INST 1
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_monitor_exit():
+ /*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ .extern artUnlockObjectFromCode
+ EXPORT_PC
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG_U a0, a2 # a0 <- vAA (object)
+ move a1, rSELF # a1 <- self
+ jal artUnlockObjectFromCode # v0 <- success for unlock(self, obj)
+ bnezc v0, MterpException
+ FETCH_ADVANCE_INST 1 # before throw: advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ ext a2, rINST, 8, 4 # a2 <- A
+ ext a3, rINST, 12, 4 # a3 <- B
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_VREG a0, a3 # a0 <- vB
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT a0, a2 # vA <- vB
+ .else
+ SET_VREG a0, a2 # vA <- vB
+ .endif
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ lhu a3, 4(rPC) # a3 <- BBBB
+ lhu a2, 2(rPC) # a2 <- AAAA
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ GET_VREG a0, a3 # a0 <- vBBBB
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT a0, a2 # vAAAA <- vBBBB
+ .else
+ SET_VREG a0, a2 # vAAAA <- vBBBB
+ .endif
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_exception():
+ /* move-exception vAA */
+ srl a2, rINST, 8 # a2 <- AA
+ ld a0, THREAD_EXCEPTION_OFFSET(rSELF) # load exception obj
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ SET_VREG_OBJECT a0, a2 # vAA <- exception obj
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ sd zero, THREAD_EXCEPTION_OFFSET(rSELF) # clear exception
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ lhu a3, 2(rPC) # a3 <- BBBB
+ srl a2, rINST, 8 # a2 <- AA
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_VREG a0, a3 # a0 <- vBBBB
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT a0, a2 # vAA <- vBBBB
+ .else
+ SET_VREG a0, a2 # vAA <- vBBBB
+ .endif
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ srl a2, rINST, 8 # a2 <- AA
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ ld a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
+ lw a0, 0(a0) # a0 <- result.i
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ .if $is_object
+ SET_VREG_OBJECT a0, a2 # vAA <- result
+ .else
+ SET_VREG a0, a2 # vAA <- result
+ .endif
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* for: move-result-wide */
+ /* op vAA */
+ srl a2, rINST, 8 # a2 <- AA
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ ld a0, OFF_FP_RESULT_REGISTER(rFP) # get pointer to result JType
+ ld a0, 0(a0) # a0 <- result.j
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAA <- result
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ ext a3, rINST, 12, 4 # a3 <- B
+ ext a2, rINST, 8, 4 # a2 <- A
+ GET_VREG_WIDE a0, a3 # a0 <- vB
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vA <- vB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ lhu a3, 4(rPC) # a3 <- BBBB
+ lhu a2, 2(rPC) # a2 <- AAAA
+ GET_VREG_WIDE a0, a3 # a0 <- vBBBB
+ FETCH_ADVANCE_INST 3 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAAAA <- vBBBB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ lhu a3, 2(rPC) # a3 <- BBBB
+ srl a2, rINST, 8 # a2 <- AA
+ GET_VREG_WIDE a0, a3 # a0 <- vBBBB
+ FETCH_ADVANCE_INST 2 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_WIDE a0, a2 # vAA <- vBBBB
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_nop():
+ FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ GOTO_OPCODE v0 # jump to next instruction
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/mips64/unop.S b/runtime/interpreter/mterp/mips64/unop.S
deleted file mode 100644
index 860e6bb..0000000
--- a/runtime/interpreter/mterp/mips64/unop.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def unop(preinstr="", instr=""):
- /*
- * Generic 32-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "a0 = op a0".
- *
- * for: int-to-byte, int-to-char, int-to-short,
- * not-int, neg-int
- */
- /* unop vA, vB */
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG a0, a3 # a0 <- vB
- ext a2, rINST, 8, 4 # a2 <- A
- $preinstr # optional op
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- $instr # a0 <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG a0, a2 # vA <- a0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/unopWide.S b/runtime/interpreter/mterp/mips64/unopWide.S
deleted file mode 100644
index d0a6f5b..0000000
--- a/runtime/interpreter/mterp/mips64/unopWide.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def unopWide(preinstr="", instr=""):
- /*
- * Generic 64-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "a0 = op a0".
- *
- * For: not-long, neg-long
- */
- /* unop vA, vB */
- ext a3, rINST, 12, 4 # a3 <- B
- GET_VREG_WIDE a0, a3 # a0 <- vB
- ext a2, rINST, 8, 4 # a2 <- A
- $preinstr # optional op
- FETCH_ADVANCE_INST 1 # advance rPC, load rINST
- $instr # a0 <- op, a0-a3 changed
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE a0, a2 # vA <- a0
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/mips64/unused.S b/runtime/interpreter/mterp/mips64/unused.S
deleted file mode 100644
index 3d611d1..0000000
--- a/runtime/interpreter/mterp/mips64/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- b MterpFallback
diff --git a/runtime/interpreter/mterp/mips64/zcmp.S b/runtime/interpreter/mterp/mips64/zcmp.S
deleted file mode 100644
index a0d2832..0000000
--- a/runtime/interpreter/mterp/mips64/zcmp.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def zcmp(condition=""):
- /*
- * Generic one-operand compare-and-branch operation. Provide a "condition"
- * fragment that specifies the comparison to perform, e.g. for
- * "if-lez" you would use "le".
- *
- * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- srl a2, rINST, 8 # a2 <- AA
- lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB)
- GET_VREG a0, a2 # a0 <- vAA
- b${condition}zc a0, MterpCommonTakenBranchNoFlags
- li v0, JIT_CHECK_OSR # possible OSR re-entry?
- beqc rPROFILE, v0, .L_check_not_taken_osr
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index dc476b7..b059564 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -311,6 +311,7 @@
.cfi_endproc
.size \name, .-\name
.endm
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -393,6 +394,7 @@
.global artMterpAsmInstructionStart
artMterpAsmInstructionStart = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -6733,6 +6735,7 @@
mov r0, #0
mov r1, #0
bx lr @ return 0 for NaN
+
/*
* Convert the double in r0/r1 to a long in r0/r1.
*
@@ -6774,6 +6777,7 @@
.global artMterpAsmAltInstructionStart
artMterpAsmAltInstructionStart = .L_ALT_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -11132,6 +11136,7 @@
.hidden artMterpAsmAltInstructionEnd
.global artMterpAsmAltInstructionEnd
artMterpAsmAltInstructionEnd:
+
/*
* ===========================================================================
* Common subroutines and data
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index c8c9cdb..d65019d 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -352,6 +352,7 @@
.cfi_endproc
.size \name, .-\name
.endm
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -424,6 +425,7 @@
.global artMterpAsmInstructionStart
artMterpAsmInstructionStart = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -6235,6 +6237,7 @@
.hidden artMterpAsmSisterEnd
.global artMterpAsmSisterEnd
artMterpAsmSisterEnd:
+
/*
* ===========================================================================
* Common subroutines and data
@@ -6544,6 +6547,7 @@
.global artMterpAsmAltInstructionStart
artMterpAsmAltInstructionStart = .L_ALT_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -10646,6 +10650,7 @@
.hidden artMterpAsmAltInstructionEnd
.global artMterpAsmAltInstructionEnd
artMterpAsmAltInstructionEnd:
+
// Close out the cfi info. We're treating mterp as a single function.
END ExecuteMterpImpl
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index f2f3453..91d4ca1 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -725,6 +725,7 @@
#define LONG_MIN_HIGH 0x80000000
#define LONG_MIN_AS_FLOAT 0xDF000000
#define LONG_MIN_AS_DOUBLE_HIGH 0xC3E00000
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -804,6 +805,7 @@
.global artMterpAsmInstructionStart
artMterpAsmInstructionStart = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -3527,6 +3529,7 @@
div a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#else
/*
* Generic 32-bit binary operation. Provide an "instr" line that
@@ -3559,6 +3562,7 @@
mflo a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#endif
/* ------------------------------ */
@@ -3596,6 +3600,7 @@
mod a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#else
/*
* Generic 32-bit binary operation. Provide an "instr" line that
@@ -3628,6 +3633,7 @@
mfhi a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#endif
/* ------------------------------ */
@@ -4616,6 +4622,7 @@
div a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#else
/*
* Generic 32-bit "/2addr" binary operation. Provide an "instr" line
@@ -4644,6 +4651,7 @@
mflo a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#endif
/* ------------------------------ */
@@ -4677,6 +4685,7 @@
mod a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#else
/*
* Generic 32-bit "/2addr" binary operation. Provide an "instr" line
@@ -4705,6 +4714,7 @@
mfhi a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#endif
/* ------------------------------ */
@@ -5603,6 +5613,7 @@
div a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#else
/*
* Generic 32-bit "lit16" binary operation. Provide an "instr" line
@@ -5631,6 +5642,7 @@
mflo a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#endif
/* ------------------------------ */
@@ -5664,6 +5676,7 @@
mod a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#else
/*
* Generic 32-bit "lit16" binary operation. Provide an "instr" line
@@ -5692,6 +5705,7 @@
mfhi a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vA <- a0
+
#endif
/* ------------------------------ */
@@ -5919,6 +5933,7 @@
div a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#else
/*
* Generic 32-bit "lit8" binary operation. Provide an "instr" line
@@ -5949,6 +5964,7 @@
mflo a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#endif
/* ------------------------------ */
@@ -5984,6 +6000,7 @@
mod a0, a0, a1 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#else
/*
* Generic 32-bit "lit8" binary operation. Provide an "instr" line
@@ -6014,6 +6031,7 @@
mfhi a0 # a0 <- op, a0-a3 changed
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG_GOTO(a0, rOBJ, t0) # vAA <- a0
+
#endif
/* ------------------------------ */
@@ -6739,6 +6757,7 @@
.global artMterpAsmAltInstructionStart
artMterpAsmAltInstructionStart = .L_ALT_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -11095,6 +11114,7 @@
.global artMterpAsmAltInstructionEnd
artMterpAsmAltInstructionEnd:
+
/*
* ===========================================================================
* Common subroutines and data
@@ -11383,3 +11403,4 @@
.cfi_endproc
.end ExecuteMterpImpl
+
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index cf95a57..86b16a1 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -327,6 +327,7 @@
#define LONG_MIN 0x8000000000000000
#define LONG_MIN_AS_FLOAT 0xDF000000
#define LONG_MIN_AS_DOUBLE 0xC3E0000000000000
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -425,6 +426,7 @@
.global artMterpAsmInstructionStart
artMterpAsmInstructionStart = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -2228,6 +2230,7 @@
bnezc v0, MterpFallback
GET_INST_OPCODE v0
GOTO_OPCODE v0
+
/*
* Handle a virtual method call.
*
@@ -2258,6 +2261,7 @@
bnezc v0, MterpFallback
GET_INST_OPCODE v0
GOTO_OPCODE v0
+
/*
* Handle a "super" method call.
*
@@ -2334,6 +2338,7 @@
bnezc v0, MterpFallback
GET_INST_OPCODE v0
GOTO_OPCODE v0
+
/*
* Handle an interface method call.
*
@@ -2586,6 +2591,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
neg.s f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2624,6 +2630,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
neg.d f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2679,6 +2686,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.s.w f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2722,6 +2730,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.d.w f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2783,6 +2792,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.s.l f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2826,6 +2836,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.d.l f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2864,6 +2875,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
trunc.w.s f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2902,6 +2914,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
trunc.l.s f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2945,6 +2958,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.d.s f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -2983,6 +2997,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
trunc.w.d f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -3021,6 +3036,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
trunc.l.d f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -3064,6 +3080,7 @@
srl a2, rINST, 12 # a2 <- B
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+
cvt.s.d f0, f0
/*
* Stores a specified register containing the result of conversion
@@ -6062,6 +6079,7 @@
.global artMterpAsmAltInstructionStart
artMterpAsmAltInstructionStart = .L_ALT_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -10674,6 +10692,7 @@
.global artMterpAsmAltInstructionEnd
artMterpAsmAltInstructionEnd:
+
/*
* We've detected a condition that will result in an exception, but the exception
* has not yet been thrown. Just bail out to the reference interpreter to deal with it.
@@ -10950,3 +10969,4 @@
.cfi_endproc
.set reorder
.size ExecuteMterpImpl, .-ExecuteMterpImpl
+
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 5a1bbf2..fb182fd 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -315,6 +315,7 @@
movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
.endm
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -404,6 +405,7 @@
.global SYMBOL(artMterpAsmInstructionStart)
SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -2532,6 +2534,7 @@
RESTORE_IBASE
FETCH_INST
GOTO_NEXT
+
/*
* Handle a virtual method call.
*
@@ -2567,6 +2570,7 @@
RESTORE_IBASE
FETCH_INST
GOTO_NEXT
+
/*
* Handle a "super" method call.
*
@@ -2658,6 +2662,7 @@
RESTORE_IBASE
FETCH_INST
GOTO_NEXT
+
/*
* Handle an interface method call.
*
@@ -5672,6 +5677,7 @@
.global SYMBOL(artMterpAsmAltInstructionStart)
.text
SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -11566,6 +11572,7 @@
ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
.global SYMBOL(artMterpAsmAltInstructionEnd)
SYMBOL(artMterpAsmAltInstructionEnd):
+
/*
* ===========================================================================
* Common subroutines and data
@@ -11891,3 +11898,4 @@
ret
.cfi_endproc
SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
+
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 1c45059..abb8986 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -301,6 +301,7 @@
movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
.endm
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -386,6 +387,7 @@
.global SYMBOL(artMterpAsmInstructionStart)
SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
.text
+
/* ------------------------------ */
.balign 128
.L_op_nop: /* 0x00 */
@@ -2388,6 +2390,7 @@
jnz MterpFallback
FETCH_INST
GOTO_NEXT
+
/*
* Handle a virtual method call.
*
@@ -2420,6 +2423,7 @@
jnz MterpFallback
FETCH_INST
GOTO_NEXT
+
/*
* Handle a "super" method call.
*
@@ -2502,6 +2506,7 @@
jnz MterpFallback
FETCH_INST
GOTO_NEXT
+
/*
* Handle an interface method call.
*
@@ -5364,6 +5369,7 @@
.global SYMBOL(artMterpAsmAltInstructionStart)
.text
SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
+
/* ------------------------------ */
.balign 128
.L_ALT_op_nop: /* 0x00 */
@@ -10746,6 +10752,7 @@
ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
.global SYMBOL(artMterpAsmAltInstructionEnd)
SYMBOL(artMterpAsmAltInstructionEnd):
+
/*
* ===========================================================================
* Common subroutines and data
@@ -11043,3 +11050,4 @@
ret
.cfi_endproc
SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
+
diff --git a/runtime/interpreter/mterp/x86/alt_stub.S b/runtime/interpreter/mterp/x86/alt_stub.S
deleted file mode 100644
index 79e3f74..0000000
--- a/runtime/interpreter/mterp/x86/alt_stub.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Unlike the Arm handler, we can't do this as a tail call
- * because rIBASE is caller save and we need to reload it.
- *
- * Note that unlike in the Arm implementation, we should never arrive
- * here with a zero breakFlag because we always refresh rIBASE on
- * return.
- */
- .extern MterpCheckBefore
- movl rSELF, %ecx
- movl %ecx, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG1(%esp)
- movl rPC, OUT_ARG2(%esp)
- call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr)
- REFRESH_IBASE
- jmp .L_op_nop+(${opnum}*${handler_size_bytes})
diff --git a/runtime/interpreter/mterp/x86/arithmetic.S b/runtime/interpreter/mterp/x86/arithmetic.S
new file mode 100644
index 0000000..a9fa0fc68
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/arithmetic.S
@@ -0,0 +1,936 @@
+%def bindiv(result="", special="", rem=""):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op0=minint and
+ * op1=-1.
+ */
+ /* div/rem vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB
+ GET_VREG %ecx, %ecx # ecx <- vCC
+ mov rIBASE, LOCAL0(%esp)
+ testl %ecx, %ecx
+ je common_errDivideByZero
+ movl %eax, %edx
+ orl %ecx, %edx
+ testl $$0xFFFFFF00, %edx # If both arguments are less
+ # than 8-bit and +ve
+ jz .L${opcode}_8 # Do 8-bit divide
+ testl $$0xFFFF0000, %edx # If both arguments are less
+ # than 16-bit and +ve
+ jz .L${opcode}_16 # Do 16-bit divide
+ cmpl $$-1, %ecx
+ jne .L${opcode}_32
+ cmpl $$0x80000000, %eax
+ jne .L${opcode}_32
+ movl $special, $result
+ jmp .L${opcode}_finish
+.L${opcode}_32:
+ cltd
+ idivl %ecx
+ jmp .L${opcode}_finish
+.L${opcode}_8:
+ div %cl # 8-bit divide otherwise.
+ # Remainder in %ah, quotient in %al
+ .if $rem
+ movl %eax, %edx
+ shr $$8, %edx
+ .else
+ andl $$0x000000FF, %eax
+ .endif
+ jmp .L${opcode}_finish
+.L${opcode}_16:
+ xorl %edx, %edx # Clear %edx before divide
+ div %cx
+.L${opcode}_finish:
+ SET_VREG $result, rINST
+ mov LOCAL0(%esp), rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def bindiv2addr(result="", special=""):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op0=minint and
+ * op1=-1.
+ */
+ /* div/rem/2addr vA, vB */
+ movzx rINSTbl, %ecx # eax <- BA
+ mov rIBASE, LOCAL0(%esp)
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # eax <- vBB
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, rINST # eax <- vBB
+ testl %ecx, %ecx
+ je common_errDivideByZero
+ cmpl $$-1, %ecx
+ jne .L${opcode}_continue_div2addr
+ cmpl $$0x80000000, %eax
+ jne .L${opcode}_continue_div2addr
+ movl $special, $result
+ SET_VREG $result, rINST
+ mov LOCAL0(%esp), rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+.L${opcode}_continue_div2addr:
+ cltd
+ idivl %ecx
+ SET_VREG $result, rINST
+ mov LOCAL0(%esp), rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def bindivLit16(result="", special=""):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op0=minint and
+ * op1=-1.
+ */
+ /* div/rem/lit16 vA, vB, #+CCCC */
+ /* Need A in rINST, ssssCCCC in ecx, vB in eax */
+ movzbl rINSTbl, %eax # eax <- 000000BA
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %eax # eax <- vB
+ movswl 2(rPC), %ecx # ecx <- ssssCCCC
+ andb $$0xf, rINSTbl # rINST <- A
+ testl %ecx, %ecx
+ je common_errDivideByZero
+ cmpl $$-1, %ecx
+ jne .L${opcode}_continue_div
+ cmpl $$0x80000000, %eax
+ jne .L${opcode}_continue_div
+ movl $special, %eax
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+.L${opcode}_continue_div:
+ mov rIBASE, LOCAL0(%esp)
+ cltd
+ idivl %ecx
+ SET_VREG $result, rINST
+ mov LOCAL0(%esp), rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def bindivLit8(result="", special=""):
+/*
+ * 32-bit div/rem "lit8" binary operation. Handles special case of
+ * op0=minint & op1=-1
+ */
+ /* div/rem/lit8 vAA, vBB, #+CC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movsbl 3(rPC), %ecx # ecx <- ssssssCC
+ GET_VREG %eax, %eax # eax <- rBB
+ testl %ecx, %ecx
+ je common_errDivideByZero
+ cmpl $$0x80000000, %eax
+ jne .L${opcode}_continue_div
+ cmpl $$-1, %ecx
+ jne .L${opcode}_continue_div
+ movl $special, %eax
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+.L${opcode}_continue_div:
+ mov rIBASE, LOCAL0(%esp)
+ cltd
+ idivl %ecx
+ SET_VREG $result, rINST
+ mov LOCAL0(%esp), rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binop(result="%eax", instr=""):
+/*
+ * Generic 32-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than eax, you can override "result".)
+ *
+ * For: add-int, sub-int, and-int, or-int,
+ * xor-int, shl-int, shr-int, ushr-int
+ */
+ /* binop vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB
+ $instr # ex: addl (rFP,%ecx,4),%eax
+ SET_VREG $result, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binop1(result="%eax", tmp="%ecx", instr=""):
+/*
+ * Generic 32-bit binary operation in which both operands loaded to
+ * registers (op0 in eax, op1 in ecx).
+ */
+ /* binop vAA, vBB, vCC */
+ movzbl 2(rPC),%eax # eax <- BB
+ movzbl 3(rPC),%ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB
+ GET_VREG %ecx, %ecx # eax <- vBB
+ $instr # ex: addl %ecx,%eax
+ SET_VREG $result, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binop2addr(result="%eax", instr=""):
+/*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = r0 op r1".
+ * This could be an instruction or a function call.
+ *
+ * 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 */
+ movzx rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ GET_VREG %eax, rINST # eax <- vB
+ andb $$0xf, %cl # ecx <- A
+ $instr # for ex: addl %eax,(rFP,%ecx,4)
+ CLEAR_REF %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def binopLit16(result="%eax", instr=""):
+/*
+ * Generic 32-bit "lit16" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = eax op ecx".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than eax, you can override "result".)
+ *
+ * For: add-int/lit16, rsub-int,
+ * and-int/lit16, or-int/lit16, xor-int/lit16
+ */
+ /* binop/lit16 vA, vB, #+CCCC */
+ movzbl rINSTbl, %eax # eax <- 000000BA
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %eax # eax <- vB
+ movswl 2(rPC), %ecx # ecx <- ssssCCCC
+ andb $$0xf, rINSTbl # rINST <- A
+ $instr # for example: addl %ecx, %eax
+ SET_VREG $result, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopLit8(result="%eax", instr=""):
+/*
+ * Generic 32-bit "lit8" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = eax op ecx".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than r0, you can override "result".)
+ *
+ * For: add-int/lit8, rsub-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 */
+ movzbl 2(rPC), %eax # eax <- BB
+ movsbl 3(rPC), %ecx # ecx <- ssssssCC
+ GET_VREG %eax, %eax # eax <- rBB
+ $instr # ex: addl %ecx,%eax
+ SET_VREG $result, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopWide(instr1="", instr2=""):
+/*
+ * Generic 64-bit binary operation.
+ */
+ /* binop vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ movl rIBASE, LOCAL0(%esp) # save rIBASE
+ GET_VREG rIBASE, %eax # rIBASE <- v[BB+0]
+ GET_VREG_HIGH %eax, %eax # eax <- v[BB+1]
+ $instr1 # ex: addl (rFP,%ecx,4),rIBASE
+ $instr2 # ex: adcl 4(rFP,%ecx,4),%eax
+ SET_VREG rIBASE, rINST # v[AA+0] <- rIBASE
+ movl LOCAL0(%esp), rIBASE # restore rIBASE
+ SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopWide2addr(instr1="", instr2=""):
+/*
+ * Generic 64-bit binary operation.
+ */
+ /* binop/2addr vA, vB */
+ movzbl rINSTbl, %ecx # ecx<- BA
+ sarl $$4, %ecx # ecx<- B
+ GET_VREG %eax, %ecx # eax<- v[B+0]
+ GET_VREG_HIGH %ecx, %ecx # eax<- v[B+1]
+ andb $$0xF, rINSTbl # rINST<- A
+ $instr1 # ex: addl %eax,(rFP,rINST,4)
+ $instr2 # ex: adcl %ecx,4(rFP,rINST,4)
+ CLEAR_WIDE_REF rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def cvtfp_int(srcdouble="1", tgtlong="1"):
+/* On fp to int conversions, Java requires that
+ * if the result > maxint, it should be clamped to maxint. If it is less
+ * than minint, it should be clamped to minint. If it is a nan, the result
+ * should be zero. Further, the rounding mode is to truncate. This model
+ * differs from what is delivered normally via the x86 fpu, so we have
+ * to play some games.
+ */
+ /* float/double to int/long vA, vB */
+ movzbl rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ .if $srcdouble
+ fldl VREG_ADDRESS(rINST) # %st0 <- vB
+ .else
+ flds VREG_ADDRESS(rINST) # %st0 <- vB
+ .endif
+ ftst
+ fnstcw LOCAL0(%esp) # remember original rounding mode
+ movzwl LOCAL0(%esp), %eax
+ movb $$0xc, %ah
+ movw %ax, LOCAL0+2(%esp)
+ fldcw LOCAL0+2(%esp) # set "to zero" rounding mode
+ andb $$0xf, %cl # ecx <- A
+ .if $tgtlong
+ fistpll VREG_ADDRESS(%ecx) # convert and store
+ .else
+ fistpl VREG_ADDRESS(%ecx) # convert and store
+ .endif
+ fldcw LOCAL0(%esp) # restore previous rounding mode
+ .if $tgtlong
+ movl $$0x80000000, %eax
+ xorl VREG_HIGH_ADDRESS(%ecx), %eax
+ orl VREG_ADDRESS(%ecx), %eax
+ .else
+ cmpl $$0x80000000, VREG_ADDRESS(%ecx)
+ .endif
+ je .L${opcode}_special_case # fix up result
+
+.L${opcode}_finish:
+ xor %eax, %eax
+ mov %eax, VREG_REF_ADDRESS(%ecx)
+ .if $tgtlong
+ mov %eax, VREG_REF_HIGH_ADDRESS(%ecx)
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+.L${opcode}_special_case:
+ fnstsw %ax
+ sahf
+ jp .L${opcode}_isNaN
+ adcl $$-1, VREG_ADDRESS(%ecx)
+ .if $tgtlong
+ adcl $$-1, VREG_HIGH_ADDRESS(%ecx)
+ .endif
+ jmp .L${opcode}_finish
+.L${opcode}_isNaN:
+ movl $$0, VREG_ADDRESS(%ecx)
+ .if $tgtlong
+ movl $$0, VREG_HIGH_ADDRESS(%ecx)
+ .endif
+ jmp .L${opcode}_finish
+
+%def shop2addr(result="%eax", instr=""):
+/*
+ * Generic 32-bit "shift/2addr" operation.
+ */
+ /* shift/2addr vA, vB */
+ movzx rINSTbl, %ecx # eax <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # eax <- vBB
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, rINST # eax <- vAA
+ $instr # ex: sarl %cl, %eax
+ SET_VREG $result, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def unop(instr=""):
+/*
+ * Generic 32-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op eax".
+ */
+ /* unop vA, vB */
+ movzbl rINSTbl,%ecx # ecx <- A+
+ sarl $$4,rINST # rINST <- B
+ GET_VREG %eax, rINST # eax <- vB
+ andb $$0xf,%cl # ecx <- A
+ $instr
+ SET_VREG %eax, %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_add_int():
+% binop(instr="addl (rFP,%ecx,4), %eax")
+
+%def op_add_int_2addr():
+% binop2addr(instr="addl %eax, (rFP,%ecx,4)")
+
+%def op_add_int_lit16():
+% binopLit16(instr="addl %ecx, %eax")
+
+%def op_add_int_lit8():
+% binopLit8(instr="addl %ecx, %eax")
+
+%def op_add_long():
+% binopWide(instr1="addl (rFP,%ecx,4), rIBASE", instr2="adcl 4(rFP,%ecx,4), %eax")
+
+%def op_add_long_2addr():
+% binopWide2addr(instr1="addl %eax, (rFP,rINST,4)", instr2="adcl %ecx, 4(rFP,rINST,4)")
+
+%def op_and_int():
+% binop(instr="andl (rFP,%ecx,4), %eax")
+
+%def op_and_int_2addr():
+% binop2addr(instr="andl %eax, (rFP,%ecx,4)")
+
+%def op_and_int_lit16():
+% binopLit16(instr="andl %ecx, %eax")
+
+%def op_and_int_lit8():
+% binopLit8(instr="andl %ecx, %eax")
+
+%def op_and_long():
+% binopWide(instr1="andl (rFP,%ecx,4), rIBASE", instr2="andl 4(rFP,%ecx,4), %eax")
+
+%def op_and_long_2addr():
+% binopWide2addr(instr1="andl %eax, (rFP,rINST,4)", instr2="andl %ecx, 4(rFP,rINST,4)")
+
+%def op_cmp_long():
+/*
+ * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
+ * register based on the results of the comparison.
+ */
+ /* cmp-long vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG_HIGH %eax, %eax # eax <- v[BB+1], BB is clobbered
+ cmpl VREG_HIGH_ADDRESS(%ecx), %eax
+ jl .L${opcode}_smaller
+ jg .L${opcode}_bigger
+ movzbl 2(rPC), %eax # eax <- BB, restore BB
+ GET_VREG %eax, %eax # eax <- v[BB]
+ sub VREG_ADDRESS(%ecx), %eax
+ ja .L${opcode}_bigger
+ jb .L${opcode}_smaller
+.L${opcode}_finish:
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+.L${opcode}_bigger:
+ movl $$1, %eax
+ jmp .L${opcode}_finish
+
+.L${opcode}_smaller:
+ movl $$-1, %eax
+ jmp .L${opcode}_finish
+
+%def op_div_int():
+% bindiv(result="%eax", special="$0x80000000", rem="0")
+
+%def op_div_int_2addr():
+% bindiv2addr(result="%eax", special="$0x80000000")
+
+%def op_div_int_lit16():
+% bindivLit16(result="%eax", special="$0x80000000")
+
+%def op_div_int_lit8():
+% bindivLit8(result="%eax", special="$0x80000000")
+
+%def op_div_long(routine="art_quick_ldiv"):
+/* art_quick_* methods has quick abi,
+ * so use eax, ecx, edx, ebx for args
+ */
+ /* div vAA, vBB, vCC */
+ .extern $routine
+ mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx
+ mov rINST, LOCAL1(%esp) # save rINST/%ebx
+ movzbl 3(rPC), %eax # eax <- CC
+ GET_VREG %ecx, %eax
+ GET_VREG_HIGH %ebx, %eax
+ movl %ecx, %edx
+ orl %ebx, %ecx
+ jz common_errDivideByZero
+ movzbl 2(rPC), %eax # eax <- BB
+ GET_VREG_HIGH %ecx, %eax
+ GET_VREG %eax, %eax
+ call SYMBOL($routine)
+ mov LOCAL1(%esp), rINST # restore rINST/%ebx
+ SET_VREG_HIGH rIBASE, rINST
+ SET_VREG %eax, rINST
+ mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_div_long_2addr(routine="art_quick_ldiv"):
+/* art_quick_* methods has quick abi,
+ * so use eax, ecx, edx, ebx for args
+ */
+ /* div/2addr vA, vB */
+ .extern $routine
+ mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx
+ movzbl rINSTbl, %eax
+ shrl $$4, %eax # eax <- B
+ andb $$0xf, rINSTbl # rINST <- A
+ mov rINST, LOCAL1(%esp) # save rINST/%ebx
+ movl %ebx, %ecx
+ GET_VREG %edx, %eax
+ GET_VREG_HIGH %ebx, %eax
+ movl %edx, %eax
+ orl %ebx, %eax
+ jz common_errDivideByZero
+ GET_VREG %eax, %ecx
+ GET_VREG_HIGH %ecx, %ecx
+ call SYMBOL($routine)
+ mov LOCAL1(%esp), rINST # restore rINST/%ebx
+ SET_VREG_HIGH rIBASE, rINST
+ SET_VREG %eax, rINST
+ mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_int_to_byte():
+% unop(instr="movsbl %al, %eax")
+
+%def op_int_to_char():
+% unop(instr="movzwl %ax,%eax")
+
+%def op_int_to_long():
+ /* int to long vA, vB */
+ movzbl rINSTbl, %eax # eax <- +A
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %eax # eax <- vB
+ andb $$0xf, rINSTbl # rINST <- A
+ movl rIBASE, %ecx # cltd trashes rIBASE/edx
+ cltd # rINST:eax<- sssssssBBBBBBBB
+ SET_VREG_HIGH rIBASE, rINST # v[A+1] <- rIBASE
+ SET_VREG %eax, rINST # v[A+0] <- %eax
+ movl %ecx, rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+
+%def op_int_to_short():
+% unop(instr="movswl %ax, %eax")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+ /*
+ * 32-bit binary multiplication.
+ */
+ /* mul vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB
+ mov rIBASE, LOCAL0(%esp)
+ imull (rFP,%ecx,4), %eax # trashes rIBASE/edx
+ mov LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_mul_int_2addr():
+ /* mul vA, vB */
+ movzx rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ GET_VREG %eax, rINST # eax <- vB
+ andb $$0xf, %cl # ecx <- A
+ movl rIBASE, rINST
+ imull (rFP,%ecx,4), %eax # trashes rIBASE/edx
+ movl rINST, rIBASE
+ SET_VREG %eax, %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_mul_int_lit16():
+ /* mul/lit16 vA, vB, #+CCCC */
+ /* Need A in rINST, ssssCCCC in ecx, vB in eax */
+ movzbl rINSTbl, %eax # eax <- 000000BA
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %eax # eax <- vB
+ movl rIBASE, %ecx
+ movswl 2(rPC), rIBASE # rIBASE <- ssssCCCC
+ andb $$0xf, rINSTbl # rINST <- A
+ imull rIBASE, %eax # trashes rIBASE/edx
+ movl %ecx, rIBASE
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_mul_int_lit8():
+ /* mul/lit8 vAA, vBB, #+CC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movl rIBASE, %ecx
+ GET_VREG %eax, %eax # eax <- rBB
+ movsbl 3(rPC), rIBASE # rIBASE <- ssssssCC
+ imull rIBASE, %eax # trashes rIBASE/edx
+ movl %ecx, rIBASE
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_mul_long():
+/*
+ * Signed 64-bit integer multiply.
+ *
+ * We could definately use more free registers for
+ * this code. We spill rINSTw (ebx),
+ * giving us eax, ebc, ecx and edx as computational
+ * temps. On top of that, we'll spill edi (rFP)
+ * for use as the vB pointer and esi (rPC) for use
+ * as the vC pointer. Yuck.
+ *
+ */
+ /* mul-long vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- B
+ movzbl 3(rPC), %ecx # ecx <- C
+ mov rPC, LOCAL0(%esp) # save Interpreter PC
+ mov rFP, LOCAL1(%esp) # save FP
+ mov rIBASE, LOCAL2(%esp) # save rIBASE
+ leal (rFP,%eax,4), %esi # esi <- &v[B]
+ leal (rFP,%ecx,4), rFP # rFP <- &v[C]
+ movl 4(%esi), %ecx # ecx <- Bmsw
+ imull (rFP), %ecx # ecx <- (Bmsw*Clsw)
+ movl 4(rFP), %eax # eax <- Cmsw
+ imull (%esi), %eax # eax <- (Cmsw*Blsw)
+ addl %eax, %ecx # ecx <- (Bmsw*Clsw)+(Cmsw*Blsw)
+ movl (rFP), %eax # eax <- Clsw
+ mull (%esi) # eax <- (Clsw*Alsw)
+ mov LOCAL0(%esp), rPC # restore Interpreter PC
+ mov LOCAL1(%esp), rFP # restore FP
+ leal (%ecx,rIBASE), rIBASE # full result now in rIBASE:%eax
+ SET_VREG_HIGH rIBASE, rINST # v[B+1] <- rIBASE
+ mov LOCAL2(%esp), rIBASE # restore IBASE
+ SET_VREG %eax, rINST # v[B] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_mul_long_2addr():
+/*
+ * Signed 64-bit integer multiply, 2-addr version
+ *
+ * We could definately use more free registers for
+ * this code. We must spill %edx (rIBASE) because it
+ * is used by imul. We'll also spill rINST (ebx),
+ * giving us eax, ebc, ecx and rIBASE as computational
+ * temps. On top of that, we'll spill %esi (edi)
+ * for use as the vA pointer and rFP (esi) for use
+ * as the vB pointer. Yuck.
+ */
+ /* mul-long/2addr vA, vB */
+ movzbl rINSTbl, %eax # eax <- BA
+ andb $$0xf, %al # eax <- A
+ CLEAR_WIDE_REF %eax # clear refs in advance
+ sarl $$4, rINST # rINST <- B
+ mov rPC, LOCAL0(%esp) # save Interpreter PC
+ mov rFP, LOCAL1(%esp) # save FP
+ mov rIBASE, LOCAL2(%esp) # save rIBASE
+ leal (rFP,%eax,4), %esi # esi <- &v[A]
+ leal (rFP,rINST,4), rFP # rFP <- &v[B]
+ movl 4(%esi), %ecx # ecx <- Amsw
+ imull (rFP), %ecx # ecx <- (Amsw*Blsw)
+ movl 4(rFP), %eax # eax <- Bmsw
+ imull (%esi), %eax # eax <- (Bmsw*Alsw)
+ addl %eax, %ecx # ecx <- (Amsw*Blsw)+(Bmsw*Alsw)
+ movl (rFP), %eax # eax <- Blsw
+ mull (%esi) # eax <- (Blsw*Alsw)
+ leal (%ecx,rIBASE), rIBASE # full result now in %edx:%eax
+ movl rIBASE, 4(%esi) # v[A+1] <- rIBASE
+ movl %eax, (%esi) # v[A] <- %eax
+ mov LOCAL0(%esp), rPC # restore Interpreter PC
+ mov LOCAL2(%esp), rIBASE # restore IBASE
+ mov LOCAL1(%esp), rFP # restore FP
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_neg_int():
+% unop(instr="negl %eax")
+
+%def op_neg_long():
+ /* unop vA, vB */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, %ecx # eax <- v[B+0]
+ GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1]
+ negl %eax
+ adcl $$0, %ecx
+ negl %ecx
+ SET_VREG %eax, rINST # v[A+0] <- eax
+ SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+
+%def op_not_int():
+% unop(instr="notl %eax")
+
+%def op_not_long():
+ /* unop vA, vB */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, %ecx # eax <- v[B+0]
+ GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1]
+ notl %eax
+ notl %ecx
+ SET_VREG %eax, rINST # v[A+0] <- eax
+ SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_or_int():
+% binop(instr="orl (rFP,%ecx,4), %eax")
+
+%def op_or_int_2addr():
+% binop2addr(instr="orl %eax, (rFP,%ecx,4)")
+
+%def op_or_int_lit16():
+% binopLit16(instr="orl %ecx, %eax")
+
+%def op_or_int_lit8():
+% binopLit8(instr="orl %ecx, %eax")
+
+%def op_or_long():
+% binopWide(instr1="orl (rFP,%ecx,4), rIBASE", instr2="orl 4(rFP,%ecx,4), %eax")
+
+%def op_or_long_2addr():
+% binopWide2addr(instr1="orl %eax, (rFP,rINST,4)", instr2="orl %ecx, 4(rFP,rINST,4)")
+
+%def op_rem_int():
+% bindiv(result="rIBASE", special="$0", rem="1")
+
+%def op_rem_int_2addr():
+% bindiv2addr(result="rIBASE", special="$0")
+
+%def op_rem_int_lit16():
+% bindivLit16(result="rIBASE", special="$0")
+
+%def op_rem_int_lit8():
+% bindivLit8(result="rIBASE", special="$0")
+
+%def op_rem_long():
+% op_div_long(routine="art_quick_lmod")
+
+%def op_rem_long_2addr():
+% op_div_long_2addr(routine="art_quick_lmod")
+
+%def op_rsub_int():
+/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
+% binopLit16(instr="subl %eax, %ecx", result="%ecx")
+
+%def op_rsub_int_lit8():
+% binopLit8(instr="subl %eax, %ecx", result="%ecx")
+
+%def op_shl_int():
+% binop1(instr="sall %cl, %eax")
+
+%def op_shl_int_2addr():
+% shop2addr(instr="sall %cl, %eax")
+
+%def op_shl_int_lit8():
+% binopLit8(instr="sall %cl, %eax")
+
+%def op_shl_long():
+/*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance. x86 shifts automatically mask off
+ * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
+ * case specially.
+ */
+ /* shl-long vAA, vBB, vCC */
+ /* ecx gets shift count */
+ /* Need to spill rINST */
+ /* rINSTw gets AA */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, %eax # ecx <- v[BB+1]
+ GET_VREG %ecx, %ecx # ecx <- vCC
+ GET_VREG %eax, %eax # eax <- v[BB+0]
+ shldl %eax,rIBASE
+ sall %cl, %eax
+ testb $$32, %cl
+ je 2f
+ movl %eax, rIBASE
+ xorl %eax, %eax
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[AA+0] <- %eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_shl_long_2addr():
+/*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shl-long/2addr vA, vB */
+ /* ecx gets shift count */
+ /* Need to spill rIBASE */
+ /* rINSTw gets AA */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, rINST # eax <- v[AA+0]
+ sarl $$4, %ecx # ecx <- B
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
+ GET_VREG %ecx, %ecx # ecx <- vBB
+ shldl %eax, rIBASE
+ sall %cl, %eax
+ testb $$32, %cl
+ je 2f
+ movl %eax, rIBASE
+ xorl %eax, %eax
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_shr_int():
+% binop1(instr="sarl %cl, %eax")
+
+%def op_shr_int_2addr():
+% shop2addr(instr="sarl %cl, %eax")
+
+%def op_shr_int_lit8():
+% binopLit8(instr="sarl %cl, %eax")
+
+%def op_shr_long():
+/*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance. x86 shifts automatically mask off
+ * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
+ * case specially.
+ */
+ /* shr-long vAA, vBB, vCC */
+ /* ecx gets shift count */
+ /* Need to spill rIBASE */
+ /* rINSTw gets AA */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, %eax # rIBASE<- v[BB+1]
+ GET_VREG %ecx, %ecx # ecx <- vCC
+ GET_VREG %eax, %eax # eax <- v[BB+0]
+ shrdl rIBASE, %eax
+ sarl %cl, rIBASE
+ testb $$32, %cl
+ je 2f
+ movl rIBASE, %eax
+ sarl $$31, rIBASE
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_shr_long_2addr():
+/*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shl-long/2addr vA, vB */
+ /* ecx gets shift count */
+ /* Need to spill rIBASE */
+ /* rINSTw gets AA */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, rINST # eax <- v[AA+0]
+ sarl $$4, %ecx # ecx <- B
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
+ GET_VREG %ecx, %ecx # ecx <- vBB
+ shrdl rIBASE, %eax
+ sarl %cl, rIBASE
+ testb $$32, %cl
+ je 2f
+ movl rIBASE, %eax
+ sarl $$31, rIBASE
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_sub_int():
+% binop(instr="subl (rFP,%ecx,4), %eax")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="subl %eax, (rFP,%ecx,4)")
+
+%def op_sub_long():
+% binopWide(instr1="subl (rFP,%ecx,4), rIBASE", instr2="sbbl 4(rFP,%ecx,4), %eax")
+
+%def op_sub_long_2addr():
+% binopWide2addr(instr1="subl %eax, (rFP,rINST,4)", instr2="sbbl %ecx, 4(rFP,rINST,4)")
+
+%def op_ushr_int():
+% binop1(instr="shrl %cl, %eax")
+
+%def op_ushr_int_2addr():
+% shop2addr(instr="shrl %cl, %eax")
+
+%def op_ushr_int_lit8():
+% binopLit8(instr="shrl %cl, %eax")
+
+%def op_ushr_long():
+/*
+ * Long integer shift. This is different from the generic 32/64-bit
+ * binary operations because vAA/vBB are 64-bit but vCC (the shift
+ * distance) is 32-bit. Also, Dalvik requires us to mask off the low
+ * 6 bits of the shift distance. x86 shifts automatically mask off
+ * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
+ * case specially.
+ */
+ /* shr-long vAA, vBB, vCC */
+ /* ecx gets shift count */
+ /* Need to spill rIBASE */
+ /* rINSTw gets AA */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, %eax # rIBASE <- v[BB+1]
+ GET_VREG %ecx, %ecx # ecx <- vCC
+ GET_VREG %eax, %eax # eax <- v[BB+0]
+ shrdl rIBASE, %eax
+ shrl %cl, rIBASE
+ testb $$32, %cl
+ je 2f
+ movl rIBASE, %eax
+ xorl rIBASE, rIBASE
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[BB+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_ushr_long_2addr():
+/*
+ * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
+ * 32-bit shift distance.
+ */
+ /* shl-long/2addr vA, vB */
+ /* ecx gets shift count */
+ /* Need to spill rIBASE */
+ /* rINSTw gets AA */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG %eax, rINST # eax <- v[AA+0]
+ sarl $$4, %ecx # ecx <- B
+ movl rIBASE, LOCAL0(%esp)
+ GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
+ GET_VREG %ecx, %ecx # ecx <- vBB
+ shrdl rIBASE, %eax
+ shrl %cl, rIBASE
+ testb $$32, %cl
+ je 2f
+ movl rIBASE, %eax
+ xorl rIBASE, rIBASE
+2:
+ SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
+ movl LOCAL0(%esp), rIBASE
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_xor_int():
+% binop(instr="xorl (rFP,%ecx,4), %eax")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="xorl %eax, (rFP,%ecx,4)")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="xorl %ecx, %eax")
+
+%def op_xor_int_lit8():
+% binopLit8(instr="xorl %ecx, %eax")
+
+%def op_xor_long():
+% binopWide(instr1="xorl (rFP,%ecx,4), rIBASE", instr2="xorl 4(rFP,%ecx,4), %eax")
+
+%def op_xor_long_2addr():
+% binopWide2addr(instr1="xorl %eax, (rFP,rINST,4)", instr2="xorl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/array.S b/runtime/interpreter/mterp/x86/array.S
new file mode 100644
index 0000000..de846a4
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/array.S
@@ -0,0 +1,215 @@
+%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+/*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short
+ *
+ */
+ /* op vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB (array object)
+ GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ $load $data_offset(%eax,%ecx,$shift), %eax
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aget_boolean():
+% op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+/*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB (array object)
+ GET_VREG %ecx, %ecx # ecs <- vCC (requested index)
+ EXPORT_PC
+ movl %eax, OUT_ARG0(%esp)
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(artAGetObjectFromMterp) # (array, index)
+ movl rSELF, %ecx
+ RESTORE_IBASE_FROM_SELF %ecx
+ cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
+ jnz MterpException
+ SET_VREG_OBJECT %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aget_short():
+% op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+/*
+ * Array get, 64 bits. vAA <- vBB[vCC].
+ */
+ /* aget-wide vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB (array object)
+ GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ leal MIRROR_WIDE_ARRAY_DATA_OFFSET(%eax,%ecx,8), %eax
+ movq (%eax), %xmm0 # xmm0 <- vBB[vCC]
+ SET_WIDE_FP_VREG %xmm0, rINST # vAA <- xmm0
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aput(reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
+/*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short
+ *
+ */
+ /* op vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB (array object)
+ GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ leal $data_offset(%eax,%ecx,$shift), %eax
+ GET_VREG rINST, rINST
+ $store $reg, (%eax)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aput_boolean():
+% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+/*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ */
+ /* op vAA, vBB, vCC */
+ EXPORT_PC
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ movl rPC, OUT_ARG1(%esp)
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpAputObject) # (array, index)
+ RESTORE_IBASE
+ testb %al, %al
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aput_short():
+% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+/*
+ * Array put, 64 bits. vBB[vCC] <- vAA.
+ *
+ */
+ /* aput-wide vAA, vBB, vCC */
+ movzbl 2(rPC), %eax # eax <- BB
+ movzbl 3(rPC), %ecx # ecx <- CC
+ GET_VREG %eax, %eax # eax <- vBB (array object)
+ GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ leal MIRROR_WIDE_ARRAY_DATA_OFFSET(%eax,%ecx,8), %eax
+ GET_WIDE_FP_VREG %xmm0, rINST # xmm0 <- vAA
+ movq %xmm0, (%eax) # vBB[vCC] <- xmm0
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_array_length():
+/*
+ * Return the length of an array.
+ */
+ mov rINST, %eax # eax <- BA
+ sarl $$4, rINST # rINST <- B
+ GET_VREG %ecx, rINST # ecx <- vB (object ref)
+ testl %ecx, %ecx # is null?
+ je common_errNullObject
+ andb $$0xf, %al # eax <- A
+ movl MIRROR_ARRAY_LENGTH_OFFSET(%ecx), rINST
+ SET_VREG rINST, %eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ EXPORT_PC
+ movl 2(rPC), %ecx # ecx <- BBBBbbbb
+ leal (rPC,%ecx,2), %ecx # ecx <- PC + BBBBbbbb*2
+ GET_VREG %eax, rINST # eax <- vAA (array object)
+ movl %eax, OUT_ARG0(%esp)
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpFillArrayData) # (obj, payload)
+ REFRESH_IBASE
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+/*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
+ .extern $helper
+ EXPORT_PC
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ movl rPC, OUT_ARG1(%esp)
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG2(%esp)
+ call SYMBOL($helper)
+ REFRESH_IBASE
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+/*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class@CCCC */
+ EXPORT_PC
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ movl rPC, OUT_ARG1(%esp)
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_ARG2(%esp)
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG3(%esp)
+ call SYMBOL(MterpNewArray)
+ RESTORE_IBASE
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/bincmp.S b/runtime/interpreter/mterp/x86/bincmp.S
deleted file mode 100644
index 28ea08e..0000000
--- a/runtime/interpreter/mterp/x86/bincmp.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def bincmp(revcmp=""):
-/*
- * Generic two-operand compare-and-branch operation. Provide a "revcmp"
- * fragment that specifies the *reverse* comparison to perform, e.g.
- * for "if-le" you would use "gt".
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- movzx rINSTbl, %ecx # ecx <- A+
- andb $$0xf, %cl # ecx <- A
- GET_VREG %eax, %ecx # eax <- vA
- sarl $$4, rINST # rINST <- B
- cmpl VREG_ADDRESS(rINST), %eax # compare (vA, vB)
- j${revcmp} 1f
- movswl 2(rPC), rINST # Get signed branch offset
- testl rINST, rINST
- jmp MterpCommonTakenBranch
-1:
- cmpw $$JIT_CHECK_OSR, rPROFILE
- je .L_check_not_taken_osr
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/bindiv.S b/runtime/interpreter/mterp/x86/bindiv.S
deleted file mode 100644
index e59e6ad..0000000
--- a/runtime/interpreter/mterp/x86/bindiv.S
+++ /dev/null
@@ -1,48 +0,0 @@
-%def bindiv(result="", special="", rem=""):
-/*
- * 32-bit binary div/rem operation. Handles special case of op0=minint and
- * op1=-1.
- */
- /* div/rem vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB
- GET_VREG %ecx, %ecx # ecx <- vCC
- mov rIBASE, LOCAL0(%esp)
- testl %ecx, %ecx
- je common_errDivideByZero
- movl %eax, %edx
- orl %ecx, %edx
- testl $$0xFFFFFF00, %edx # If both arguments are less
- # than 8-bit and +ve
- jz .L${opcode}_8 # Do 8-bit divide
- testl $$0xFFFF0000, %edx # If both arguments are less
- # than 16-bit and +ve
- jz .L${opcode}_16 # Do 16-bit divide
- cmpl $$-1, %ecx
- jne .L${opcode}_32
- cmpl $$0x80000000, %eax
- jne .L${opcode}_32
- movl $special, $result
- jmp .L${opcode}_finish
-.L${opcode}_32:
- cltd
- idivl %ecx
- jmp .L${opcode}_finish
-.L${opcode}_8:
- div %cl # 8-bit divide otherwise.
- # Remainder in %ah, quotient in %al
- .if $rem
- movl %eax, %edx
- shr $$8, %edx
- .else
- andl $$0x000000FF, %eax
- .endif
- jmp .L${opcode}_finish
-.L${opcode}_16:
- xorl %edx, %edx # Clear %edx before divide
- div %cx
-.L${opcode}_finish:
- SET_VREG $result, rINST
- mov LOCAL0(%esp), rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/bindiv2addr.S b/runtime/interpreter/mterp/x86/bindiv2addr.S
deleted file mode 100644
index 40c22bb..0000000
--- a/runtime/interpreter/mterp/x86/bindiv2addr.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def bindiv2addr(result="", special=""):
-/*
- * 32-bit binary div/rem operation. Handles special case of op0=minint and
- * op1=-1.
- */
- /* div/rem/2addr vA, vB */
- movzx rINSTbl, %ecx # eax <- BA
- mov rIBASE, LOCAL0(%esp)
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # eax <- vBB
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, rINST # eax <- vBB
- testl %ecx, %ecx
- je common_errDivideByZero
- cmpl $$-1, %ecx
- jne .L${opcode}_continue_div2addr
- cmpl $$0x80000000, %eax
- jne .L${opcode}_continue_div2addr
- movl $special, $result
- SET_VREG $result, rINST
- mov LOCAL0(%esp), rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-
-.L${opcode}_continue_div2addr:
- cltd
- idivl %ecx
- SET_VREG $result, rINST
- mov LOCAL0(%esp), rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/bindivLit16.S b/runtime/interpreter/mterp/x86/bindivLit16.S
deleted file mode 100644
index a89f452..0000000
--- a/runtime/interpreter/mterp/x86/bindivLit16.S
+++ /dev/null
@@ -1,29 +0,0 @@
-%def bindivLit16(result="", special=""):
-/*
- * 32-bit binary div/rem operation. Handles special case of op0=minint and
- * op1=-1.
- */
- /* div/rem/lit16 vA, vB, #+CCCC */
- /* Need A in rINST, ssssCCCC in ecx, vB in eax */
- movzbl rINSTbl, %eax # eax <- 000000BA
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %eax # eax <- vB
- movswl 2(rPC), %ecx # ecx <- ssssCCCC
- andb $$0xf, rINSTbl # rINST <- A
- testl %ecx, %ecx
- je common_errDivideByZero
- cmpl $$-1, %ecx
- jne .L${opcode}_continue_div
- cmpl $$0x80000000, %eax
- jne .L${opcode}_continue_div
- movl $special, %eax
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-
-.L${opcode}_continue_div:
- mov rIBASE, LOCAL0(%esp)
- cltd
- idivl %ecx
- SET_VREG $result, rINST
- mov LOCAL0(%esp), rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/bindivLit8.S b/runtime/interpreter/mterp/x86/bindivLit8.S
deleted file mode 100644
index ce13019..0000000
--- a/runtime/interpreter/mterp/x86/bindivLit8.S
+++ /dev/null
@@ -1,26 +0,0 @@
-%def bindivLit8(result="", special=""):
-/*
- * 32-bit div/rem "lit8" binary operation. Handles special case of
- * op0=minint & op1=-1
- */
- /* div/rem/lit8 vAA, vBB, #+CC */
- movzbl 2(rPC), %eax # eax <- BB
- movsbl 3(rPC), %ecx # ecx <- ssssssCC
- GET_VREG %eax, %eax # eax <- rBB
- testl %ecx, %ecx
- je common_errDivideByZero
- cmpl $$0x80000000, %eax
- jne .L${opcode}_continue_div
- cmpl $$-1, %ecx
- jne .L${opcode}_continue_div
- movl $special, %eax
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-
-.L${opcode}_continue_div:
- mov rIBASE, LOCAL0(%esp)
- cltd
- idivl %ecx
- SET_VREG $result, rINST
- mov LOCAL0(%esp), rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binop.S b/runtime/interpreter/mterp/x86/binop.S
deleted file mode 100644
index c827372..0000000
--- a/runtime/interpreter/mterp/x86/binop.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def binop(result="%eax", instr=""):
-/*
- * Generic 32-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than eax, you can override "result".)
- *
- * For: add-int, sub-int, and-int, or-int,
- * xor-int, shl-int, shr-int, ushr-int
- */
- /* binop vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB
- $instr # ex: addl (rFP,%ecx,4),%eax
- SET_VREG $result, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binop1.S b/runtime/interpreter/mterp/x86/binop1.S
deleted file mode 100644
index e6ae857..0000000
--- a/runtime/interpreter/mterp/x86/binop1.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def binop1(result="%eax", tmp="%ecx", instr=""):
-/*
- * Generic 32-bit binary operation in which both operands loaded to
- * registers (op0 in eax, op1 in ecx).
- */
- /* binop vAA, vBB, vCC */
- movzbl 2(rPC),%eax # eax <- BB
- movzbl 3(rPC),%ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB
- GET_VREG %ecx, %ecx # eax <- vBB
- $instr # ex: addl %ecx,%eax
- SET_VREG $result, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binop2addr.S b/runtime/interpreter/mterp/x86/binop2addr.S
deleted file mode 100644
index 0b74364..0000000
--- a/runtime/interpreter/mterp/x86/binop2addr.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def binop2addr(result="%eax", instr=""):
-/*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = r0 op r1".
- * This could be an instruction or a function call.
- *
- * 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 */
- movzx rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- GET_VREG %eax, rINST # eax <- vB
- andb $$0xf, %cl # ecx <- A
- $instr # for ex: addl %eax,(rFP,%ecx,4)
- CLEAR_REF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/binopLit16.S b/runtime/interpreter/mterp/x86/binopLit16.S
deleted file mode 100644
index 5b162f1..0000000
--- a/runtime/interpreter/mterp/x86/binopLit16.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def binopLit16(result="%eax", instr=""):
-/*
- * Generic 32-bit "lit16" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = eax op ecx".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than eax, you can override "result".)
- *
- * For: add-int/lit16, rsub-int,
- * and-int/lit16, or-int/lit16, xor-int/lit16
- */
- /* binop/lit16 vA, vB, #+CCCC */
- movzbl rINSTbl, %eax # eax <- 000000BA
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %eax # eax <- vB
- movswl 2(rPC), %ecx # ecx <- ssssCCCC
- andb $$0xf, rINSTbl # rINST <- A
- $instr # for example: addl %ecx, %eax
- SET_VREG $result, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binopLit8.S b/runtime/interpreter/mterp/x86/binopLit8.S
deleted file mode 100644
index c2ebc18..0000000
--- a/runtime/interpreter/mterp/x86/binopLit8.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def binopLit8(result="%eax", instr=""):
-/*
- * Generic 32-bit "lit8" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = eax op ecx".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than r0, you can override "result".)
- *
- * For: add-int/lit8, rsub-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 */
- movzbl 2(rPC), %eax # eax <- BB
- movsbl 3(rPC), %ecx # ecx <- ssssssCC
- GET_VREG %eax, %eax # eax <- rBB
- $instr # ex: addl %ecx,%eax
- SET_VREG $result, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binopWide.S b/runtime/interpreter/mterp/x86/binopWide.S
deleted file mode 100644
index 1e878c8..0000000
--- a/runtime/interpreter/mterp/x86/binopWide.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def binopWide(instr1="", instr2=""):
-/*
- * Generic 64-bit binary operation.
- */
- /* binop vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- movl rIBASE, LOCAL0(%esp) # save rIBASE
- GET_VREG rIBASE, %eax # rIBASE <- v[BB+0]
- GET_VREG_HIGH %eax, %eax # eax <- v[BB+1]
- $instr1 # ex: addl (rFP,%ecx,4),rIBASE
- $instr2 # ex: adcl 4(rFP,%ecx,4),%eax
- SET_VREG rIBASE, rINST # v[AA+0] <- rIBASE
- movl LOCAL0(%esp), rIBASE # restore rIBASE
- SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/binopWide2addr.S b/runtime/interpreter/mterp/x86/binopWide2addr.S
deleted file mode 100644
index 65da1df..0000000
--- a/runtime/interpreter/mterp/x86/binopWide2addr.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def binopWide2addr(instr1="", instr2=""):
-/*
- * Generic 64-bit binary operation.
- */
- /* binop/2addr vA, vB */
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG %eax, %ecx # eax<- v[B+0]
- GET_VREG_HIGH %ecx, %ecx # eax<- v[B+1]
- andb $$0xF, rINSTbl # rINST<- A
- $instr1 # ex: addl %eax,(rFP,rINST,4)
- $instr2 # ex: adcl %ecx,4(rFP,rINST,4)
- CLEAR_WIDE_REF rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/const.S b/runtime/interpreter/mterp/x86/const.S
deleted file mode 100644
index aad76bb..0000000
--- a/runtime/interpreter/mterp/x86/const.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- BBBB
- movl %eax, OUT_ARG0(%esp)
- movl rINST, OUT_ARG1(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG2(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
- call SYMBOL($helper) # (index, tgt_reg, shadow_frame, self)
- RESTORE_IBASE
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/control_flow.S b/runtime/interpreter/mterp/x86/control_flow.S
new file mode 100644
index 0000000..74b4fad
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/control_flow.S
@@ -0,0 +1,219 @@
+%def bincmp(revcmp=""):
+/*
+ * Generic two-operand compare-and-branch operation. Provide a "revcmp"
+ * fragment that specifies the *reverse* comparison to perform, e.g.
+ * for "if-le" you would use "gt".
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ movzx rINSTbl, %ecx # ecx <- A+
+ andb $$0xf, %cl # ecx <- A
+ GET_VREG %eax, %ecx # eax <- vA
+ sarl $$4, rINST # rINST <- B
+ cmpl VREG_ADDRESS(rINST), %eax # compare (vA, vB)
+ j${revcmp} 1f
+ movswl 2(rPC), rINST # Get signed branch offset
+ testl rINST, rINST
+ jmp MterpCommonTakenBranch
+1:
+ cmpw $$JIT_CHECK_OSR, rPROFILE
+ je .L_check_not_taken_osr
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def zcmp(revcmp=""):
+/*
+ * Generic one-operand compare-and-branch operation. Provide a "revcmp"
+ * fragment that specifies the *reverse* comparison to perform, e.g.
+ * for "if-le" you would use "gt".
+ *
+ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ cmpl $$0, VREG_ADDRESS(rINST) # compare (vA, 0)
+ j${revcmp} 1f
+ movswl 2(rPC), rINST # fetch signed displacement
+ testl rINST, rINST
+ jmp MterpCommonTakenBranch
+1:
+ cmpw $$JIT_CHECK_OSR, rPROFILE
+ je .L_check_not_taken_osr
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_goto():
+/*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ movsbl rINSTbl, rINST # rINST <- ssssssAA
+ testl rINST, rINST
+ jmp MterpCommonTakenBranch
+
+%def op_goto_16():
+/*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ movswl 2(rPC), rINST # rINST <- ssssAAAA
+ testl rINST, rINST
+ jmp MterpCommonTakenBranch
+
+%def op_goto_32():
+/*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Unlike most opcodes, this one is allowed to branch to itself, so
+ * our "backward branch" test must be "<=0" instead of "<0". Because
+ * we need the V bit set, we'll use an adds to convert from Dalvik
+ * offset to byte offset.
+ */
+ /* goto/32 +AAAAAAAA */
+ movl 2(rPC), rINST # rINST <- AAAAAAAA
+ testl rINST, rINST
+ jmp MterpCommonTakenBranch
+
+%def op_if_eq():
+% bincmp(revcmp="ne")
+
+%def op_if_eqz():
+% zcmp(revcmp="ne")
+
+%def op_if_ge():
+% bincmp(revcmp="l")
+
+%def op_if_gez():
+% zcmp(revcmp="l")
+
+%def op_if_gt():
+% bincmp(revcmp="le")
+
+%def op_if_gtz():
+% zcmp(revcmp="le")
+
+%def op_if_le():
+% bincmp(revcmp="g")
+
+%def op_if_lez():
+% zcmp(revcmp="g")
+
+%def op_if_lt():
+% bincmp(revcmp="ge")
+
+%def op_if_ltz():
+% zcmp(revcmp="ge")
+
+%def op_if_ne():
+% bincmp(revcmp="e")
+
+%def op_if_nez():
+% zcmp(revcmp="e")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+/*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBB */
+ movl 2(rPC), %ecx # ecx <- BBBBbbbb
+ GET_VREG %eax, rINST # eax <- vAA
+ leal (rPC,%ecx,2), %ecx # ecx <- PC + BBBBbbbb*2
+ movl %eax, OUT_ARG1(%esp) # ARG1 <- vAA
+ movl %ecx, OUT_ARG0(%esp) # ARG0 <- switchData
+ call SYMBOL($func)
+ REFRESH_IBASE
+ testl %eax, %eax
+ movl %eax, rINST
+ jmp MterpCommonTakenBranch
+
+%def op_return():
+/*
+ * Return a 32-bit value.
+ *
+ * for: return, return-object
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call SYMBOL(MterpSuspendCheck)
+1:
+ GET_VREG %eax, rINST # eax <- vAA
+ xorl %ecx, %ecx
+ jmp MterpReturn
+
+%def op_return_object():
+% op_return()
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call SYMBOL(MterpSuspendCheck)
+1:
+ xorl %eax, %eax
+ xorl %ecx, %ecx
+ jmp MterpReturn
+
+%def op_return_void_no_barrier():
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call SYMBOL(MterpSuspendCheck)
+1:
+ xorl %eax, %eax
+ xorl %ecx, %ecx
+ jmp MterpReturn
+
+%def op_return_wide():
+/*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call SYMBOL(MterpSuspendCheck)
+1:
+ GET_VREG %eax, rINST # eax <- v[AA+0]
+ GET_VREG_HIGH %ecx, rINST # ecx <- v[AA+1]
+ jmp MterpReturn
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+/*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC
+ GET_VREG %eax, rINST # eax<- vAA (exception object)
+ testl %eax, %eax
+ jz common_errNullObject
+ movl rSELF,%ecx
+ movl %eax, THREAD_EXCEPTION_OFFSET(%ecx)
+ jmp MterpException
diff --git a/runtime/interpreter/mterp/x86/cvtfp_int.S b/runtime/interpreter/mterp/x86/cvtfp_int.S
deleted file mode 100644
index 0bc9908..0000000
--- a/runtime/interpreter/mterp/x86/cvtfp_int.S
+++ /dev/null
@@ -1,61 +0,0 @@
-%def cvtfp_int(srcdouble="1", tgtlong="1"):
-/* On fp to int conversions, Java requires that
- * if the result > maxint, it should be clamped to maxint. If it is less
- * than minint, it should be clamped to minint. If it is a nan, the result
- * should be zero. Further, the rounding mode is to truncate. This model
- * differs from what is delivered normally via the x86 fpu, so we have
- * to play some games.
- */
- /* float/double to int/long vA, vB */
- movzbl rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- .if $srcdouble
- fldl VREG_ADDRESS(rINST) # %st0 <- vB
- .else
- flds VREG_ADDRESS(rINST) # %st0 <- vB
- .endif
- ftst
- fnstcw LOCAL0(%esp) # remember original rounding mode
- movzwl LOCAL0(%esp), %eax
- movb $$0xc, %ah
- movw %ax, LOCAL0+2(%esp)
- fldcw LOCAL0+2(%esp) # set "to zero" rounding mode
- andb $$0xf, %cl # ecx <- A
- .if $tgtlong
- fistpll VREG_ADDRESS(%ecx) # convert and store
- .else
- fistpl VREG_ADDRESS(%ecx) # convert and store
- .endif
- fldcw LOCAL0(%esp) # restore previous rounding mode
- .if $tgtlong
- movl $$0x80000000, %eax
- xorl VREG_HIGH_ADDRESS(%ecx), %eax
- orl VREG_ADDRESS(%ecx), %eax
- .else
- cmpl $$0x80000000, VREG_ADDRESS(%ecx)
- .endif
- je .L${opcode}_special_case # fix up result
-
-.L${opcode}_finish:
- xor %eax, %eax
- mov %eax, VREG_REF_ADDRESS(%ecx)
- .if $tgtlong
- mov %eax, VREG_REF_HIGH_ADDRESS(%ecx)
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-
-.L${opcode}_special_case:
- fnstsw %ax
- sahf
- jp .L${opcode}_isNaN
- adcl $$-1, VREG_ADDRESS(%ecx)
- .if $tgtlong
- adcl $$-1, VREG_HIGH_ADDRESS(%ecx)
- .endif
- jmp .L${opcode}_finish
-.L${opcode}_isNaN:
- movl $$0, VREG_ADDRESS(%ecx)
- .if $tgtlong
- movl $$0, VREG_HIGH_ADDRESS(%ecx)
- .endif
- jmp .L${opcode}_finish
diff --git a/runtime/interpreter/mterp/x86/entry.S b/runtime/interpreter/mterp/x86/entry.S
deleted file mode 100644
index b6291c1..0000000
--- a/runtime/interpreter/mterp/x86/entry.S
+++ /dev/null
@@ -1,84 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Interpreter entry point.
- */
-
- .text
- ASM_HIDDEN SYMBOL(ExecuteMterpImpl)
- .global SYMBOL(ExecuteMterpImpl)
- FUNCTION_TYPE(ExecuteMterpImpl)
-
-/*
- * On entry:
- * 0 Thread* self
- * 1 insns_
- * 2 ShadowFrame
- * 3 JValue* result_register
- *
- */
-
-SYMBOL(ExecuteMterpImpl):
- .cfi_startproc
- .cfi_def_cfa esp, 4
-
- /* Spill callee save regs */
- PUSH %ebp
- PUSH %edi
- PUSH %esi
- PUSH %ebx
-
- /* Allocate frame */
- subl $$FRAME_SIZE, %esp
- .cfi_adjust_cfa_offset FRAME_SIZE
-
- /* Load ShadowFrame pointer */
- movl IN_ARG2(%esp), %edx
-
- /* Remember the return register */
- movl IN_ARG3(%esp), %eax
- movl %eax, SHADOWFRAME_RESULT_REGISTER_OFFSET(%edx)
-
- /* Remember the code_item */
- movl IN_ARG1(%esp), %ecx
- movl %ecx, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(%edx)
-
- /* set up "named" registers */
- movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(%edx), %eax
- leal SHADOWFRAME_VREGS_OFFSET(%edx), rFP
- leal (rFP, %eax, 4), rREFS
- movl SHADOWFRAME_DEX_PC_OFFSET(%edx), %eax
- lea (%ecx, %eax, 2), rPC
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
- EXPORT_PC
-
- /* Set up for backwards branches & osr profiling */
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG2(%esp)
- call SYMBOL(MterpSetUpHotnessCountdown)
-
- /* Starting ibase */
- REFRESH_IBASE
-
- /* start executing the instruction at rPC */
- FETCH_INST
- GOTO_NEXT
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/x86/fallback.S b/runtime/interpreter/mterp/x86/fallback.S
deleted file mode 100644
index e3c2e2b..0000000
--- a/runtime/interpreter/mterp/x86/fallback.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- jmp MterpFallback
-
diff --git a/runtime/interpreter/mterp/x86/field.S b/runtime/interpreter/mterp/x86/field.S
deleted file mode 100644
index 06362d8..0000000
--- a/runtime/interpreter/mterp/x86/field.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def field(helper=""):
- /*
- * General field read / write (iget-* iput-* sget-* sput-*).
- */
- .extern $helper
- REFRESH_INST ${opnum} # fix rINST to include opcode
- movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
- movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
- movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
- call SYMBOL($helper)
- testb %al, %al
- jz MterpPossibleException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/floating_point.S b/runtime/interpreter/mterp/x86/floating_point.S
new file mode 100644
index 0000000..3de1fc8
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/floating_point.S
@@ -0,0 +1,236 @@
+%def fpcmp(suff="d", nanval="pos"):
+/*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x < y) {
+ * return -1;
+ * } else if (x > y) {
+ * return 1;
+ * } else {
+ * return nanval ? 1 : -1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ movzbl 3(rPC), %ecx # ecx<- CC
+ movzbl 2(rPC), %eax # eax<- BB
+ movs${suff} VREG_ADDRESS(%eax), %xmm0
+ xor %eax, %eax
+ ucomis${suff} VREG_ADDRESS(%ecx), %xmm0
+ jp .L${opcode}_nan_is_${nanval}
+ je .L${opcode}_finish
+ jb .L${opcode}_less
+.L${opcode}_nan_is_pos:
+ incl %eax
+ jmp .L${opcode}_finish
+.L${opcode}_nan_is_neg:
+.L${opcode}_less:
+ decl %eax
+.L${opcode}_finish:
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def fpcvt(instr="", load="", store="", wide="0"):
+/*
+ * Generic 32-bit FP conversion operation.
+ */
+ /* unop vA, vB */
+ movzbl rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ $load VREG_ADDRESS(rINST) # %st0 <- vB
+ andb $$0xf, %cl # ecx <- A
+ $instr
+ $store VREG_ADDRESS(%ecx) # vA <- %st0
+ .if $wide
+ CLEAR_WIDE_REF %ecx
+ .else
+ CLEAR_REF %ecx
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def sseBinop(instr="", suff=""):
+ movzbl 2(rPC), %ecx # ecx <- BB
+ movzbl 3(rPC), %eax # eax <- CC
+ movs${suff} VREG_ADDRESS(%ecx), %xmm0 # %xmm0 <- 1st src
+ ${instr}${suff} VREG_ADDRESS(%eax), %xmm0
+ movs${suff} %xmm0, VREG_ADDRESS(rINST) # vAA <- %xmm0
+ pxor %xmm0, %xmm0
+ movs${suff} %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def sseBinop2Addr(instr="", suff=""):
+ movzx rINSTbl, %ecx # ecx <- A+
+ andl $$0xf, %ecx # ecx <- A
+ movs${suff} VREG_ADDRESS(%ecx), %xmm0 # %xmm0 <- 1st src
+ sarl $$4, rINST # rINST<- B
+ ${instr}${suff} VREG_ADDRESS(rINST), %xmm0
+ movs${suff} %xmm0, VREG_ADDRESS(%ecx) # vAA<- %xmm0
+ pxor %xmm0, %xmm0
+ movs${suff} %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_add_double():
+% sseBinop(instr="adds", suff="d")
+
+%def op_add_double_2addr():
+% sseBinop2Addr(instr="adds", suff="d")
+
+%def op_add_float():
+% sseBinop(instr="adds", suff="s")
+
+%def op_add_float_2addr():
+% sseBinop2Addr(instr="adds", suff="s")
+
+%def op_cmpg_double():
+% fpcmp(suff="d", nanval="pos")
+
+%def op_cmpg_float():
+% fpcmp(suff="s", nanval="pos")
+
+%def op_cmpl_double():
+% fpcmp(suff="d", nanval="neg")
+
+%def op_cmpl_float():
+% fpcmp(suff="s", nanval="neg")
+
+%def op_div_double():
+% sseBinop(instr="divs", suff="d")
+
+%def op_div_double_2addr():
+% sseBinop2Addr(instr="divs", suff="d")
+
+%def op_div_float():
+% sseBinop(instr="divs", suff="s")
+
+%def op_div_float_2addr():
+% sseBinop2Addr(instr="divs", suff="s")
+
+%def op_double_to_float():
+% fpcvt(load="fldl", store="fstps")
+
+%def op_double_to_int():
+% cvtfp_int(srcdouble="1", tgtlong="0")
+
+%def op_double_to_long():
+% cvtfp_int(srcdouble="1", tgtlong="1")
+
+%def op_float_to_double():
+% fpcvt(load="flds", store="fstpl", wide="1")
+
+%def op_float_to_int():
+% cvtfp_int(srcdouble="0", tgtlong="0")
+
+%def op_float_to_long():
+% cvtfp_int(srcdouble="0", tgtlong="1")
+
+%def op_int_to_double():
+% fpcvt(load="fildl", store="fstpl", wide="1")
+
+%def op_int_to_float():
+% fpcvt(load="fildl", store="fstps")
+
+%def op_long_to_double():
+% fpcvt(load="fildll", store="fstpl", wide="1")
+
+%def op_long_to_float():
+% fpcvt(load="fildll", store="fstps")
+
+%def op_mul_double():
+% sseBinop(instr="muls", suff="d")
+
+%def op_mul_double_2addr():
+% sseBinop2Addr(instr="muls", suff="d")
+
+%def op_mul_float():
+% sseBinop(instr="muls", suff="s")
+
+%def op_mul_float_2addr():
+% sseBinop2Addr(instr="muls", suff="s")
+
+%def op_neg_double():
+% fpcvt(instr="fchs", load="fldl", store="fstpl", wide="1")
+
+%def op_neg_float():
+% fpcvt(instr="fchs", load="flds", store="fstps")
+
+%def op_rem_double():
+ /* rem_double vAA, vBB, vCC */
+ movzbl 3(rPC), %ecx # ecx <- BB
+ movzbl 2(rPC), %eax # eax <- CC
+ fldl VREG_ADDRESS(%ecx) # %st1 <- fp[vBB]
+ fldl VREG_ADDRESS(%eax) # %st0 <- fp[vCC]
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstpl VREG_ADDRESS(rINST) # fp[vAA] <- %st
+ CLEAR_WIDE_REF rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_rem_double_2addr():
+ /* rem_double/2addr vA, vB */
+ movzx rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ fldl VREG_ADDRESS(rINST) # vB to fp stack
+ andb $$0xf, %cl # ecx <- A
+ fldl VREG_ADDRESS(%ecx) # vA to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstpl VREG_ADDRESS(%ecx) # %st to vA
+ CLEAR_WIDE_REF %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_rem_float():
+ /* rem_float vAA, vBB, vCC */
+ movzbl 3(rPC), %ecx # ecx <- BB
+ movzbl 2(rPC), %eax # eax <- CC
+ flds VREG_ADDRESS(%ecx) # vBB to fp stack
+ flds VREG_ADDRESS(%eax) # vCC to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstps VREG_ADDRESS(rINST) # %st to vAA
+ CLEAR_REF rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_rem_float_2addr():
+ /* rem_float/2addr vA, vB */
+ movzx rINSTbl, %ecx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ flds VREG_ADDRESS(rINST) # vB to fp stack
+ andb $$0xf, %cl # ecx <- A
+ flds VREG_ADDRESS(%ecx) # vA to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstps VREG_ADDRESS(%ecx) # %st to vA
+ CLEAR_REF %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_sub_double():
+% sseBinop(instr="subs", suff="d")
+
+%def op_sub_double_2addr():
+% sseBinop2Addr(instr="subs", suff="d")
+
+%def op_sub_float():
+% sseBinop(instr="subs", suff="s")
+
+%def op_sub_float_2addr():
+% sseBinop2Addr(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86/footer.S b/runtime/interpreter/mterp/x86/footer.S
deleted file mode 100644
index 31cc067..0000000
--- a/runtime/interpreter/mterp/x86/footer.S
+++ /dev/null
@@ -1,326 +0,0 @@
-%def footer():
-/*
- * ===========================================================================
- * Common subroutines and data
- * ===========================================================================
- */
-
- .text
- .align 2
-
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-common_errDivideByZero:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogDivideByZeroException)
-#endif
- jmp MterpCommonFallback
-
-common_errArrayIndex:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogArrayIndexException)
-#endif
- jmp MterpCommonFallback
-
-common_errNegativeArraySize:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogNegativeArraySizeException)
-#endif
- jmp MterpCommonFallback
-
-common_errNoSuchMethod:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogNoSuchMethodException)
-#endif
- jmp MterpCommonFallback
-
-common_errNullObject:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogNullObjectException)
-#endif
- jmp MterpCommonFallback
-
-common_exceptionThrown:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG0(%esp)
- call SYMBOL(MterpLogExceptionThrownException)
-#endif
- jmp MterpCommonFallback
-
-MterpSuspendFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG0(%esp)
- movl THREAD_FLAGS_OFFSET(%eax), %eax
- movl %eax, OUT_ARG2(%esp)
- call SYMBOL(MterpLogSuspendFallback)
-#endif
- jmp MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- movl rSELF, %eax
- testl $$-1, THREAD_EXCEPTION_OFFSET(%eax)
- jz MterpFallback
- /* intentional fallthrough - handle pending exception. */
-
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
-MterpException:
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpHandleException)
- testb %al, %al
- jz MterpExceptionReturn
- movl OFF_FP_DEX_INSTRUCTIONS(rFP), %eax
- movl OFF_FP_DEX_PC(rFP), %ecx
- lea (%eax, %ecx, 2), rPC
- movl rPC, OFF_FP_DEX_PC_PTR(rFP)
- /* Do we need to switch interpreters? */
- call SYMBOL(MterpShouldSwitchInterpreters)
- testb %al, %al
- jnz MterpFallback
- /* resume execution at catch block */
- REFRESH_IBASE
- FETCH_INST
- GOTO_NEXT
- /* NOTE: no fallthrough */
-
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * rINST <= signed offset
- * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- *
- */
-MterpCommonTakenBranch:
- jg .L_forward_branch # don't add forward branches to hotness
-/*
- * We need to subtract 1 from positive values and we should not see 0 here,
- * so we may use the result of the comparison with -1.
- */
-#if JIT_CHECK_OSR != -1
-# error "JIT_CHECK_OSR must be -1."
-#endif
- cmpw $$JIT_CHECK_OSR, rPROFILE
- je .L_osr_check
- decw rPROFILE
- je .L_add_batch # counted down to zero - report
-.L_resume_backward_branch:
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- leal (rPC, rINST, 2), rPC
- FETCH_INST
- jnz .L_suspend_request_pending
- REFRESH_IBASE
- GOTO_NEXT
-
-.L_suspend_request_pending:
- EXPORT_PC
- movl %eax, OUT_ARG0(%esp) # rSELF in eax
- call SYMBOL(MterpSuspendCheck) # (self)
- testb %al, %al
- jnz MterpFallback
- REFRESH_IBASE # might have changed during suspend
- GOTO_NEXT
-
-.L_no_count_backwards:
- cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
- jne .L_resume_backward_branch
-.L_osr_check:
- EXPORT_PC
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- jz .L_resume_backward_branch
- jmp MterpOnStackReplacement
-
-.L_forward_branch:
- cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
- je .L_check_osr_forward
-.L_resume_forward_branch:
- leal (rPC, rINST, 2), rPC
- FETCH_INST
- GOTO_NEXT
-
-.L_check_osr_forward:
- EXPORT_PC
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- REFRESH_IBASE
- jz .L_resume_forward_branch
- jmp MterpOnStackReplacement
-
-.L_add_batch:
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG2(%esp)
- call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- jmp .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- EXPORT_PC
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl $$2, OUT_ARG2(%esp)
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- REFRESH_IBASE
- jnz MterpOnStackReplacement
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpLogOSR)
-#endif
- movl $$1, %eax
- jmp MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
-MterpFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- movl rSELF, %eax
- movl %eax, OUT_ARG0(%esp)
- lea OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpLogFallback)
-#endif
-MterpCommonFallback:
- xor %eax, %eax
- jmp MterpDone
-
-/*
- * On entry:
- * uint32_t* rFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- movl $$1, %eax
- jmp MterpDone
-MterpReturn:
- movl OFF_FP_RESULT_REGISTER(rFP), %edx
- movl %eax, (%edx)
- movl %ecx, 4(%edx)
- mov $$1, %eax
-MterpDone:
-/*
- * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- cmpw $$0, rPROFILE
- jle MRestoreFrame # if > 0, we may have some counts to report.
-
- movl %eax, rINST # stash return value
- /* Report cached hotness counts */
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG2(%esp)
- call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- movl rINST, %eax # restore return value
-
- /* pop up frame */
-MRestoreFrame:
- addl $$FRAME_SIZE, %esp
- .cfi_adjust_cfa_offset -FRAME_SIZE
-
- /* Restore callee save register */
- POP %ebx
- POP %esi
- POP %edi
- POP %ebp
- ret
- .cfi_endproc
- SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
diff --git a/runtime/interpreter/mterp/x86/fpcmp.S b/runtime/interpreter/mterp/x86/fpcmp.S
deleted file mode 100644
index 7cd18f6..0000000
--- a/runtime/interpreter/mterp/x86/fpcmp.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def fpcmp(suff="d", nanval="pos"):
-/*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x < y) {
- * return -1;
- * } else if (x > y) {
- * return 1;
- * } else {
- * return nanval ? 1 : -1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- movzbl 3(rPC), %ecx # ecx<- CC
- movzbl 2(rPC), %eax # eax<- BB
- movs${suff} VREG_ADDRESS(%eax), %xmm0
- xor %eax, %eax
- ucomis${suff} VREG_ADDRESS(%ecx), %xmm0
- jp .L${opcode}_nan_is_${nanval}
- je .L${opcode}_finish
- jb .L${opcode}_less
-.L${opcode}_nan_is_pos:
- incl %eax
- jmp .L${opcode}_finish
-.L${opcode}_nan_is_neg:
-.L${opcode}_less:
- decl %eax
-.L${opcode}_finish:
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/fpcvt.S b/runtime/interpreter/mterp/x86/fpcvt.S
deleted file mode 100644
index 4280f15..0000000
--- a/runtime/interpreter/mterp/x86/fpcvt.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def fpcvt(instr="", load="", store="", wide="0"):
-/*
- * Generic 32-bit FP conversion operation.
- */
- /* unop vA, vB */
- movzbl rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- $load VREG_ADDRESS(rINST) # %st0 <- vB
- andb $$0xf, %cl # ecx <- A
- $instr
- $store VREG_ADDRESS(%ecx) # vA <- %st0
- .if $wide
- CLEAR_WIDE_REF %ecx
- .else
- CLEAR_REF %ecx
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/header.S b/runtime/interpreter/mterp/x86/header.S
deleted file mode 100644
index f0d14fe..0000000
--- a/runtime/interpreter/mterp/x86/header.S
+++ /dev/null
@@ -1,317 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- Art assembly interpreter notes:
-
- First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
- handle invoke, allows higher-level code to create frame & shadow frame.
-
- Once that's working, support direct entry code & eliminate shadow frame (and
- excess locals allocation.
-
- Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
- base of the vreg array within the shadow frame. Access the other fields,
- dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
- the shadow frame mechanism of double-storing object references - via rFP &
- number_of_vregs_.
-
- */
-
-/*
-x86 ABI general notes:
-
-Caller save set:
- eax, edx, ecx, st(0)-st(7)
-Callee save set:
- ebx, esi, edi, ebp
-Return regs:
- 32-bit in eax
- 64-bit in edx:eax (low-order 32 in eax)
- fp on top of fp stack st(0)
-
-Parameters passed on stack, pushed right-to-left. On entry to target, first
-parm is at 4(%esp). Traditional entry code is:
-
-functEntry:
- push %ebp # save old frame pointer
- mov %ebp,%esp # establish new frame pointer
- sub FrameSize,%esp # Allocate storage for spill, locals & outs
-
-Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp)
-
-Stack must be 16-byte aligned to support SSE in native code.
-
-If we're not doing variable stack allocation (alloca), the frame pointer can be
-eliminated and all arg references adjusted to be esp relative.
-*/
-
-/*
-Mterp and x86 notes:
-
-Some key interpreter variables will be assigned to registers.
-
- nick reg purpose
- rPC esi interpreted program counter, used for fetching instructions
- rFP edi interpreted frame pointer, used for accessing locals and args
- rINSTw bx first 16-bit code of current instruction
- rINSTbl bl opcode portion of instruction word
- rINSTbh bh high byte of inst word, usually contains src/tgt reg names
- rIBASE edx base of instruction handler table
- rREFS ebp base of object references in shadow frame.
-
-Notes:
- o High order 16 bits of ebx must be zero on entry to handler
- o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
- o eax and ecx are scratch, rINSTw/ebx sometimes scratch
-
-Macros are provided for common operations. Each macro MUST emit only
-one instruction to make instruction-counting easier. They MUST NOT alter
-unspecified registers or condition codes.
-*/
-
-/*
- * This is a #include, not a %include, because we want the C pre-processor
- * to expand the macros into assembler assignment statements.
- */
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-/*
- * Handle mac compiler specific
- */
-#if defined(__APPLE__)
- #define MACRO_LITERAL(value) $$(value)
- #define FUNCTION_TYPE(name)
- #define OBJECT_TYPE(name)
- #define SIZE(start,end)
- // Mac OS' symbols have an _ prefix.
- #define SYMBOL(name) _ ## name
- #define ASM_HIDDEN .private_extern
-#else
- #define MACRO_LITERAL(value) $$value
- #define FUNCTION_TYPE(name) .type name, @function
- #define OBJECT_TYPE(name) .type name, @object
- #define SIZE(start,end) .size start, .-end
- #define SYMBOL(name) name
- #define ASM_HIDDEN .hidden
-#endif
-
-.macro PUSH _reg
- pushl \_reg
- .cfi_adjust_cfa_offset 4
- .cfi_rel_offset \_reg, 0
-.endm
-
-.macro POP _reg
- popl \_reg
- .cfi_adjust_cfa_offset -4
- .cfi_restore \_reg
-.endm
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET)
-#define OFF_FP_SHADOWFRAME OFF_FP(0)
-
-/* Frame size must be 16-byte aligned.
- * Remember about 4 bytes for return address + 4 * 4 for spills
- */
-#define FRAME_SIZE 28
-
-/* Frame diagram while executing ExecuteMterpImpl, high to low addresses */
-#define IN_ARG3 (FRAME_SIZE + 16 + 16)
-#define IN_ARG2 (FRAME_SIZE + 16 + 12)
-#define IN_ARG1 (FRAME_SIZE + 16 + 8)
-#define IN_ARG0 (FRAME_SIZE + 16 + 4)
-/* Spill offsets relative to %esp */
-#define LOCAL0 (FRAME_SIZE - 4)
-#define LOCAL1 (FRAME_SIZE - 8)
-#define LOCAL2 (FRAME_SIZE - 12)
-/* Out Arg offsets, relative to %esp */
-#define OUT_ARG3 ( 12)
-#define OUT_ARG2 ( 8)
-#define OUT_ARG1 ( 4)
-#define OUT_ARG0 ( 0) /* <- ExecuteMterpImpl esp + 0 */
-
-/* During bringup, we'll use the shadow frame model instead of rFP */
-/* single-purpose registers, given names for clarity */
-#define rSELF IN_ARG0(%esp)
-#define rPC %esi
-#define CFI_DEX 6 // DWARF register number of the register holding dex-pc (esi).
-#define CFI_TMP 0 // DWARF register number of the first argument register (eax).
-#define rFP %edi
-#define rINST %ebx
-#define rINSTw %bx
-#define rINSTbh %bh
-#define rINSTbl %bl
-#define rIBASE %edx
-#define rREFS %ebp
-#define rPROFILE OFF_FP_COUNTDOWN_OFFSET(rFP)
-
-#define MTERP_LOGGING 0
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-.macro EXPORT_PC
- movl rPC, OFF_FP_DEX_PC_PTR(rFP)
-.endm
-
-/*
- * Refresh handler table.
- */
-.macro REFRESH_IBASE
- movl rSELF, rIBASE
- movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE
-.endm
-
-/*
- * Refresh handler table.
- * IBase handles uses the caller save register so we must restore it after each call.
- * Also it is used as a result of some 64-bit operations (like imul) and we should
- * restore it in such cases also.
- *
- * TODO: Consider spilling the IBase instead of restoring it from Thread structure.
- */
-.macro RESTORE_IBASE
- movl rSELF, rIBASE
- movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE
-.endm
-
-/*
- * If rSELF is already loaded then we can use it from known reg.
- */
-.macro RESTORE_IBASE_FROM_SELF _reg
- movl THREAD_CURRENT_IBASE_OFFSET(\_reg), rIBASE
-.endm
-
-/*
- * Refresh rINST.
- * At enter to handler rINST does not contain the opcode number.
- * However some utilities require the full value, so this macro
- * restores the opcode number.
- */
-.macro REFRESH_INST _opnum
- movb rINSTbl, rINSTbh
- movb MACRO_LITERAL(\_opnum), rINSTbl
-.endm
-
-/*
- * Fetch the next instruction from rPC into rINSTw. Does not advance rPC.
- */
-.macro FETCH_INST
- movzwl (rPC), rINST
-.endm
-
-/*
- * Remove opcode from rINST, compute the address of handler and jump to it.
- */
-.macro GOTO_NEXT
- movzx rINSTbl,%eax
- movzbl rINSTbh,rINST
- shll MACRO_LITERAL(${handler_size_bits}), %eax
- addl rIBASE, %eax
- jmp *%eax
-.endm
-
-/*
- * Advance rPC by instruction count.
- */
-.macro ADVANCE_PC _count
- leal 2*\_count(rPC), rPC
-.endm
-
-/*
- * Advance rPC by instruction count, fetch instruction and jump to handler.
- */
-.macro ADVANCE_PC_FETCH_AND_GOTO_NEXT _count
- ADVANCE_PC \_count
- FETCH_INST
- GOTO_NEXT
-.endm
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- */
-#define VREG_ADDRESS(_vreg) (rFP,_vreg,4)
-#define VREG_HIGH_ADDRESS(_vreg) 4(rFP,_vreg,4)
-#define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4)
-#define VREG_REF_HIGH_ADDRESS(_vreg) 4(rREFS,_vreg,4)
-
-.macro GET_VREG _reg _vreg
- movl (rFP,\_vreg,4), \_reg
-.endm
-
-/* Read wide value to xmm. */
-.macro GET_WIDE_FP_VREG _reg _vreg
- movq (rFP,\_vreg,4), \_reg
-.endm
-
-.macro SET_VREG _reg _vreg
- movl \_reg, (rFP,\_vreg,4)
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
-.endm
-
-/* Write wide value from xmm. xmm is clobbered. */
-.macro SET_WIDE_FP_VREG _reg _vreg
- movq \_reg, (rFP,\_vreg,4)
- pxor \_reg, \_reg
- movq \_reg, (rREFS,\_vreg,4)
-.endm
-
-.macro SET_VREG_OBJECT _reg _vreg
- movl \_reg, (rFP,\_vreg,4)
- movl \_reg, (rREFS,\_vreg,4)
-.endm
-
-.macro GET_VREG_HIGH _reg _vreg
- movl 4(rFP,\_vreg,4), \_reg
-.endm
-
-.macro SET_VREG_HIGH _reg _vreg
- movl \_reg, 4(rFP,\_vreg,4)
- movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
-.endm
-
-.macro CLEAR_REF _vreg
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
-.endm
-
-.macro CLEAR_WIDE_REF _vreg
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
- movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
-.endm
diff --git a/runtime/interpreter/mterp/x86/instruction_end.S b/runtime/interpreter/mterp/x86/instruction_end.S
deleted file mode 100644
index 5a24b66..0000000
--- a/runtime/interpreter/mterp/x86/instruction_end.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end():
-
- OBJECT_TYPE(artMterpAsmInstructionEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmInstructionEnd)
- .global SYMBOL(artMterpAsmInstructionEnd)
-SYMBOL(artMterpAsmInstructionEnd):
diff --git a/runtime/interpreter/mterp/x86/instruction_end_alt.S b/runtime/interpreter/mterp/x86/instruction_end_alt.S
deleted file mode 100644
index d037db9..0000000
--- a/runtime/interpreter/mterp/x86/instruction_end_alt.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_alt():
-
- OBJECT_TYPE(artMterpAsmAltInstructionEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
- .global SYMBOL(artMterpAsmAltInstructionEnd)
-SYMBOL(artMterpAsmAltInstructionEnd):
diff --git a/runtime/interpreter/mterp/x86/instruction_end_sister.S b/runtime/interpreter/mterp/x86/instruction_end_sister.S
deleted file mode 100644
index 7b1ec89..0000000
--- a/runtime/interpreter/mterp/x86/instruction_end_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_sister():
-
- OBJECT_TYPE(artMterpAsmSisterEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmSisterEnd)
- .global SYMBOL(artMterpAsmSisterEnd)
-SYMBOL(artMterpAsmSisterEnd):
diff --git a/runtime/interpreter/mterp/x86/instruction_start.S b/runtime/interpreter/mterp/x86/instruction_start.S
deleted file mode 100644
index dee581b..0000000
--- a/runtime/interpreter/mterp/x86/instruction_start.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start():
-
- OBJECT_TYPE(artMterpAsmInstructionStart)
- ASM_HIDDEN SYMBOL(artMterpAsmInstructionStart)
- .global SYMBOL(artMterpAsmInstructionStart)
-SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/x86/instruction_start_alt.S b/runtime/interpreter/mterp/x86/instruction_start_alt.S
deleted file mode 100644
index 66650e7..0000000
--- a/runtime/interpreter/mterp/x86/instruction_start_alt.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start_alt():
-
- OBJECT_TYPE(artMterpAsmAltInstructionStart)
- ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart)
- .global SYMBOL(artMterpAsmAltInstructionStart)
- .text
-SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
diff --git a/runtime/interpreter/mterp/x86/instruction_start_sister.S b/runtime/interpreter/mterp/x86/instruction_start_sister.S
deleted file mode 100644
index 8c156ad..0000000
--- a/runtime/interpreter/mterp/x86/instruction_start_sister.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def instruction_start_sister():
-
- OBJECT_TYPE(artMterpAsmSisterStart)
- ASM_HIDDEN SYMBOL(artMterpAsmSisterStart)
- .global SYMBOL(artMterpAsmSisterStart)
- .text
- .balign 4
-SYMBOL(artMterpAsmSisterStart):
diff --git a/runtime/interpreter/mterp/x86/invoke.S b/runtime/interpreter/mterp/x86/invoke.S
index eb5cdbc..587c4cf 100644
--- a/runtime/interpreter/mterp/x86/invoke.S
+++ b/runtime/interpreter/mterp/x86/invoke.S
@@ -23,3 +23,99 @@
RESTORE_IBASE
FETCH_INST
GOTO_NEXT
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ EXPORT_PC
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG1(%esp)
+ movl rPC, OUT_ARG2(%esp)
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_ARG3(%esp)
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpException
+ ADVANCE_PC 4
+ call SYMBOL(MterpShouldSwitchInterpreters)
+ testb %al, %al
+ jnz MterpFallback
+ RESTORE_IBASE
+ FETCH_INST
+ GOTO_NEXT
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+/*
+ * Handle an interface method call.
+ *
+ * for: invoke-interface, invoke-interface/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+/*
+ * Handle a "super" method call.
+ *
+ * for: invoke-super, invoke-super/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+/*
+ * Handle a virtual method call.
+ *
+ * for: invoke-virtual, invoke-virtual/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/x86/invoke_polymorphic.S b/runtime/interpreter/mterp/x86/invoke_polymorphic.S
deleted file mode 100644
index 63196ec..0000000
--- a/runtime/interpreter/mterp/x86/invoke_polymorphic.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- EXPORT_PC
- movl rSELF, %ecx
- movl %ecx, OUT_ARG0(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG1(%esp)
- movl rPC, OUT_ARG2(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG3(%esp)
- call SYMBOL($helper)
- testb %al, %al
- jz MterpException
- ADVANCE_PC 4
- call SYMBOL(MterpShouldSwitchInterpreters)
- testb %al, %al
- jnz MterpFallback
- RESTORE_IBASE
- FETCH_INST
- GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86/main.S b/runtime/interpreter/mterp/x86/main.S
new file mode 100644
index 0000000..2dec6b4
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/main.S
@@ -0,0 +1,801 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ Art assembly interpreter notes:
+
+ First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
+ handle invoke, allows higher-level code to create frame & shadow frame.
+
+ Once that's working, support direct entry code & eliminate shadow frame (and
+ excess locals allocation.
+
+ Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
+ base of the vreg array within the shadow frame. Access the other fields,
+ dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
+ the shadow frame mechanism of double-storing object references - via rFP &
+ number_of_vregs_.
+
+ */
+
+/*
+x86 ABI general notes:
+
+Caller save set:
+ eax, edx, ecx, st(0)-st(7)
+Callee save set:
+ ebx, esi, edi, ebp
+Return regs:
+ 32-bit in eax
+ 64-bit in edx:eax (low-order 32 in eax)
+ fp on top of fp stack st(0)
+
+Parameters passed on stack, pushed right-to-left. On entry to target, first
+parm is at 4(%esp). Traditional entry code is:
+
+functEntry:
+ push %ebp # save old frame pointer
+ mov %ebp,%esp # establish new frame pointer
+ sub FrameSize,%esp # Allocate storage for spill, locals & outs
+
+Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp)
+
+Stack must be 16-byte aligned to support SSE in native code.
+
+If we're not doing variable stack allocation (alloca), the frame pointer can be
+eliminated and all arg references adjusted to be esp relative.
+*/
+
+/*
+Mterp and x86 notes:
+
+Some key interpreter variables will be assigned to registers.
+
+ nick reg purpose
+ rPC esi interpreted program counter, used for fetching instructions
+ rFP edi interpreted frame pointer, used for accessing locals and args
+ rINSTw bx first 16-bit code of current instruction
+ rINSTbl bl opcode portion of instruction word
+ rINSTbh bh high byte of inst word, usually contains src/tgt reg names
+ rIBASE edx base of instruction handler table
+ rREFS ebp base of object references in shadow frame.
+
+Notes:
+ o High order 16 bits of ebx must be zero on entry to handler
+ o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
+ o eax and ecx are scratch, rINSTw/ebx sometimes scratch
+
+Macros are provided for common operations. Each macro MUST emit only
+one instruction to make instruction-counting easier. They MUST NOT alter
+unspecified registers or condition codes.
+*/
+
+/*
+ * This is a #include, not a %include, because we want the C pre-processor
+ * to expand the macros into assembler assignment statements.
+ */
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * Handle mac compiler specific
+ */
+#if defined(__APPLE__)
+ #define MACRO_LITERAL(value) $$(value)
+ #define FUNCTION_TYPE(name)
+ #define OBJECT_TYPE(name)
+ #define SIZE(start,end)
+ // Mac OS' symbols have an _ prefix.
+ #define SYMBOL(name) _ ## name
+ #define ASM_HIDDEN .private_extern
+#else
+ #define MACRO_LITERAL(value) $$value
+ #define FUNCTION_TYPE(name) .type name, @function
+ #define OBJECT_TYPE(name) .type name, @object
+ #define SIZE(start,end) .size start, .-end
+ #define SYMBOL(name) name
+ #define ASM_HIDDEN .hidden
+#endif
+
+.macro PUSH _reg
+ pushl \_reg
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset \_reg, 0
+.endm
+
+.macro POP _reg
+ popl \_reg
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore \_reg
+.endm
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET)
+#define OFF_FP_SHADOWFRAME OFF_FP(0)
+
+/* Frame size must be 16-byte aligned.
+ * Remember about 4 bytes for return address + 4 * 4 for spills
+ */
+#define FRAME_SIZE 28
+
+/* Frame diagram while executing ExecuteMterpImpl, high to low addresses */
+#define IN_ARG3 (FRAME_SIZE + 16 + 16)
+#define IN_ARG2 (FRAME_SIZE + 16 + 12)
+#define IN_ARG1 (FRAME_SIZE + 16 + 8)
+#define IN_ARG0 (FRAME_SIZE + 16 + 4)
+/* Spill offsets relative to %esp */
+#define LOCAL0 (FRAME_SIZE - 4)
+#define LOCAL1 (FRAME_SIZE - 8)
+#define LOCAL2 (FRAME_SIZE - 12)
+/* Out Arg offsets, relative to %esp */
+#define OUT_ARG3 ( 12)
+#define OUT_ARG2 ( 8)
+#define OUT_ARG1 ( 4)
+#define OUT_ARG0 ( 0) /* <- ExecuteMterpImpl esp + 0 */
+
+/* During bringup, we'll use the shadow frame model instead of rFP */
+/* single-purpose registers, given names for clarity */
+#define rSELF IN_ARG0(%esp)
+#define rPC %esi
+#define CFI_DEX 6 // DWARF register number of the register holding dex-pc (esi).
+#define CFI_TMP 0 // DWARF register number of the first argument register (eax).
+#define rFP %edi
+#define rINST %ebx
+#define rINSTw %bx
+#define rINSTbh %bh
+#define rINSTbl %bl
+#define rIBASE %edx
+#define rREFS %ebp
+#define rPROFILE OFF_FP_COUNTDOWN_OFFSET(rFP)
+
+#define MTERP_LOGGING 0
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+.macro EXPORT_PC
+ movl rPC, OFF_FP_DEX_PC_PTR(rFP)
+.endm
+
+/*
+ * Refresh handler table.
+ */
+.macro REFRESH_IBASE
+ movl rSELF, rIBASE
+ movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE
+.endm
+
+/*
+ * Refresh handler table.
+ * IBase handles uses the caller save register so we must restore it after each call.
+ * Also it is used as a result of some 64-bit operations (like imul) and we should
+ * restore it in such cases also.
+ *
+ * TODO: Consider spilling the IBase instead of restoring it from Thread structure.
+ */
+.macro RESTORE_IBASE
+ movl rSELF, rIBASE
+ movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE
+.endm
+
+/*
+ * If rSELF is already loaded then we can use it from known reg.
+ */
+.macro RESTORE_IBASE_FROM_SELF _reg
+ movl THREAD_CURRENT_IBASE_OFFSET(\_reg), rIBASE
+.endm
+
+/*
+ * Refresh rINST.
+ * At enter to handler rINST does not contain the opcode number.
+ * However some utilities require the full value, so this macro
+ * restores the opcode number.
+ */
+.macro REFRESH_INST _opnum
+ movb rINSTbl, rINSTbh
+ movb MACRO_LITERAL(\_opnum), rINSTbl
+.endm
+
+/*
+ * Fetch the next instruction from rPC into rINSTw. Does not advance rPC.
+ */
+.macro FETCH_INST
+ movzwl (rPC), rINST
+.endm
+
+/*
+ * Remove opcode from rINST, compute the address of handler and jump to it.
+ */
+.macro GOTO_NEXT
+ movzx rINSTbl,%eax
+ movzbl rINSTbh,rINST
+ shll MACRO_LITERAL(${handler_size_bits}), %eax
+ addl rIBASE, %eax
+ jmp *%eax
+.endm
+
+/*
+ * Advance rPC by instruction count.
+ */
+.macro ADVANCE_PC _count
+ leal 2*\_count(rPC), rPC
+.endm
+
+/*
+ * Advance rPC by instruction count, fetch instruction and jump to handler.
+ */
+.macro ADVANCE_PC_FETCH_AND_GOTO_NEXT _count
+ ADVANCE_PC \_count
+ FETCH_INST
+ GOTO_NEXT
+.endm
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ */
+#define VREG_ADDRESS(_vreg) (rFP,_vreg,4)
+#define VREG_HIGH_ADDRESS(_vreg) 4(rFP,_vreg,4)
+#define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4)
+#define VREG_REF_HIGH_ADDRESS(_vreg) 4(rREFS,_vreg,4)
+
+.macro GET_VREG _reg _vreg
+ movl (rFP,\_vreg,4), \_reg
+.endm
+
+/* Read wide value to xmm. */
+.macro GET_WIDE_FP_VREG _reg _vreg
+ movq (rFP,\_vreg,4), \_reg
+.endm
+
+.macro SET_VREG _reg _vreg
+ movl \_reg, (rFP,\_vreg,4)
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+.endm
+
+/* Write wide value from xmm. xmm is clobbered. */
+.macro SET_WIDE_FP_VREG _reg _vreg
+ movq \_reg, (rFP,\_vreg,4)
+ pxor \_reg, \_reg
+ movq \_reg, (rREFS,\_vreg,4)
+.endm
+
+.macro SET_VREG_OBJECT _reg _vreg
+ movl \_reg, (rFP,\_vreg,4)
+ movl \_reg, (rREFS,\_vreg,4)
+.endm
+
+.macro GET_VREG_HIGH _reg _vreg
+ movl 4(rFP,\_vreg,4), \_reg
+.endm
+
+.macro SET_VREG_HIGH _reg _vreg
+ movl \_reg, 4(rFP,\_vreg,4)
+ movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
+.endm
+
+.macro CLEAR_REF _vreg
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+.endm
+
+.macro CLEAR_WIDE_REF _vreg
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+ movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
+.endm
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Interpreter entry point.
+ */
+
+ .text
+ ASM_HIDDEN SYMBOL(ExecuteMterpImpl)
+ .global SYMBOL(ExecuteMterpImpl)
+ FUNCTION_TYPE(ExecuteMterpImpl)
+
+/*
+ * On entry:
+ * 0 Thread* self
+ * 1 insns_
+ * 2 ShadowFrame
+ * 3 JValue* result_register
+ *
+ */
+
+SYMBOL(ExecuteMterpImpl):
+ .cfi_startproc
+ .cfi_def_cfa esp, 4
+
+ /* Spill callee save regs */
+ PUSH %ebp
+ PUSH %edi
+ PUSH %esi
+ PUSH %ebx
+
+ /* Allocate frame */
+ subl $$FRAME_SIZE, %esp
+ .cfi_adjust_cfa_offset FRAME_SIZE
+
+ /* Load ShadowFrame pointer */
+ movl IN_ARG2(%esp), %edx
+
+ /* Remember the return register */
+ movl IN_ARG3(%esp), %eax
+ movl %eax, SHADOWFRAME_RESULT_REGISTER_OFFSET(%edx)
+
+ /* Remember the code_item */
+ movl IN_ARG1(%esp), %ecx
+ movl %ecx, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(%edx)
+
+ /* set up "named" registers */
+ movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(%edx), %eax
+ leal SHADOWFRAME_VREGS_OFFSET(%edx), rFP
+ leal (rFP, %eax, 4), rREFS
+ movl SHADOWFRAME_DEX_PC_OFFSET(%edx), %eax
+ lea (%ecx, %eax, 2), rPC
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+ EXPORT_PC
+
+ /* Set up for backwards branches & osr profiling */
+ movl OFF_FP_METHOD(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG2(%esp)
+ call SYMBOL(MterpSetUpHotnessCountdown)
+
+ /* Starting ibase */
+ REFRESH_IBASE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST
+ GOTO_NEXT
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Unlike the Arm handler, we can't do this as a tail call
+ * because rIBASE is caller save and we need to reload it.
+ *
+ * Note that unlike in the Arm implementation, we should never arrive
+ * here with a zero breakFlag because we always refresh rIBASE on
+ * return.
+ */
+ .extern MterpCheckBefore
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG1(%esp)
+ movl rPC, OUT_ARG2(%esp)
+ call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr)
+ REFRESH_IBASE
+ jmp .L_op_nop+(${opnum}*${handler_size_bytes})
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ jmp MterpFallback
+
+
+%def footer():
+/*
+ * ===========================================================================
+ * Common subroutines and data
+ * ===========================================================================
+ */
+
+ .text
+ .align 2
+
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+common_errDivideByZero:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogDivideByZeroException)
+#endif
+ jmp MterpCommonFallback
+
+common_errArrayIndex:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogArrayIndexException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNegativeArraySize:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogNegativeArraySizeException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNoSuchMethod:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogNoSuchMethodException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNullObject:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogNullObjectException)
+#endif
+ jmp MterpCommonFallback
+
+common_exceptionThrown:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG0(%esp)
+ call SYMBOL(MterpLogExceptionThrownException)
+#endif
+ jmp MterpCommonFallback
+
+MterpSuspendFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG0(%esp)
+ movl THREAD_FLAGS_OFFSET(%eax), %eax
+ movl %eax, OUT_ARG2(%esp)
+ call SYMBOL(MterpLogSuspendFallback)
+#endif
+ jmp MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ movl rSELF, %eax
+ testl $$-1, THREAD_EXCEPTION_OFFSET(%eax)
+ jz MterpFallback
+ /* intentional fallthrough - handle pending exception. */
+
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+MterpException:
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpHandleException)
+ testb %al, %al
+ jz MterpExceptionReturn
+ movl OFF_FP_DEX_INSTRUCTIONS(rFP), %eax
+ movl OFF_FP_DEX_PC(rFP), %ecx
+ lea (%eax, %ecx, 2), rPC
+ movl rPC, OFF_FP_DEX_PC_PTR(rFP)
+ /* Do we need to switch interpreters? */
+ call SYMBOL(MterpShouldSwitchInterpreters)
+ testb %al, %al
+ jnz MterpFallback
+ /* resume execution at catch block */
+ REFRESH_IBASE
+ FETCH_INST
+ GOTO_NEXT
+ /* NOTE: no fallthrough */
+
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * rINST <= signed offset
+ * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ *
+ */
+MterpCommonTakenBranch:
+ jg .L_forward_branch # don't add forward branches to hotness
+/*
+ * We need to subtract 1 from positive values and we should not see 0 here,
+ * so we may use the result of the comparison with -1.
+ */
+#if JIT_CHECK_OSR != -1
+# error "JIT_CHECK_OSR must be -1."
+#endif
+ cmpw $$JIT_CHECK_OSR, rPROFILE
+ je .L_osr_check
+ decw rPROFILE
+ je .L_add_batch # counted down to zero - report
+.L_resume_backward_branch:
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ leal (rPC, rINST, 2), rPC
+ FETCH_INST
+ jnz .L_suspend_request_pending
+ REFRESH_IBASE
+ GOTO_NEXT
+
+.L_suspend_request_pending:
+ EXPORT_PC
+ movl %eax, OUT_ARG0(%esp) # rSELF in eax
+ call SYMBOL(MterpSuspendCheck) # (self)
+ testb %al, %al
+ jnz MterpFallback
+ REFRESH_IBASE # might have changed during suspend
+ GOTO_NEXT
+
+.L_no_count_backwards:
+ cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
+ jne .L_resume_backward_branch
+.L_osr_check:
+ EXPORT_PC
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ jz .L_resume_backward_branch
+ jmp MterpOnStackReplacement
+
+.L_forward_branch:
+ cmpw $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
+ je .L_check_osr_forward
+.L_resume_forward_branch:
+ leal (rPC, rINST, 2), rPC
+ FETCH_INST
+ GOTO_NEXT
+
+.L_check_osr_forward:
+ EXPORT_PC
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ REFRESH_IBASE
+ jz .L_resume_forward_branch
+ jmp MterpOnStackReplacement
+
+.L_add_batch:
+ movl OFF_FP_METHOD(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG2(%esp)
+ call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ jmp .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ EXPORT_PC
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl $$2, OUT_ARG2(%esp)
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ REFRESH_IBASE
+ jnz MterpOnStackReplacement
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpLogOSR)
+#endif
+ movl $$1, %eax
+ jmp MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+MterpFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movl rSELF, %eax
+ movl %eax, OUT_ARG0(%esp)
+ lea OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ call SYMBOL(MterpLogFallback)
+#endif
+MterpCommonFallback:
+ xor %eax, %eax
+ jmp MterpDone
+
+/*
+ * On entry:
+ * uint32_t* rFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ movl $$1, %eax
+ jmp MterpDone
+MterpReturn:
+ movl OFF_FP_RESULT_REGISTER(rFP), %edx
+ movl %eax, (%edx)
+ movl %ecx, 4(%edx)
+ mov $$1, %eax
+MterpDone:
+/*
+ * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ cmpw $$0, rPROFILE
+ jle MRestoreFrame # if > 0, we may have some counts to report.
+
+ movl %eax, rINST # stash return value
+ /* Report cached hotness counts */
+ movl OFF_FP_METHOD(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG2(%esp)
+ call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ movl rINST, %eax # restore return value
+
+ /* pop up frame */
+MRestoreFrame:
+ addl $$FRAME_SIZE, %esp
+ .cfi_adjust_cfa_offset -FRAME_SIZE
+
+ /* Restore callee save register */
+ POP %ebx
+ POP %esi
+ POP %edi
+ POP %ebp
+ ret
+ .cfi_endproc
+ SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
+
+%def instruction_end():
+
+ OBJECT_TYPE(artMterpAsmInstructionEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmInstructionEnd)
+ .global SYMBOL(artMterpAsmInstructionEnd)
+SYMBOL(artMterpAsmInstructionEnd):
+
+%def instruction_end_alt():
+
+ OBJECT_TYPE(artMterpAsmAltInstructionEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
+ .global SYMBOL(artMterpAsmAltInstructionEnd)
+SYMBOL(artMterpAsmAltInstructionEnd):
+
+%def instruction_end_sister():
+
+ OBJECT_TYPE(artMterpAsmSisterEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmSisterEnd)
+ .global SYMBOL(artMterpAsmSisterEnd)
+SYMBOL(artMterpAsmSisterEnd):
+
+%def instruction_start():
+
+ OBJECT_TYPE(artMterpAsmInstructionStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmInstructionStart)
+ .global SYMBOL(artMterpAsmInstructionStart)
+SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ OBJECT_TYPE(artMterpAsmAltInstructionStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart)
+ .global SYMBOL(artMterpAsmAltInstructionStart)
+ .text
+SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
+
+%def instruction_start_sister():
+
+ OBJECT_TYPE(artMterpAsmSisterStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmSisterStart)
+ .global SYMBOL(artMterpAsmSisterStart)
+ .text
+ .balign 4
+SYMBOL(artMterpAsmSisterStart):
diff --git a/runtime/interpreter/mterp/x86/object.S b/runtime/interpreter/mterp/x86/object.S
new file mode 100644
index 0000000..a47fa3a
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/object.S
@@ -0,0 +1,278 @@
+%def field(helper=""):
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_check_cast():
+/*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class@BBBB */
+ EXPORT_PC
+ movzwl 2(rPC), %eax # eax <- BBBB
+ movl %eax, OUT_ARG0(%esp)
+ leal VREG_ADDRESS(rINST), %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ movl OFF_FP_METHOD(rFP),%eax
+ movl %eax, OUT_ARG2(%esp)
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG3(%esp)
+ call SYMBOL(MterpCheckCast) # (index, &obj, method, self)
+ RESTORE_IBASE
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="movsbl")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="movsbl")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="movzwl")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset@CCCC */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # vB (object we're operating on)
+ movzwl 2(rPC), %eax # eax <- field byte offset
+ movl %ecx, OUT_ARG0(%esp)
+ movl %eax, OUT_ARG1(%esp)
+ EXPORT_PC
+ call SYMBOL(artIGetObjectFromMterp) # (obj, offset)
+ movl rSELF, %ecx
+ RESTORE_IBASE_FROM_SELF %ecx
+ cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
+ jnz MterpException # bail out
+ andb $$0xf,rINSTbl # rINST <- A
+ SET_VREG_OBJECT %eax, rINST # fp[A] <- value
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget_quick(load="movl"):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
+ /* op vA, vB, offset@CCCC */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # vB (object we're operating on)
+ movzwl 2(rPC), %eax # eax <- field byte offset
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ ${load} (%ecx,%eax,1), %eax
+ andb $$0xf,rINSTbl # rINST <- A
+ SET_VREG %eax, rINST # fp[A] <- value
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="movswl")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+ /* iget-wide-quick vA, vB, offset@CCCC */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # vB (object we're operating on)
+ movzwl 2(rPC), %eax # eax <- field byte offset
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ movq (%ecx,%eax,1), %xmm0
+ andb $$0xf, rINSTbl # rINST <- A
+ SET_WIDE_FP_VREG %xmm0, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_instance_of():
+/*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class@CCCC */
+ EXPORT_PC
+ movzwl 2(rPC), %eax # eax <- BBBB
+ movl %eax, OUT_ARG0(%esp)
+ movl rINST, %eax # eax <- BA
+ sarl $$4, %eax # eax <- B
+ leal VREG_ADDRESS(%eax), %ecx # Get object address
+ movl %ecx, OUT_ARG1(%esp)
+ movl OFF_FP_METHOD(rFP),%eax
+ movl %eax, OUT_ARG2(%esp)
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG3(%esp)
+ call SYMBOL(MterpInstanceOf) # (index, &obj, method, self)
+ movl rSELF, %ecx
+ RESTORE_IBASE_FROM_SELF %ecx
+ cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
+ jnz MterpException
+ andb $$0xf, rINSTbl # rINSTbl <- A
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(reg="rINSTbl", store="movb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(reg="rINSTbl", store="movb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(reg="rINSTw", store="movw")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ EXPORT_PC
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ movl rPC, OUT_ARG1(%esp)
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpIputObjectQuick)
+ testb %al, %al
+ jz MterpException
+ RESTORE_IBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput_quick(reg="rINST", store="movl"):
+ /* For: iput-quick, iput-object-quick */
+ /* op vA, vB, offset@CCCC */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %ecx # vB (object we're operating on)
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG rINST, rINST # rINST <- v[A]
+ movzwl 2(rPC), %eax # eax <- field byte offset
+ ${store} ${reg}, (%ecx,%eax,1)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(reg="rINSTw", store="movw")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset@CCCC */
+ movzbl rINSTbl, %ecx # ecx<- BA
+ sarl $$4, %ecx # ecx<- B
+ GET_VREG %ecx, %ecx # vB (object we're operating on)
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ movzwl 2(rPC), %eax # eax<- field byte offset
+ leal (%ecx,%eax,1), %ecx # ecx<- Address of 64-bit target
+ andb $$0xf, rINSTbl # rINST<- A
+ GET_WIDE_FP_VREG %xmm0, rINST # xmm0<- fp[A]/fp[A+1]
+ movq %xmm0, (%ecx) # obj.field<- r0/r1
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_new_instance():
+/*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class@BBBB */
+ EXPORT_PC
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG0(%esp)
+ movl rSELF, %ecx
+ movl %ecx, OUT_ARG1(%esp)
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_ARG2(%esp)
+ call SYMBOL(MterpNewInstance)
+ RESTORE_IBASE
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/x86/op_add_double.S b/runtime/interpreter/mterp/x86/op_add_double.S
deleted file mode 100644
index a009239..0000000
--- a/runtime/interpreter/mterp/x86/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% sseBinop(instr="adds", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_add_double_2addr.S b/runtime/interpreter/mterp/x86/op_add_double_2addr.S
deleted file mode 100644
index 8cb45a9..0000000
--- a/runtime/interpreter/mterp/x86/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% sseBinop2Addr(instr="adds", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_add_float.S b/runtime/interpreter/mterp/x86/op_add_float.S
deleted file mode 100644
index dee28c7..0000000
--- a/runtime/interpreter/mterp/x86/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% sseBinop(instr="adds", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_add_float_2addr.S b/runtime/interpreter/mterp/x86/op_add_float_2addr.S
deleted file mode 100644
index 4deb445..0000000
--- a/runtime/interpreter/mterp/x86/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% sseBinop2Addr(instr="adds", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_add_int.S b/runtime/interpreter/mterp/x86/op_add_int.S
deleted file mode 100644
index 9c4455a..0000000
--- a/runtime/interpreter/mterp/x86/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="addl (rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_add_int_2addr.S b/runtime/interpreter/mterp/x86/op_add_int_2addr.S
deleted file mode 100644
index b04ae4c..0000000
--- a/runtime/interpreter/mterp/x86/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="addl %eax, (rFP,%ecx,4)")
diff --git a/runtime/interpreter/mterp/x86/op_add_int_lit16.S b/runtime/interpreter/mterp/x86/op_add_int_lit16.S
deleted file mode 100644
index a431030..0000000
--- a/runtime/interpreter/mterp/x86/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="addl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_add_int_lit8.S b/runtime/interpreter/mterp/x86/op_add_int_lit8.S
deleted file mode 100644
index 3205aee..0000000
--- a/runtime/interpreter/mterp/x86/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(instr="addl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_add_long.S b/runtime/interpreter/mterp/x86/op_add_long.S
deleted file mode 100644
index 24a9226..0000000
--- a/runtime/interpreter/mterp/x86/op_add_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long():
-% binopWide(instr1="addl (rFP,%ecx,4), rIBASE", instr2="adcl 4(rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_add_long_2addr.S b/runtime/interpreter/mterp/x86/op_add_long_2addr.S
deleted file mode 100644
index e020714..0000000
--- a/runtime/interpreter/mterp/x86/op_add_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long_2addr():
-% binopWide2addr(instr1="addl %eax, (rFP,rINST,4)", instr2="adcl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/op_aget.S b/runtime/interpreter/mterp/x86/op_aget.S
deleted file mode 100644
index fc57a91..0000000
--- a/runtime/interpreter/mterp/x86/op_aget.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
-/*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short
- *
- */
- /* op vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB (array object)
- GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- $load $data_offset(%eax,%ecx,$shift), %eax
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_aget_boolean.S b/runtime/interpreter/mterp/x86/op_aget_boolean.S
deleted file mode 100644
index 279e6fc..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aget_byte.S b/runtime/interpreter/mterp/x86/op_aget_byte.S
deleted file mode 100644
index 1989450..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aget_char.S b/runtime/interpreter/mterp/x86/op_aget_char.S
deleted file mode 100644
index a35269b..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aget_object.S b/runtime/interpreter/mterp/x86/op_aget_object.S
deleted file mode 100644
index 4cf90e9..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_object.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_aget_object():
-/*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB (array object)
- GET_VREG %ecx, %ecx # ecs <- vCC (requested index)
- EXPORT_PC
- movl %eax, OUT_ARG0(%esp)
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(artAGetObjectFromMterp) # (array, index)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- SET_VREG_OBJECT %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_aget_short.S b/runtime/interpreter/mterp/x86/op_aget_short.S
deleted file mode 100644
index ca51ec8..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aget_wide.S b/runtime/interpreter/mterp/x86/op_aget_wide.S
deleted file mode 100644
index 03cf50a..0000000
--- a/runtime/interpreter/mterp/x86/op_aget_wide.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_aget_wide():
-/*
- * Array get, 64 bits. vAA <- vBB[vCC].
- */
- /* aget-wide vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB (array object)
- GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- leal MIRROR_WIDE_ARRAY_DATA_OFFSET(%eax,%ecx,8), %eax
- movq (%eax), %xmm0 # xmm0 <- vBB[vCC]
- SET_WIDE_FP_VREG %xmm0, rINST # vAA <- xmm0
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_and_int.S b/runtime/interpreter/mterp/x86/op_and_int.S
deleted file mode 100644
index ffa28d7..0000000
--- a/runtime/interpreter/mterp/x86/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="andl (rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_and_int_2addr.S b/runtime/interpreter/mterp/x86/op_and_int_2addr.S
deleted file mode 100644
index 8648980..0000000
--- a/runtime/interpreter/mterp/x86/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="andl %eax, (rFP,%ecx,4)")
diff --git a/runtime/interpreter/mterp/x86/op_and_int_lit16.S b/runtime/interpreter/mterp/x86/op_and_int_lit16.S
deleted file mode 100644
index d7752b1..0000000
--- a/runtime/interpreter/mterp/x86/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="andl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_and_int_lit8.S b/runtime/interpreter/mterp/x86/op_and_int_lit8.S
deleted file mode 100644
index a353178..0000000
--- a/runtime/interpreter/mterp/x86/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(instr="andl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_and_long.S b/runtime/interpreter/mterp/x86/op_and_long.S
deleted file mode 100644
index 15164ae..0000000
--- a/runtime/interpreter/mterp/x86/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(instr1="andl (rFP,%ecx,4), rIBASE", instr2="andl 4(rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_and_long_2addr.S b/runtime/interpreter/mterp/x86/op_and_long_2addr.S
deleted file mode 100644
index 173c159..0000000
--- a/runtime/interpreter/mterp/x86/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(instr1="andl %eax, (rFP,rINST,4)", instr2="andl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/op_aput.S b/runtime/interpreter/mterp/x86/op_aput.S
deleted file mode 100644
index 60bcc50..0000000
--- a/runtime/interpreter/mterp/x86/op_aput.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_aput(reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
-/*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short
- *
- */
- /* op vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB (array object)
- GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- leal $data_offset(%eax,%ecx,$shift), %eax
- GET_VREG rINST, rINST
- $store $reg, (%eax)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_aput_boolean.S b/runtime/interpreter/mterp/x86/op_aput_boolean.S
deleted file mode 100644
index 8420b5a..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aput_byte.S b/runtime/interpreter/mterp/x86/op_aput_byte.S
deleted file mode 100644
index 6c181a4..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aput_char.S b/runtime/interpreter/mterp/x86/op_aput_char.S
deleted file mode 100644
index 3f4602a..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aput_object.S b/runtime/interpreter/mterp/x86/op_aput_object.S
deleted file mode 100644
index 5d0bb0b..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_object.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_aput_object():
-/*
- * Store an object into an array. vBB[vCC] <- vAA.
- */
- /* op vAA, vBB, vCC */
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpAputObject) # (array, index)
- RESTORE_IBASE
- testb %al, %al
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_aput_short.S b/runtime/interpreter/mterp/x86/op_aput_short.S
deleted file mode 100644
index e76d833..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86/op_aput_wide.S b/runtime/interpreter/mterp/x86/op_aput_wide.S
deleted file mode 100644
index c59f7b3..0000000
--- a/runtime/interpreter/mterp/x86/op_aput_wide.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_aput_wide():
-/*
- * Array put, 64 bits. vBB[vCC] <- vAA.
- *
- */
- /* aput-wide vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB (array object)
- GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- leal MIRROR_WIDE_ARRAY_DATA_OFFSET(%eax,%ecx,8), %eax
- GET_WIDE_FP_VREG %xmm0, rINST # xmm0 <- vAA
- movq %xmm0, (%eax) # vBB[vCC] <- xmm0
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_array_length.S b/runtime/interpreter/mterp/x86/op_array_length.S
deleted file mode 100644
index c9d8930..0000000
--- a/runtime/interpreter/mterp/x86/op_array_length.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_array_length():
-/*
- * Return the length of an array.
- */
- mov rINST, %eax # eax <- BA
- sarl $$4, rINST # rINST <- B
- GET_VREG %ecx, rINST # ecx <- vB (object ref)
- testl %ecx, %ecx # is null?
- je common_errNullObject
- andb $$0xf, %al # eax <- A
- movl MIRROR_ARRAY_LENGTH_OFFSET(%ecx), rINST
- SET_VREG rINST, %eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_check_cast.S b/runtime/interpreter/mterp/x86/op_check_cast.S
deleted file mode 100644
index 12f8543..0000000
--- a/runtime/interpreter/mterp/x86/op_check_cast.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_check_cast():
-/*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class@BBBB */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- BBBB
- movl %eax, OUT_ARG0(%esp)
- leal VREG_ADDRESS(rINST), %ecx
- movl %ecx, OUT_ARG1(%esp)
- movl OFF_FP_METHOD(rFP),%eax
- movl %eax, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
- call SYMBOL(MterpCheckCast) # (index, &obj, method, self)
- RESTORE_IBASE
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_cmp_long.S b/runtime/interpreter/mterp/x86/op_cmp_long.S
deleted file mode 100644
index 0e33874..0000000
--- a/runtime/interpreter/mterp/x86/op_cmp_long.S
+++ /dev/null
@@ -1,28 +0,0 @@
-%def op_cmp_long():
-/*
- * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
- * register based on the results of the comparison.
- */
- /* cmp-long vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG_HIGH %eax, %eax # eax <- v[BB+1], BB is clobbered
- cmpl VREG_HIGH_ADDRESS(%ecx), %eax
- jl .L${opcode}_smaller
- jg .L${opcode}_bigger
- movzbl 2(rPC), %eax # eax <- BB, restore BB
- GET_VREG %eax, %eax # eax <- v[BB]
- sub VREG_ADDRESS(%ecx), %eax
- ja .L${opcode}_bigger
- jb .L${opcode}_smaller
-.L${opcode}_finish:
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-
-.L${opcode}_bigger:
- movl $$1, %eax
- jmp .L${opcode}_finish
-
-.L${opcode}_smaller:
- movl $$-1, %eax
- jmp .L${opcode}_finish
diff --git a/runtime/interpreter/mterp/x86/op_cmpg_double.S b/runtime/interpreter/mterp/x86/op_cmpg_double.S
deleted file mode 100644
index 1c04e99..0000000
--- a/runtime/interpreter/mterp/x86/op_cmpg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_double():
-% fpcmp(suff="d", nanval="pos")
diff --git a/runtime/interpreter/mterp/x86/op_cmpg_float.S b/runtime/interpreter/mterp/x86/op_cmpg_float.S
deleted file mode 100644
index 797c3d5..0000000
--- a/runtime/interpreter/mterp/x86/op_cmpg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_float():
-% fpcmp(suff="s", nanval="pos")
diff --git a/runtime/interpreter/mterp/x86/op_cmpl_double.S b/runtime/interpreter/mterp/x86/op_cmpl_double.S
deleted file mode 100644
index cbe8db7..0000000
--- a/runtime/interpreter/mterp/x86/op_cmpl_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_double():
-% fpcmp(suff="d", nanval="neg")
diff --git a/runtime/interpreter/mterp/x86/op_cmpl_float.S b/runtime/interpreter/mterp/x86/op_cmpl_float.S
deleted file mode 100644
index 068f4cb..0000000
--- a/runtime/interpreter/mterp/x86/op_cmpl_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_float():
-% fpcmp(suff="s", nanval="neg")
diff --git a/runtime/interpreter/mterp/x86/op_const.S b/runtime/interpreter/mterp/x86/op_const.S
deleted file mode 100644
index dc4342f..0000000
--- a/runtime/interpreter/mterp/x86/op_const.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const():
- /* const vAA, #+BBBBbbbb */
- movl 2(rPC), %eax # grab all 32 bits at once
- SET_VREG %eax, rINST # vAA<- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_const_16.S b/runtime/interpreter/mterp/x86/op_const_16.S
deleted file mode 100644
index 84678ae..0000000
--- a/runtime/interpreter/mterp/x86/op_const_16.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, #+BBBB */
- movswl 2(rPC), %ecx # ecx <- ssssBBBB
- SET_VREG %ecx, rINST # vAA <- ssssBBBB
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_const_4.S b/runtime/interpreter/mterp/x86/op_const_4.S
deleted file mode 100644
index 8cfd9c0..0000000
--- a/runtime/interpreter/mterp/x86/op_const_4.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_4():
- /* const/4 vA, #+B */
- movsx rINSTbl, %eax # eax <-ssssssBx
- movl $$0xf, rINST
- andl %eax, rINST # rINST <- A
- sarl $$4, %eax
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_const_class.S b/runtime/interpreter/mterp/x86/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/x86/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/x86/op_const_high16.S b/runtime/interpreter/mterp/x86/op_const_high16.S
deleted file mode 100644
index 5252ba2..0000000
--- a/runtime/interpreter/mterp/x86/op_const_high16.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, #+BBBB0000 */
- movzwl 2(rPC), %eax # eax <- 0000BBBB
- sall $$16, %eax # eax <- BBBB0000
- SET_VREG %eax, rINST # vAA <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_const_method_handle.S b/runtime/interpreter/mterp/x86/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/x86/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/x86/op_const_method_type.S b/runtime/interpreter/mterp/x86/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/x86/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/x86/op_const_string.S b/runtime/interpreter/mterp/x86/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/x86/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/x86/op_const_string_jumbo.S b/runtime/interpreter/mterp/x86/op_const_string_jumbo.S
deleted file mode 100644
index dc70c25..0000000
--- a/runtime/interpreter/mterp/x86/op_const_string_jumbo.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, String@BBBBBBBB */
- EXPORT_PC
- movl 2(rPC), %eax # eax <- BBBB
- movl %eax, OUT_ARG0(%esp)
- movl rINST, OUT_ARG1(%esp)
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG2(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
- call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self)
- RESTORE_IBASE
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_const_wide.S b/runtime/interpreter/mterp/x86/op_const_wide.S
deleted file mode 100644
index d076e83..0000000
--- a/runtime/interpreter/mterp/x86/op_const_wide.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
- movl 2(rPC), %eax # eax <- lsw
- movzbl rINSTbl, %ecx # ecx <- AA
- movl 6(rPC), rINST # rINST <- msw
- SET_VREG %eax, %ecx
- SET_VREG_HIGH rINST, %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 5
diff --git a/runtime/interpreter/mterp/x86/op_const_wide_16.S b/runtime/interpreter/mterp/x86/op_const_wide_16.S
deleted file mode 100644
index 328cdee..0000000
--- a/runtime/interpreter/mterp/x86/op_const_wide_16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, #+BBBB */
- movswl 2(rPC), %eax # eax <- ssssBBBB
- movl rIBASE, %ecx # preserve rIBASE (cltd trashes it)
- cltd # rIBASE:eax <- ssssssssssssBBBB
- SET_VREG_HIGH rIBASE, rINST # store msw
- SET_VREG %eax, rINST # store lsw
- movl %ecx, rIBASE # restore rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_const_wide_32.S b/runtime/interpreter/mterp/x86/op_const_wide_32.S
deleted file mode 100644
index c4b5b67..0000000
--- a/runtime/interpreter/mterp/x86/op_const_wide_32.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, #+BBBBbbbb */
- movl 2(rPC), %eax # eax <- BBBBbbbb
- movl rIBASE, %ecx # preserve rIBASE (cltd trashes it)
- cltd # rIBASE:eax <- ssssssssssssBBBB
- SET_VREG_HIGH rIBASE, rINST # store msw
- SET_VREG %eax, rINST # store lsw
- movl %ecx, rIBASE # restore rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_const_wide_high16.S b/runtime/interpreter/mterp/x86/op_const_wide_high16.S
deleted file mode 100644
index f99e674..0000000
--- a/runtime/interpreter/mterp/x86/op_const_wide_high16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, #+BBBB000000000000 */
- movzwl 2(rPC), %eax # eax <- 0000BBBB
- sall $$16, %eax # eax <- BBBB0000
- SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax
- xorl %eax, %eax
- SET_VREG %eax, rINST # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_div_double.S b/runtime/interpreter/mterp/x86/op_div_double.S
deleted file mode 100644
index 6b342f8..0000000
--- a/runtime/interpreter/mterp/x86/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% sseBinop(instr="divs", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_div_double_2addr.S b/runtime/interpreter/mterp/x86/op_div_double_2addr.S
deleted file mode 100644
index 212c825..0000000
--- a/runtime/interpreter/mterp/x86/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% sseBinop2Addr(instr="divs", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_div_float.S b/runtime/interpreter/mterp/x86/op_div_float.S
deleted file mode 100644
index b6537d9..0000000
--- a/runtime/interpreter/mterp/x86/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% sseBinop(instr="divs", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_div_float_2addr.S b/runtime/interpreter/mterp/x86/op_div_float_2addr.S
deleted file mode 100644
index 19ae27d..0000000
--- a/runtime/interpreter/mterp/x86/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% sseBinop2Addr(instr="divs", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_div_int.S b/runtime/interpreter/mterp/x86/op_div_int.S
deleted file mode 100644
index 4df3b92..0000000
--- a/runtime/interpreter/mterp/x86/op_div_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int():
-% bindiv(result="%eax", special="$0x80000000", rem="0")
diff --git a/runtime/interpreter/mterp/x86/op_div_int_2addr.S b/runtime/interpreter/mterp/x86/op_div_int_2addr.S
deleted file mode 100644
index d43135f..0000000
--- a/runtime/interpreter/mterp/x86/op_div_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_2addr():
-% bindiv2addr(result="%eax", special="$0x80000000")
diff --git a/runtime/interpreter/mterp/x86/op_div_int_lit16.S b/runtime/interpreter/mterp/x86/op_div_int_lit16.S
deleted file mode 100644
index e561eae..0000000
--- a/runtime/interpreter/mterp/x86/op_div_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit16():
-% bindivLit16(result="%eax", special="$0x80000000")
diff --git a/runtime/interpreter/mterp/x86/op_div_int_lit8.S b/runtime/interpreter/mterp/x86/op_div_int_lit8.S
deleted file mode 100644
index 5facee2..0000000
--- a/runtime/interpreter/mterp/x86/op_div_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit8():
-% bindivLit8(result="%eax", special="$0x80000000")
diff --git a/runtime/interpreter/mterp/x86/op_div_long.S b/runtime/interpreter/mterp/x86/op_div_long.S
deleted file mode 100644
index 2fdf6ad..0000000
--- a/runtime/interpreter/mterp/x86/op_div_long.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_div_long(routine="art_quick_ldiv"):
-/* art_quick_* methods has quick abi,
- * so use eax, ecx, edx, ebx for args
- */
- /* div vAA, vBB, vCC */
- .extern $routine
- mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx
- mov rINST, LOCAL1(%esp) # save rINST/%ebx
- movzbl 3(rPC), %eax # eax <- CC
- GET_VREG %ecx, %eax
- GET_VREG_HIGH %ebx, %eax
- movl %ecx, %edx
- orl %ebx, %ecx
- jz common_errDivideByZero
- movzbl 2(rPC), %eax # eax <- BB
- GET_VREG_HIGH %ecx, %eax
- GET_VREG %eax, %eax
- call SYMBOL($routine)
- mov LOCAL1(%esp), rINST # restore rINST/%ebx
- SET_VREG_HIGH rIBASE, rINST
- SET_VREG %eax, rINST
- mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_div_long_2addr.S b/runtime/interpreter/mterp/x86/op_div_long_2addr.S
deleted file mode 100644
index b3d81a4..0000000
--- a/runtime/interpreter/mterp/x86/op_div_long_2addr.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def op_div_long_2addr(routine="art_quick_ldiv"):
-/* art_quick_* methods has quick abi,
- * so use eax, ecx, edx, ebx for args
- */
- /* div/2addr vA, vB */
- .extern $routine
- mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx
- movzbl rINSTbl, %eax
- shrl $$4, %eax # eax <- B
- andb $$0xf, rINSTbl # rINST <- A
- mov rINST, LOCAL1(%esp) # save rINST/%ebx
- movl %ebx, %ecx
- GET_VREG %edx, %eax
- GET_VREG_HIGH %ebx, %eax
- movl %edx, %eax
- orl %ebx, %eax
- jz common_errDivideByZero
- GET_VREG %eax, %ecx
- GET_VREG_HIGH %ecx, %ecx
- call SYMBOL($routine)
- mov LOCAL1(%esp), rINST # restore rINST/%ebx
- SET_VREG_HIGH rIBASE, rINST
- SET_VREG %eax, rINST
- mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_double_to_float.S b/runtime/interpreter/mterp/x86/op_double_to_float.S
deleted file mode 100644
index a52b505..0000000
--- a/runtime/interpreter/mterp/x86/op_double_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_float():
-% fpcvt(load="fldl", store="fstps")
diff --git a/runtime/interpreter/mterp/x86/op_double_to_int.S b/runtime/interpreter/mterp/x86/op_double_to_int.S
deleted file mode 100644
index 65c31fb..0000000
--- a/runtime/interpreter/mterp/x86/op_double_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_int():
-% cvtfp_int(srcdouble="1", tgtlong="0")
diff --git a/runtime/interpreter/mterp/x86/op_double_to_long.S b/runtime/interpreter/mterp/x86/op_double_to_long.S
deleted file mode 100644
index 1eb74bf..0000000
--- a/runtime/interpreter/mterp/x86/op_double_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_long():
-% cvtfp_int(srcdouble="1", tgtlong="1")
diff --git a/runtime/interpreter/mterp/x86/op_fill_array_data.S b/runtime/interpreter/mterp/x86/op_fill_array_data.S
deleted file mode 100644
index f121787..0000000
--- a/runtime/interpreter/mterp/x86/op_fill_array_data.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- EXPORT_PC
- movl 2(rPC), %ecx # ecx <- BBBBbbbb
- leal (rPC,%ecx,2), %ecx # ecx <- PC + BBBBbbbb*2
- GET_VREG %eax, rINST # eax <- vAA (array object)
- movl %eax, OUT_ARG0(%esp)
- movl %ecx, OUT_ARG1(%esp)
- call SYMBOL(MterpFillArrayData) # (obj, payload)
- REFRESH_IBASE
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_filled_new_array.S b/runtime/interpreter/mterp/x86/op_filled_new_array.S
deleted file mode 100644
index 8e5bd03..0000000
--- a/runtime/interpreter/mterp/x86/op_filled_new_array.S
+++ /dev/null
@@ -1,20 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
-/*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
- .extern $helper
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp)
- call SYMBOL($helper)
- REFRESH_IBASE
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_filled_new_array_range.S b/runtime/interpreter/mterp/x86/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/x86/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/x86/op_float_to_double.S b/runtime/interpreter/mterp/x86/op_float_to_double.S
deleted file mode 100644
index 152bb00..0000000
--- a/runtime/interpreter/mterp/x86/op_float_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_double():
-% fpcvt(load="flds", store="fstpl", wide="1")
diff --git a/runtime/interpreter/mterp/x86/op_float_to_int.S b/runtime/interpreter/mterp/x86/op_float_to_int.S
deleted file mode 100644
index 1f8e5cc..0000000
--- a/runtime/interpreter/mterp/x86/op_float_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_int():
-% cvtfp_int(srcdouble="0", tgtlong="0")
diff --git a/runtime/interpreter/mterp/x86/op_float_to_long.S b/runtime/interpreter/mterp/x86/op_float_to_long.S
deleted file mode 100644
index a056769..0000000
--- a/runtime/interpreter/mterp/x86/op_float_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_long():
-% cvtfp_int(srcdouble="0", tgtlong="1")
diff --git a/runtime/interpreter/mterp/x86/op_goto.S b/runtime/interpreter/mterp/x86/op_goto.S
deleted file mode 100644
index b6236fe..0000000
--- a/runtime/interpreter/mterp/x86/op_goto.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto():
-/*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- movsbl rINSTbl, rINST # rINST <- ssssssAA
- testl rINST, rINST
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86/op_goto_16.S b/runtime/interpreter/mterp/x86/op_goto_16.S
deleted file mode 100644
index a8c2bf5..0000000
--- a/runtime/interpreter/mterp/x86/op_goto_16.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto_16():
-/*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- movswl 2(rPC), rINST # rINST <- ssssAAAA
- testl rINST, rINST
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86/op_goto_32.S b/runtime/interpreter/mterp/x86/op_goto_32.S
deleted file mode 100644
index 87d0e33..0000000
--- a/runtime/interpreter/mterp/x86/op_goto_32.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_goto_32():
-/*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Unlike most opcodes, this one is allowed to branch to itself, so
- * our "backward branch" test must be "<=0" instead of "<0". Because
- * we need the V bit set, we'll use an adds to convert from Dalvik
- * offset to byte offset.
- */
- /* goto/32 +AAAAAAAA */
- movl 2(rPC), rINST # rINST <- AAAAAAAA
- testl rINST, rINST
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86/op_if_eq.S b/runtime/interpreter/mterp/x86/op_if_eq.S
deleted file mode 100644
index 4d1f6a5..0000000
--- a/runtime/interpreter/mterp/x86/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(revcmp="ne")
diff --git a/runtime/interpreter/mterp/x86/op_if_eqz.S b/runtime/interpreter/mterp/x86/op_if_eqz.S
deleted file mode 100644
index 12de558..0000000
--- a/runtime/interpreter/mterp/x86/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(revcmp="ne")
diff --git a/runtime/interpreter/mterp/x86/op_if_ge.S b/runtime/interpreter/mterp/x86/op_if_ge.S
deleted file mode 100644
index 6849027..0000000
--- a/runtime/interpreter/mterp/x86/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(revcmp="l")
diff --git a/runtime/interpreter/mterp/x86/op_if_gez.S b/runtime/interpreter/mterp/x86/op_if_gez.S
deleted file mode 100644
index 87bdcbf..0000000
--- a/runtime/interpreter/mterp/x86/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(revcmp="l")
diff --git a/runtime/interpreter/mterp/x86/op_if_gt.S b/runtime/interpreter/mterp/x86/op_if_gt.S
deleted file mode 100644
index 4a52100..0000000
--- a/runtime/interpreter/mterp/x86/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(revcmp="le")
diff --git a/runtime/interpreter/mterp/x86/op_if_gtz.S b/runtime/interpreter/mterp/x86/op_if_gtz.S
deleted file mode 100644
index a0b2e3a..0000000
--- a/runtime/interpreter/mterp/x86/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(revcmp="le")
diff --git a/runtime/interpreter/mterp/x86/op_if_le.S b/runtime/interpreter/mterp/x86/op_if_le.S
deleted file mode 100644
index 69e94db..0000000
--- a/runtime/interpreter/mterp/x86/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(revcmp="g")
diff --git a/runtime/interpreter/mterp/x86/op_if_lez.S b/runtime/interpreter/mterp/x86/op_if_lez.S
deleted file mode 100644
index 42e69d9..0000000
--- a/runtime/interpreter/mterp/x86/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(revcmp="g")
diff --git a/runtime/interpreter/mterp/x86/op_if_lt.S b/runtime/interpreter/mterp/x86/op_if_lt.S
deleted file mode 100644
index 052aabe..0000000
--- a/runtime/interpreter/mterp/x86/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(revcmp="ge")
diff --git a/runtime/interpreter/mterp/x86/op_if_ltz.S b/runtime/interpreter/mterp/x86/op_if_ltz.S
deleted file mode 100644
index 8e13e48..0000000
--- a/runtime/interpreter/mterp/x86/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(revcmp="ge")
diff --git a/runtime/interpreter/mterp/x86/op_if_ne.S b/runtime/interpreter/mterp/x86/op_if_ne.S
deleted file mode 100644
index 2cfd8a9..0000000
--- a/runtime/interpreter/mterp/x86/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(revcmp="e")
diff --git a/runtime/interpreter/mterp/x86/op_if_nez.S b/runtime/interpreter/mterp/x86/op_if_nez.S
deleted file mode 100644
index 261a173..0000000
--- a/runtime/interpreter/mterp/x86/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(revcmp="e")
diff --git a/runtime/interpreter/mterp/x86/op_iget.S b/runtime/interpreter/mterp/x86/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/x86/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86/op_iget_boolean.S b/runtime/interpreter/mterp/x86/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/x86/op_iget_boolean_quick.S b/runtime/interpreter/mterp/x86/op_iget_boolean_quick.S
deleted file mode 100644
index 4e16768..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="movsbl")
diff --git a/runtime/interpreter/mterp/x86/op_iget_byte.S b/runtime/interpreter/mterp/x86/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/x86/op_iget_byte_quick.S b/runtime/interpreter/mterp/x86/op_iget_byte_quick.S
deleted file mode 100644
index b92936c..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="movsbl")
diff --git a/runtime/interpreter/mterp/x86/op_iget_char.S b/runtime/interpreter/mterp/x86/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/x86/op_iget_char_quick.S b/runtime/interpreter/mterp/x86/op_iget_char_quick.S
deleted file mode 100644
index d6f836b..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="movzwl")
diff --git a/runtime/interpreter/mterp/x86/op_iget_object.S b/runtime/interpreter/mterp/x86/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/x86/op_iget_object_quick.S b/runtime/interpreter/mterp/x86/op_iget_object_quick.S
deleted file mode 100644
index 66340e9..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_object_quick.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset@CCCC */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # vB (object we're operating on)
- movzwl 2(rPC), %eax # eax <- field byte offset
- movl %ecx, OUT_ARG0(%esp)
- movl %eax, OUT_ARG1(%esp)
- EXPORT_PC
- call SYMBOL(artIGetObjectFromMterp) # (obj, offset)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $$0xf,rINSTbl # rINST <- A
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iget_quick.S b/runtime/interpreter/mterp/x86/op_iget_quick.S
deleted file mode 100644
index 8ca2c86..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iget_quick(load="movl"):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick */
- /* op vA, vB, offset@CCCC */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # vB (object we're operating on)
- movzwl 2(rPC), %eax # eax <- field byte offset
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- ${load} (%ecx,%eax,1), %eax
- andb $$0xf,rINSTbl # rINST <- A
- SET_VREG %eax, rINST # fp[A] <- value
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iget_short.S b/runtime/interpreter/mterp/x86/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/x86/op_iget_short_quick.S b/runtime/interpreter/mterp/x86/op_iget_short_quick.S
deleted file mode 100644
index f5e48d6..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="movswl")
diff --git a/runtime/interpreter/mterp/x86/op_iget_wide.S b/runtime/interpreter/mterp/x86/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/x86/op_iget_wide_quick.S b/runtime/interpreter/mterp/x86/op_iget_wide_quick.S
deleted file mode 100644
index c1a1326..0000000
--- a/runtime/interpreter/mterp/x86/op_iget_wide_quick.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_iget_wide_quick():
- /* iget-wide-quick vA, vB, offset@CCCC */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # vB (object we're operating on)
- movzwl 2(rPC), %eax # eax <- field byte offset
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- movq (%ecx,%eax,1), %xmm0
- andb $$0xf, rINSTbl # rINST <- A
- SET_WIDE_FP_VREG %xmm0, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_instance_of.S b/runtime/interpreter/mterp/x86/op_instance_of.S
deleted file mode 100644
index ae1afae..0000000
--- a/runtime/interpreter/mterp/x86/op_instance_of.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_instance_of():
-/*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class@CCCC */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- BBBB
- movl %eax, OUT_ARG0(%esp)
- movl rINST, %eax # eax <- BA
- sarl $$4, %eax # eax <- B
- leal VREG_ADDRESS(%eax), %ecx # Get object address
- movl %ecx, OUT_ARG1(%esp)
- movl OFF_FP_METHOD(rFP),%eax
- movl %eax, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
- call SYMBOL(MterpInstanceOf) # (index, &obj, method, self)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- andb $$0xf, rINSTbl # rINSTbl <- A
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_int_to_byte.S b/runtime/interpreter/mterp/x86/op_int_to_byte.S
deleted file mode 100644
index 80e4d5c..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="movsbl %al, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_int_to_char.S b/runtime/interpreter/mterp/x86/op_int_to_char.S
deleted file mode 100644
index 83e9868..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(instr="movzwl %ax,%eax")
diff --git a/runtime/interpreter/mterp/x86/op_int_to_double.S b/runtime/interpreter/mterp/x86/op_int_to_double.S
deleted file mode 100644
index e304d8e..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_double():
-% fpcvt(load="fildl", store="fstpl", wide="1")
diff --git a/runtime/interpreter/mterp/x86/op_int_to_float.S b/runtime/interpreter/mterp/x86/op_int_to_float.S
deleted file mode 100644
index fe00097..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_float():
-% fpcvt(load="fildl", store="fstps")
diff --git a/runtime/interpreter/mterp/x86/op_int_to_long.S b/runtime/interpreter/mterp/x86/op_int_to_long.S
deleted file mode 100644
index 8491973..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_long.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_int_to_long():
- /* int to long vA, vB */
- movzbl rINSTbl, %eax # eax <- +A
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %eax # eax <- vB
- andb $$0xf, rINSTbl # rINST <- A
- movl rIBASE, %ecx # cltd trashes rIBASE/edx
- cltd # rINST:eax<- sssssssBBBBBBBB
- SET_VREG_HIGH rIBASE, rINST # v[A+1] <- rIBASE
- SET_VREG %eax, rINST # v[A+0] <- %eax
- movl %ecx, rIBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-
diff --git a/runtime/interpreter/mterp/x86/op_int_to_short.S b/runtime/interpreter/mterp/x86/op_int_to_short.S
deleted file mode 100644
index e4db90b..0000000
--- a/runtime/interpreter/mterp/x86/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="movswl %ax, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_custom.S b/runtime/interpreter/mterp/x86/op_invoke_custom.S
deleted file mode 100644
index 4bba9ee..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_custom.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_custom_range.S b/runtime/interpreter/mterp/x86/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_direct.S b/runtime/interpreter/mterp/x86/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_direct_range.S b/runtime/interpreter/mterp/x86/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_interface.S b/runtime/interpreter/mterp/x86/op_invoke_interface.S
deleted file mode 100644
index 559b976..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_interface.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
-/*
- * Handle an interface method call.
- *
- * for: invoke-interface, invoke-interface/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86/op_invoke_interface_range.S b/runtime/interpreter/mterp/x86/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_polymorphic.S b/runtime/interpreter/mterp/x86/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/x86/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_static.S b/runtime/interpreter/mterp/x86/op_invoke_static.S
deleted file mode 100644
index 3e38d36..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_static.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
-
diff --git a/runtime/interpreter/mterp/x86/op_invoke_static_range.S b/runtime/interpreter/mterp/x86/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_super.S b/runtime/interpreter/mterp/x86/op_invoke_super.S
deleted file mode 100644
index 5b20550..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_super.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
-/*
- * Handle a "super" method call.
- *
- * for: invoke-super, invoke-super/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86/op_invoke_super_range.S b/runtime/interpreter/mterp/x86/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_virtual.S b/runtime/interpreter/mterp/x86/op_invoke_virtual.S
deleted file mode 100644
index e27eeed..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_virtual.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
-/*
- * Handle a virtual method call.
- *
- * for: invoke-virtual, invoke-virtual/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/x86/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_virtual_range.S b/runtime/interpreter/mterp/x86/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/x86/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/x86/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/x86/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/x86/op_iput.S b/runtime/interpreter/mterp/x86/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/x86/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86/op_iput_boolean.S b/runtime/interpreter/mterp/x86/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/x86/op_iput_boolean_quick.S b/runtime/interpreter/mterp/x86/op_iput_boolean_quick.S
deleted file mode 100644
index c304c76..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(reg="rINSTbl", store="movb")
diff --git a/runtime/interpreter/mterp/x86/op_iput_byte.S b/runtime/interpreter/mterp/x86/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/x86/op_iput_byte_quick.S b/runtime/interpreter/mterp/x86/op_iput_byte_quick.S
deleted file mode 100644
index dac18e6..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(reg="rINSTbl", store="movb")
diff --git a/runtime/interpreter/mterp/x86/op_iput_char.S b/runtime/interpreter/mterp/x86/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/x86/op_iput_char_quick.S b/runtime/interpreter/mterp/x86/op_iput_char_quick.S
deleted file mode 100644
index 21a2581..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(reg="rINSTw", store="movw")
diff --git a/runtime/interpreter/mterp/x86/op_iput_object.S b/runtime/interpreter/mterp/x86/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/x86/op_iput_object_quick.S b/runtime/interpreter/mterp/x86/op_iput_object_quick.S
deleted file mode 100644
index 6b6fb2d..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_object_quick.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_iput_object_quick():
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpIputObjectQuick)
- testb %al, %al
- jz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iput_quick.S b/runtime/interpreter/mterp/x86/op_iput_quick.S
deleted file mode 100644
index 5198cfe..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iput_quick(reg="rINST", store="movl"):
- /* For: iput-quick, iput-object-quick */
- /* op vA, vB, offset@CCCC */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # vB (object we're operating on)
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG rINST, rINST # rINST <- v[A]
- movzwl 2(rPC), %eax # eax <- field byte offset
- ${store} ${reg}, (%ecx,%eax,1)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iput_short.S b/runtime/interpreter/mterp/x86/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/x86/op_iput_short_quick.S b/runtime/interpreter/mterp/x86/op_iput_short_quick.S
deleted file mode 100644
index 5eb28d6..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(reg="rINSTw", store="movw")
diff --git a/runtime/interpreter/mterp/x86/op_iput_wide.S b/runtime/interpreter/mterp/x86/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/x86/op_iput_wide_quick.S b/runtime/interpreter/mterp/x86/op_iput_wide_quick.S
deleted file mode 100644
index 6e1feef..0000000
--- a/runtime/interpreter/mterp/x86/op_iput_wide_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset@CCCC */
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx # vB (object we're operating on)
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- movzwl 2(rPC), %eax # eax<- field byte offset
- leal (%ecx,%eax,1), %ecx # ecx<- Address of 64-bit target
- andb $$0xf, rINSTbl # rINST<- A
- GET_WIDE_FP_VREG %xmm0, rINST # xmm0<- fp[A]/fp[A+1]
- movq %xmm0, (%ecx) # obj.field<- r0/r1
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_long_to_double.S b/runtime/interpreter/mterp/x86/op_long_to_double.S
deleted file mode 100644
index 858cb2e..0000000
--- a/runtime/interpreter/mterp/x86/op_long_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_double():
-% fpcvt(load="fildll", store="fstpl", wide="1")
diff --git a/runtime/interpreter/mterp/x86/op_long_to_float.S b/runtime/interpreter/mterp/x86/op_long_to_float.S
deleted file mode 100644
index b26085a..0000000
--- a/runtime/interpreter/mterp/x86/op_long_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_float():
-% fpcvt(load="fildll", store="fstps")
diff --git a/runtime/interpreter/mterp/x86/op_long_to_int.S b/runtime/interpreter/mterp/x86/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/x86/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/x86/op_monitor_enter.S b/runtime/interpreter/mterp/x86/op_monitor_enter.S
deleted file mode 100644
index d28ab4c..0000000
--- a/runtime/interpreter/mterp/x86/op_monitor_enter.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_monitor_enter():
-/*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- EXPORT_PC
- GET_VREG %ecx, rINST
- movl %ecx, OUT_ARG0(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG1(%esp)
- call SYMBOL(artLockObjectFromCode) # (object, self)
- RESTORE_IBASE
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_monitor_exit.S b/runtime/interpreter/mterp/x86/op_monitor_exit.S
deleted file mode 100644
index 63a8287..0000000
--- a/runtime/interpreter/mterp/x86/op_monitor_exit.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_monitor_exit():
-/*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- EXPORT_PC
- GET_VREG %ecx, rINST
- movl %ecx, OUT_ARG0(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG1(%esp)
- call SYMBOL(artUnlockObjectFromCode) # (object, self)
- RESTORE_IBASE
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move.S b/runtime/interpreter/mterp/x86/op_move.S
deleted file mode 100644
index e023755..0000000
--- a/runtime/interpreter/mterp/x86/op_move.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- movzbl rINSTbl, %eax # eax <- BA
- andb $$0xf, %al # eax <- A
- shrl $$4, rINST # rINST <- B
- GET_VREG rINST, rINST
- .if $is_object
- SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
- .else
- SET_VREG rINST, %eax # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move_16.S b/runtime/interpreter/mterp/x86/op_move_16.S
deleted file mode 100644
index 0b4f839..0000000
--- a/runtime/interpreter/mterp/x86/op_move_16.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- movzwl 4(rPC), %ecx # ecx <- BBBB
- movzwl 2(rPC), %eax # eax <- AAAA
- GET_VREG rINST, %ecx
- .if $is_object
- SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
- .else
- SET_VREG rINST, %eax # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_move_exception.S b/runtime/interpreter/mterp/x86/op_move_exception.S
deleted file mode 100644
index cadce40..0000000
--- a/runtime/interpreter/mterp/x86/op_move_exception.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- movl rSELF, %ecx
- movl THREAD_EXCEPTION_OFFSET(%ecx), %eax
- SET_VREG_OBJECT %eax, rINST # fp[AA] <- exception object
- movl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move_from16.S b/runtime/interpreter/mterp/x86/op_move_from16.S
deleted file mode 100644
index b8a9c8b..0000000
--- a/runtime/interpreter/mterp/x86/op_move_from16.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- movzx rINSTbl, %eax # eax <- AA
- movw 2(rPC), rINSTw # rINSTw <- BBBB
- GET_VREG rINST, rINST # rINST <- fp[BBBB]
- .if $is_object
- SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
- .else
- SET_VREG rINST, %eax # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_move_object.S b/runtime/interpreter/mterp/x86/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/x86/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/x86/op_move_object_16.S b/runtime/interpreter/mterp/x86/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/x86/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/x86/op_move_object_from16.S b/runtime/interpreter/mterp/x86/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/x86/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/x86/op_move_result.S b/runtime/interpreter/mterp/x86/op_move_result.S
deleted file mode 100644
index c287faa..0000000
--- a/runtime/interpreter/mterp/x86/op_move_result.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- movl OFF_FP_RESULT_REGISTER(rFP), %eax # get pointer to result JType.
- movl (%eax), %eax # r0 <- result.i.
- .if $is_object
- SET_VREG_OBJECT %eax, rINST # fp[A] <- fp[B]
- .else
- SET_VREG %eax, rINST # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move_result_object.S b/runtime/interpreter/mterp/x86/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/x86/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/x86/op_move_result_wide.S b/runtime/interpreter/mterp/x86/op_move_result_wide.S
deleted file mode 100644
index 68b1d80..0000000
--- a/runtime/interpreter/mterp/x86/op_move_result_wide.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_move_result_wide():
- /* move-result-wide vAA */
- movl OFF_FP_RESULT_REGISTER(rFP), %eax # get pointer to result JType.
- movl 4(%eax), %ecx # Get high
- movl (%eax), %eax # Get low
- SET_VREG %eax, rINST # v[AA+0] <- eax
- SET_VREG_HIGH %ecx, rINST # v[AA+1] <- ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move_wide.S b/runtime/interpreter/mterp/x86/op_move_wide.S
deleted file mode 100644
index 0559d01..0000000
--- a/runtime/interpreter/mterp/x86/op_move_wide.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_WIDE_FP_VREG %xmm0, rINST # xmm0 <- v[B]
- SET_WIDE_FP_VREG %xmm0, %ecx # v[A] <- xmm0
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_move_wide_16.S b/runtime/interpreter/mterp/x86/op_move_wide_16.S
deleted file mode 100644
index 13a5e0d..0000000
--- a/runtime/interpreter/mterp/x86/op_move_wide_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movzwl 4(rPC), %ecx # ecx<- BBBB
- movzwl 2(rPC), %eax # eax<- AAAA
- GET_WIDE_FP_VREG %xmm0, %ecx # xmm0 <- v[B]
- SET_WIDE_FP_VREG %xmm0, %eax # v[A] <- xmm0
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86/op_move_wide_from16.S b/runtime/interpreter/mterp/x86/op_move_wide_from16.S
deleted file mode 100644
index 5380a8f..0000000
--- a/runtime/interpreter/mterp/x86/op_move_wide_from16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movzwl 2(rPC), %ecx # ecx <- BBBB
- movzbl rINSTbl, %eax # eax <- AAAA
- GET_WIDE_FP_VREG %xmm0, %ecx # xmm0 <- v[B]
- SET_WIDE_FP_VREG %xmm0, %eax # v[A] <- xmm0
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_mul_double.S b/runtime/interpreter/mterp/x86/op_mul_double.S
deleted file mode 100644
index 5353028..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% sseBinop(instr="muls", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_mul_double_2addr.S b/runtime/interpreter/mterp/x86/op_mul_double_2addr.S
deleted file mode 100644
index 7a6dcd0..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% sseBinop2Addr(instr="muls", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_mul_float.S b/runtime/interpreter/mterp/x86/op_mul_float.S
deleted file mode 100644
index b9eeeee..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% sseBinop(instr="muls", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_mul_float_2addr.S b/runtime/interpreter/mterp/x86/op_mul_float_2addr.S
deleted file mode 100644
index 949af7b..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% sseBinop2Addr(instr="muls", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_mul_int.S b/runtime/interpreter/mterp/x86/op_mul_int.S
deleted file mode 100644
index 9388486..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_int.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_mul_int():
- /*
- * 32-bit binary multiplication.
- */
- /* mul vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- GET_VREG %eax, %eax # eax <- vBB
- mov rIBASE, LOCAL0(%esp)
- imull (rFP,%ecx,4), %eax # trashes rIBASE/edx
- mov LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_mul_int_2addr.S b/runtime/interpreter/mterp/x86/op_mul_int_2addr.S
deleted file mode 100644
index 34e9b31..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_int_2addr.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_mul_int_2addr():
- /* mul vA, vB */
- movzx rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- GET_VREG %eax, rINST # eax <- vB
- andb $$0xf, %cl # ecx <- A
- movl rIBASE, rINST
- imull (rFP,%ecx,4), %eax # trashes rIBASE/edx
- movl rINST, rIBASE
- SET_VREG %eax, %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_mul_int_lit16.S b/runtime/interpreter/mterp/x86/op_mul_int_lit16.S
deleted file mode 100644
index 491fde4..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_int_lit16.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_mul_int_lit16():
- /* mul/lit16 vA, vB, #+CCCC */
- /* Need A in rINST, ssssCCCC in ecx, vB in eax */
- movzbl rINSTbl, %eax # eax <- 000000BA
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %eax # eax <- vB
- movl rIBASE, %ecx
- movswl 2(rPC), rIBASE # rIBASE <- ssssCCCC
- andb $$0xf, rINSTbl # rINST <- A
- imull rIBASE, %eax # trashes rIBASE/edx
- movl %ecx, rIBASE
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_mul_int_lit8.S b/runtime/interpreter/mterp/x86/op_mul_int_lit8.S
deleted file mode 100644
index d76973c..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_int_lit8.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_mul_int_lit8():
- /* mul/lit8 vAA, vBB, #+CC */
- movzbl 2(rPC), %eax # eax <- BB
- movl rIBASE, %ecx
- GET_VREG %eax, %eax # eax <- rBB
- movsbl 3(rPC), rIBASE # rIBASE <- ssssssCC
- imull rIBASE, %eax # trashes rIBASE/edx
- movl %ecx, rIBASE
- SET_VREG %eax, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_mul_long.S b/runtime/interpreter/mterp/x86/op_mul_long.S
deleted file mode 100644
index 0359272..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_long.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def op_mul_long():
-/*
- * Signed 64-bit integer multiply.
- *
- * We could definately use more free registers for
- * this code. We spill rINSTw (ebx),
- * giving us eax, ebc, ecx and edx as computational
- * temps. On top of that, we'll spill edi (rFP)
- * for use as the vB pointer and esi (rPC) for use
- * as the vC pointer. Yuck.
- *
- */
- /* mul-long vAA, vBB, vCC */
- movzbl 2(rPC), %eax # eax <- B
- movzbl 3(rPC), %ecx # ecx <- C
- mov rPC, LOCAL0(%esp) # save Interpreter PC
- mov rFP, LOCAL1(%esp) # save FP
- mov rIBASE, LOCAL2(%esp) # save rIBASE
- leal (rFP,%eax,4), %esi # esi <- &v[B]
- leal (rFP,%ecx,4), rFP # rFP <- &v[C]
- movl 4(%esi), %ecx # ecx <- Bmsw
- imull (rFP), %ecx # ecx <- (Bmsw*Clsw)
- movl 4(rFP), %eax # eax <- Cmsw
- imull (%esi), %eax # eax <- (Cmsw*Blsw)
- addl %eax, %ecx # ecx <- (Bmsw*Clsw)+(Cmsw*Blsw)
- movl (rFP), %eax # eax <- Clsw
- mull (%esi) # eax <- (Clsw*Alsw)
- mov LOCAL0(%esp), rPC # restore Interpreter PC
- mov LOCAL1(%esp), rFP # restore FP
- leal (%ecx,rIBASE), rIBASE # full result now in rIBASE:%eax
- SET_VREG_HIGH rIBASE, rINST # v[B+1] <- rIBASE
- mov LOCAL2(%esp), rIBASE # restore IBASE
- SET_VREG %eax, rINST # v[B] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_mul_long_2addr.S b/runtime/interpreter/mterp/x86/op_mul_long_2addr.S
deleted file mode 100644
index b48f58d..0000000
--- a/runtime/interpreter/mterp/x86/op_mul_long_2addr.S
+++ /dev/null
@@ -1,36 +0,0 @@
-%def op_mul_long_2addr():
-/*
- * Signed 64-bit integer multiply, 2-addr version
- *
- * We could definately use more free registers for
- * this code. We must spill %edx (rIBASE) because it
- * is used by imul. We'll also spill rINST (ebx),
- * giving us eax, ebc, ecx and rIBASE as computational
- * temps. On top of that, we'll spill %esi (edi)
- * for use as the vA pointer and rFP (esi) for use
- * as the vB pointer. Yuck.
- */
- /* mul-long/2addr vA, vB */
- movzbl rINSTbl, %eax # eax <- BA
- andb $$0xf, %al # eax <- A
- CLEAR_WIDE_REF %eax # clear refs in advance
- sarl $$4, rINST # rINST <- B
- mov rPC, LOCAL0(%esp) # save Interpreter PC
- mov rFP, LOCAL1(%esp) # save FP
- mov rIBASE, LOCAL2(%esp) # save rIBASE
- leal (rFP,%eax,4), %esi # esi <- &v[A]
- leal (rFP,rINST,4), rFP # rFP <- &v[B]
- movl 4(%esi), %ecx # ecx <- Amsw
- imull (rFP), %ecx # ecx <- (Amsw*Blsw)
- movl 4(rFP), %eax # eax <- Bmsw
- imull (%esi), %eax # eax <- (Bmsw*Alsw)
- addl %eax, %ecx # ecx <- (Amsw*Blsw)+(Bmsw*Alsw)
- movl (rFP), %eax # eax <- Blsw
- mull (%esi) # eax <- (Blsw*Alsw)
- leal (%ecx,rIBASE), rIBASE # full result now in %edx:%eax
- movl rIBASE, 4(%esi) # v[A+1] <- rIBASE
- movl %eax, (%esi) # v[A] <- %eax
- mov LOCAL0(%esp), rPC # restore Interpreter PC
- mov LOCAL2(%esp), rIBASE # restore IBASE
- mov LOCAL1(%esp), rFP # restore FP
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_neg_double.S b/runtime/interpreter/mterp/x86/op_neg_double.S
deleted file mode 100644
index df29053..0000000
--- a/runtime/interpreter/mterp/x86/op_neg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_double():
-% fpcvt(instr="fchs", load="fldl", store="fstpl", wide="1")
diff --git a/runtime/interpreter/mterp/x86/op_neg_float.S b/runtime/interpreter/mterp/x86/op_neg_float.S
deleted file mode 100644
index 0abe45c..0000000
--- a/runtime/interpreter/mterp/x86/op_neg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_float():
-% fpcvt(instr="fchs", load="flds", store="fstps")
diff --git a/runtime/interpreter/mterp/x86/op_neg_int.S b/runtime/interpreter/mterp/x86/op_neg_int.S
deleted file mode 100644
index 24604a9..0000000
--- a/runtime/interpreter/mterp/x86/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr="negl %eax")
diff --git a/runtime/interpreter/mterp/x86/op_neg_long.S b/runtime/interpreter/mterp/x86/op_neg_long.S
deleted file mode 100644
index 75f3279..0000000
--- a/runtime/interpreter/mterp/x86/op_neg_long.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_neg_long():
- /* unop vA, vB */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, %ecx # eax <- v[B+0]
- GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1]
- negl %eax
- adcl $$0, %ecx
- negl %ecx
- SET_VREG %eax, rINST # v[A+0] <- eax
- SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-
diff --git a/runtime/interpreter/mterp/x86/op_new_array.S b/runtime/interpreter/mterp/x86/op_new_array.S
deleted file mode 100644
index e59e106..0000000
--- a/runtime/interpreter/mterp/x86/op_new_array.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def op_new_array():
-/*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class@CCCC */
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
- call SYMBOL(MterpNewArray)
- RESTORE_IBASE
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_new_instance.S b/runtime/interpreter/mterp/x86/op_new_instance.S
deleted file mode 100644
index 81631c6..0000000
--- a/runtime/interpreter/mterp/x86/op_new_instance.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_new_instance():
-/*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class@BBBB */
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- call SYMBOL(MterpNewInstance)
- RESTORE_IBASE
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_nop.S b/runtime/interpreter/mterp/x86/op_nop.S
deleted file mode 100644
index aa4a843..0000000
--- a/runtime/interpreter/mterp/x86/op_nop.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_nop():
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_not_int.S b/runtime/interpreter/mterp/x86/op_not_int.S
deleted file mode 100644
index c95ac08..0000000
--- a/runtime/interpreter/mterp/x86/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr="notl %eax")
diff --git a/runtime/interpreter/mterp/x86/op_not_long.S b/runtime/interpreter/mterp/x86/op_not_long.S
deleted file mode 100644
index c79f9d0..0000000
--- a/runtime/interpreter/mterp/x86/op_not_long.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_not_long():
- /* unop vA, vB */
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, %ecx # eax <- v[B+0]
- GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1]
- notl %eax
- notl %ecx
- SET_VREG %eax, rINST # v[A+0] <- eax
- SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_or_int.S b/runtime/interpreter/mterp/x86/op_or_int.S
deleted file mode 100644
index f44ac0d..0000000
--- a/runtime/interpreter/mterp/x86/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="orl (rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_or_int_2addr.S b/runtime/interpreter/mterp/x86/op_or_int_2addr.S
deleted file mode 100644
index f0f278c..0000000
--- a/runtime/interpreter/mterp/x86/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="orl %eax, (rFP,%ecx,4)")
diff --git a/runtime/interpreter/mterp/x86/op_or_int_lit16.S b/runtime/interpreter/mterp/x86/op_or_int_lit16.S
deleted file mode 100644
index ba9b6bf..0000000
--- a/runtime/interpreter/mterp/x86/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="orl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_or_int_lit8.S b/runtime/interpreter/mterp/x86/op_or_int_lit8.S
deleted file mode 100644
index 758109b..0000000
--- a/runtime/interpreter/mterp/x86/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(instr="orl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_or_long.S b/runtime/interpreter/mterp/x86/op_or_long.S
deleted file mode 100644
index 389081d..0000000
--- a/runtime/interpreter/mterp/x86/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(instr1="orl (rFP,%ecx,4), rIBASE", instr2="orl 4(rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_or_long_2addr.S b/runtime/interpreter/mterp/x86/op_or_long_2addr.S
deleted file mode 100644
index 5beb9a2..0000000
--- a/runtime/interpreter/mterp/x86/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(instr1="orl %eax, (rFP,rINST,4)", instr2="orl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/op_packed_switch.S b/runtime/interpreter/mterp/x86/op_packed_switch.S
deleted file mode 100644
index b4c393f..0000000
--- a/runtime/interpreter/mterp/x86/op_packed_switch.S
+++ /dev/null
@@ -1,21 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
-/*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBB */
- movl 2(rPC), %ecx # ecx <- BBBBbbbb
- GET_VREG %eax, rINST # eax <- vAA
- leal (rPC,%ecx,2), %ecx # ecx <- PC + BBBBbbbb*2
- movl %eax, OUT_ARG1(%esp) # ARG1 <- vAA
- movl %ecx, OUT_ARG0(%esp) # ARG0 <- switchData
- call SYMBOL($func)
- REFRESH_IBASE
- testl %eax, %eax
- movl %eax, rINST
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86/op_rem_double.S b/runtime/interpreter/mterp/x86/op_rem_double.S
deleted file mode 100644
index df7b740..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_double.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_rem_double():
- /* rem_double vAA, vBB, vCC */
- movzbl 3(rPC), %ecx # ecx <- BB
- movzbl 2(rPC), %eax # eax <- CC
- fldl VREG_ADDRESS(%ecx) # %st1 <- fp[vBB]
- fldl VREG_ADDRESS(%eax) # %st0 <- fp[vCC]
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstpl VREG_ADDRESS(rINST) # fp[vAA] <- %st
- CLEAR_WIDE_REF rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_rem_double_2addr.S b/runtime/interpreter/mterp/x86/op_rem_double_2addr.S
deleted file mode 100644
index fb4e393..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_double_2addr.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_rem_double_2addr():
- /* rem_double/2addr vA, vB */
- movzx rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- fldl VREG_ADDRESS(rINST) # vB to fp stack
- andb $$0xf, %cl # ecx <- A
- fldl VREG_ADDRESS(%ecx) # vA to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstpl VREG_ADDRESS(%ecx) # %st to vA
- CLEAR_WIDE_REF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_rem_float.S b/runtime/interpreter/mterp/x86/op_rem_float.S
deleted file mode 100644
index 9b436f2..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_float.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_rem_float():
- /* rem_float vAA, vBB, vCC */
- movzbl 3(rPC), %ecx # ecx <- BB
- movzbl 2(rPC), %eax # eax <- CC
- flds VREG_ADDRESS(%ecx) # vBB to fp stack
- flds VREG_ADDRESS(%eax) # vCC to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstps VREG_ADDRESS(rINST) # %st to vAA
- CLEAR_REF rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_rem_float_2addr.S b/runtime/interpreter/mterp/x86/op_rem_float_2addr.S
deleted file mode 100644
index 81d44c8..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_float_2addr.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_rem_float_2addr():
- /* rem_float/2addr vA, vB */
- movzx rINSTbl, %ecx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- flds VREG_ADDRESS(rINST) # vB to fp stack
- andb $$0xf, %cl # ecx <- A
- flds VREG_ADDRESS(%ecx) # vA to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstps VREG_ADDRESS(%ecx) # %st to vA
- CLEAR_REF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_rem_int.S b/runtime/interpreter/mterp/x86/op_rem_int.S
deleted file mode 100644
index 71da7b8..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int():
-% bindiv(result="rIBASE", special="$0", rem="1")
diff --git a/runtime/interpreter/mterp/x86/op_rem_int_2addr.S b/runtime/interpreter/mterp/x86/op_rem_int_2addr.S
deleted file mode 100644
index f58f4ac..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_2addr():
-% bindiv2addr(result="rIBASE", special="$0")
diff --git a/runtime/interpreter/mterp/x86/op_rem_int_lit16.S b/runtime/interpreter/mterp/x86/op_rem_int_lit16.S
deleted file mode 100644
index 8915740..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit16():
-% bindivLit16(result="rIBASE", special="$0")
diff --git a/runtime/interpreter/mterp/x86/op_rem_int_lit8.S b/runtime/interpreter/mterp/x86/op_rem_int_lit8.S
deleted file mode 100644
index 88369de..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit8():
-% bindivLit8(result="rIBASE", special="$0")
diff --git a/runtime/interpreter/mterp/x86/op_rem_long.S b/runtime/interpreter/mterp/x86/op_rem_long.S
deleted file mode 100644
index ef23c05..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long():
-% op_div_long(routine="art_quick_lmod")
diff --git a/runtime/interpreter/mterp/x86/op_rem_long_2addr.S b/runtime/interpreter/mterp/x86/op_rem_long_2addr.S
deleted file mode 100644
index f6a8ec3..0000000
--- a/runtime/interpreter/mterp/x86/op_rem_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long_2addr():
-% op_div_long_2addr(routine="art_quick_lmod")
diff --git a/runtime/interpreter/mterp/x86/op_return.S b/runtime/interpreter/mterp/x86/op_return.S
deleted file mode 100644
index 0fdd6f5..0000000
--- a/runtime/interpreter/mterp/x86/op_return.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_return():
-/*
- * Return a 32-bit value.
- *
- * for: return, return-object
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call SYMBOL(MterpSuspendCheck)
-1:
- GET_VREG %eax, rINST # eax <- vAA
- xorl %ecx, %ecx
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_object.S b/runtime/interpreter/mterp/x86/op_return_object.S
deleted file mode 100644
index 2eeec0b..0000000
--- a/runtime/interpreter/mterp/x86/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return()
diff --git a/runtime/interpreter/mterp/x86/op_return_void.S b/runtime/interpreter/mterp/x86/op_return_void.S
deleted file mode 100644
index 3eb5b66..0000000
--- a/runtime/interpreter/mterp/x86/op_return_void.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call SYMBOL(MterpSuspendCheck)
-1:
- xorl %eax, %eax
- xorl %ecx, %ecx
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S b/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S
deleted file mode 100644
index eadd522..0000000
--- a/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_return_void_no_barrier():
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call SYMBOL(MterpSuspendCheck)
-1:
- xorl %eax, %eax
- xorl %ecx, %ecx
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_wide.S b/runtime/interpreter/mterp/x86/op_return_wide.S
deleted file mode 100644
index 67a103d..0000000
--- a/runtime/interpreter/mterp/x86/op_return_wide.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_return_wide():
-/*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call SYMBOL(MterpSuspendCheck)
-1:
- GET_VREG %eax, rINST # eax <- v[AA+0]
- GET_VREG_HIGH %ecx, rINST # ecx <- v[AA+1]
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_rsub_int.S b/runtime/interpreter/mterp/x86/op_rsub_int.S
deleted file mode 100644
index 05ba130..0000000
--- a/runtime/interpreter/mterp/x86/op_rsub_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rsub_int():
-/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
-% binopLit16(instr="subl %eax, %ecx", result="%ecx")
diff --git a/runtime/interpreter/mterp/x86/op_rsub_int_lit8.S b/runtime/interpreter/mterp/x86/op_rsub_int_lit8.S
deleted file mode 100644
index d023047..0000000
--- a/runtime/interpreter/mterp/x86/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(instr="subl %eax, %ecx", result="%ecx")
diff --git a/runtime/interpreter/mterp/x86/op_sget.S b/runtime/interpreter/mterp/x86/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/x86/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86/op_sget_boolean.S b/runtime/interpreter/mterp/x86/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/x86/op_sget_byte.S b/runtime/interpreter/mterp/x86/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/x86/op_sget_char.S b/runtime/interpreter/mterp/x86/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/x86/op_sget_object.S b/runtime/interpreter/mterp/x86/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/x86/op_sget_short.S b/runtime/interpreter/mterp/x86/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/x86/op_sget_wide.S b/runtime/interpreter/mterp/x86/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/x86/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/x86/op_shl_int.S b/runtime/interpreter/mterp/x86/op_shl_int.S
deleted file mode 100644
index a98b256..0000000
--- a/runtime/interpreter/mterp/x86/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop1(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shl_int_2addr.S b/runtime/interpreter/mterp/x86/op_shl_int_2addr.S
deleted file mode 100644
index 987c7d1..0000000
--- a/runtime/interpreter/mterp/x86/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% shop2addr(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shl_int_lit8.S b/runtime/interpreter/mterp/x86/op_shl_int_lit8.S
deleted file mode 100644
index ee1a15e..0000000
--- a/runtime/interpreter/mterp/x86/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shl_long.S b/runtime/interpreter/mterp/x86/op_shl_long.S
deleted file mode 100644
index d45705a..0000000
--- a/runtime/interpreter/mterp/x86/op_shl_long.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_shl_long():
-/*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance. x86 shifts automatically mask off
- * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
- * case specially.
- */
- /* shl-long vAA, vBB, vCC */
- /* ecx gets shift count */
- /* Need to spill rINST */
- /* rINSTw gets AA */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, %eax # ecx <- v[BB+1]
- GET_VREG %ecx, %ecx # ecx <- vCC
- GET_VREG %eax, %eax # eax <- v[BB+0]
- shldl %eax,rIBASE
- sall %cl, %eax
- testb $$32, %cl
- je 2f
- movl %eax, rIBASE
- xorl %eax, %eax
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[AA+0] <- %eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_shl_long_2addr.S b/runtime/interpreter/mterp/x86/op_shl_long_2addr.S
deleted file mode 100644
index 7d40f56..0000000
--- a/runtime/interpreter/mterp/x86/op_shl_long_2addr.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_shl_long_2addr():
-/*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shl-long/2addr vA, vB */
- /* ecx gets shift count */
- /* Need to spill rIBASE */
- /* rINSTw gets AA */
- movzbl rINSTbl, %ecx # ecx <- BA
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, rINST # eax <- v[AA+0]
- sarl $$4, %ecx # ecx <- B
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
- GET_VREG %ecx, %ecx # ecx <- vBB
- shldl %eax, rIBASE
- sall %cl, %eax
- testb $$32, %cl
- je 2f
- movl %eax, rIBASE
- xorl %eax, %eax
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_shr_int.S b/runtime/interpreter/mterp/x86/op_shr_int.S
deleted file mode 100644
index 4d4d79c..0000000
--- a/runtime/interpreter/mterp/x86/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop1(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shr_int_2addr.S b/runtime/interpreter/mterp/x86/op_shr_int_2addr.S
deleted file mode 100644
index 8e4b055..0000000
--- a/runtime/interpreter/mterp/x86/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% shop2addr(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shr_int_lit8.S b/runtime/interpreter/mterp/x86/op_shr_int_lit8.S
deleted file mode 100644
index a7acf5f..0000000
--- a/runtime/interpreter/mterp/x86/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_shr_long.S b/runtime/interpreter/mterp/x86/op_shr_long.S
deleted file mode 100644
index 3b85941..0000000
--- a/runtime/interpreter/mterp/x86/op_shr_long.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_shr_long():
-/*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance. x86 shifts automatically mask off
- * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
- * case specially.
- */
- /* shr-long vAA, vBB, vCC */
- /* ecx gets shift count */
- /* Need to spill rIBASE */
- /* rINSTw gets AA */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, %eax # rIBASE<- v[BB+1]
- GET_VREG %ecx, %ecx # ecx <- vCC
- GET_VREG %eax, %eax # eax <- v[BB+0]
- shrdl rIBASE, %eax
- sarl %cl, rIBASE
- testb $$32, %cl
- je 2f
- movl rIBASE, %eax
- sarl $$31, rIBASE
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_shr_long_2addr.S b/runtime/interpreter/mterp/x86/op_shr_long_2addr.S
deleted file mode 100644
index 6427ded..0000000
--- a/runtime/interpreter/mterp/x86/op_shr_long_2addr.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_shr_long_2addr():
-/*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shl-long/2addr vA, vB */
- /* ecx gets shift count */
- /* Need to spill rIBASE */
- /* rINSTw gets AA */
- movzbl rINSTbl, %ecx # ecx <- BA
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, rINST # eax <- v[AA+0]
- sarl $$4, %ecx # ecx <- B
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
- GET_VREG %ecx, %ecx # ecx <- vBB
- shrdl rIBASE, %eax
- sarl %cl, rIBASE
- testb $$32, %cl
- je 2f
- movl rIBASE, %eax
- sarl $$31, rIBASE
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_sparse_switch.S b/runtime/interpreter/mterp/x86/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/x86/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/x86/op_sput.S b/runtime/interpreter/mterp/x86/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/x86/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86/op_sput_boolean.S b/runtime/interpreter/mterp/x86/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/x86/op_sput_byte.S b/runtime/interpreter/mterp/x86/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/x86/op_sput_char.S b/runtime/interpreter/mterp/x86/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/x86/op_sput_object.S b/runtime/interpreter/mterp/x86/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/x86/op_sput_short.S b/runtime/interpreter/mterp/x86/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/x86/op_sput_wide.S b/runtime/interpreter/mterp/x86/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/x86/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/x86/op_sub_double.S b/runtime/interpreter/mterp/x86/op_sub_double.S
deleted file mode 100644
index 64a28c3..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% sseBinop(instr="subs", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_sub_double_2addr.S b/runtime/interpreter/mterp/x86/op_sub_double_2addr.S
deleted file mode 100644
index 753074b..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% sseBinop2Addr(instr="subs", suff="d")
diff --git a/runtime/interpreter/mterp/x86/op_sub_float.S b/runtime/interpreter/mterp/x86/op_sub_float.S
deleted file mode 100644
index 1a1966d..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% sseBinop(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_sub_float_2addr.S b/runtime/interpreter/mterp/x86/op_sub_float_2addr.S
deleted file mode 100644
index 9557907..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% sseBinop2Addr(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86/op_sub_int.S b/runtime/interpreter/mterp/x86/op_sub_int.S
deleted file mode 100644
index 289d241..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="subl (rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_sub_int_2addr.S b/runtime/interpreter/mterp/x86/op_sub_int_2addr.S
deleted file mode 100644
index b55f887..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="subl %eax, (rFP,%ecx,4)")
diff --git a/runtime/interpreter/mterp/x86/op_sub_long.S b/runtime/interpreter/mterp/x86/op_sub_long.S
deleted file mode 100644
index d45c9a7..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long():
-% binopWide(instr1="subl (rFP,%ecx,4), rIBASE", instr2="sbbl 4(rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_sub_long_2addr.S b/runtime/interpreter/mterp/x86/op_sub_long_2addr.S
deleted file mode 100644
index 615b535..0000000
--- a/runtime/interpreter/mterp/x86/op_sub_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long_2addr():
-% binopWide2addr(instr1="subl %eax, (rFP,rINST,4)", instr2="sbbl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/op_throw.S b/runtime/interpreter/mterp/x86/op_throw.S
deleted file mode 100644
index fa4a9d0..0000000
--- a/runtime/interpreter/mterp/x86/op_throw.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_throw():
-/*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC
- GET_VREG %eax, rINST # eax<- vAA (exception object)
- testl %eax, %eax
- jz common_errNullObject
- movl rSELF,%ecx
- movl %eax, THREAD_EXCEPTION_OFFSET(%ecx)
- jmp MterpException
diff --git a/runtime/interpreter/mterp/x86/op_unused_3e.S b/runtime/interpreter/mterp/x86/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_3f.S b/runtime/interpreter/mterp/x86/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_40.S b/runtime/interpreter/mterp/x86/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_41.S b/runtime/interpreter/mterp/x86/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_42.S b/runtime/interpreter/mterp/x86/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_43.S b/runtime/interpreter/mterp/x86/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_79.S b/runtime/interpreter/mterp/x86/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_7a.S b/runtime/interpreter/mterp/x86/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f3.S b/runtime/interpreter/mterp/x86/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f4.S b/runtime/interpreter/mterp/x86/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f5.S b/runtime/interpreter/mterp/x86/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f6.S b/runtime/interpreter/mterp/x86/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f7.S b/runtime/interpreter/mterp/x86/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f8.S b/runtime/interpreter/mterp/x86/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_f9.S b/runtime/interpreter/mterp/x86/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_fc.S b/runtime/interpreter/mterp/x86/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_unused_fd.S b/runtime/interpreter/mterp/x86/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/x86/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/x86/op_ushr_int.S b/runtime/interpreter/mterp/x86/op_ushr_int.S
deleted file mode 100644
index 38c8782..0000000
--- a/runtime/interpreter/mterp/x86/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop1(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_ushr_int_2addr.S b/runtime/interpreter/mterp/x86/op_ushr_int_2addr.S
deleted file mode 100644
index f1da71a..0000000
--- a/runtime/interpreter/mterp/x86/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% shop2addr(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_ushr_int_lit8.S b/runtime/interpreter/mterp/x86/op_ushr_int_lit8.S
deleted file mode 100644
index 4298d36..0000000
--- a/runtime/interpreter/mterp/x86/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_ushr_long.S b/runtime/interpreter/mterp/x86/op_ushr_long.S
deleted file mode 100644
index 5837a9a..0000000
--- a/runtime/interpreter/mterp/x86/op_ushr_long.S
+++ /dev/null
@@ -1,30 +0,0 @@
-%def op_ushr_long():
-/*
- * Long integer shift. This is different from the generic 32/64-bit
- * binary operations because vAA/vBB are 64-bit but vCC (the shift
- * distance) is 32-bit. Also, Dalvik requires us to mask off the low
- * 6 bits of the shift distance. x86 shifts automatically mask off
- * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
- * case specially.
- */
- /* shr-long vAA, vBB, vCC */
- /* ecx gets shift count */
- /* Need to spill rIBASE */
- /* rINSTw gets AA */
- movzbl 2(rPC), %eax # eax <- BB
- movzbl 3(rPC), %ecx # ecx <- CC
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, %eax # rIBASE <- v[BB+1]
- GET_VREG %ecx, %ecx # ecx <- vCC
- GET_VREG %eax, %eax # eax <- v[BB+0]
- shrdl rIBASE, %eax
- shrl %cl, rIBASE
- testb $$32, %cl
- je 2f
- movl rIBASE, %eax
- xorl rIBASE, rIBASE
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[BB+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_ushr_long_2addr.S b/runtime/interpreter/mterp/x86/op_ushr_long_2addr.S
deleted file mode 100644
index f07318a..0000000
--- a/runtime/interpreter/mterp/x86/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def op_ushr_long_2addr():
-/*
- * Long integer shift, 2addr version. vA is 64-bit value/result, vB is
- * 32-bit shift distance.
- */
- /* shl-long/2addr vA, vB */
- /* ecx gets shift count */
- /* Need to spill rIBASE */
- /* rINSTw gets AA */
- movzbl rINSTbl, %ecx # ecx <- BA
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, rINST # eax <- v[AA+0]
- sarl $$4, %ecx # ecx <- B
- movl rIBASE, LOCAL0(%esp)
- GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1]
- GET_VREG %ecx, %ecx # ecx <- vBB
- shrdl rIBASE, %eax
- shrl %cl, rIBASE
- testb $$32, %cl
- je 2f
- movl rIBASE, %eax
- xorl rIBASE, rIBASE
-2:
- SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE
- movl LOCAL0(%esp), rIBASE
- SET_VREG %eax, rINST # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/op_xor_int.S b/runtime/interpreter/mterp/x86/op_xor_int.S
deleted file mode 100644
index 351d73a..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="xorl (rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_xor_int_2addr.S b/runtime/interpreter/mterp/x86/op_xor_int_2addr.S
deleted file mode 100644
index daeebed..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="xorl %eax, (rFP,%ecx,4)")
diff --git a/runtime/interpreter/mterp/x86/op_xor_int_lit16.S b/runtime/interpreter/mterp/x86/op_xor_int_lit16.S
deleted file mode 100644
index f5dc00e..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="xorl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_xor_int_lit8.S b/runtime/interpreter/mterp/x86/op_xor_int_lit8.S
deleted file mode 100644
index 98a1a43..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(instr="xorl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86/op_xor_long.S b/runtime/interpreter/mterp/x86/op_xor_long.S
deleted file mode 100644
index cc749e6..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(instr1="xorl (rFP,%ecx,4), rIBASE", instr2="xorl 4(rFP,%ecx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86/op_xor_long_2addr.S b/runtime/interpreter/mterp/x86/op_xor_long_2addr.S
deleted file mode 100644
index 3aa9235..0000000
--- a/runtime/interpreter/mterp/x86/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(instr1="xorl %eax, (rFP,rINST,4)", instr2="xorl %ecx, 4(rFP,rINST,4)")
diff --git a/runtime/interpreter/mterp/x86/other.S b/runtime/interpreter/mterp/x86/other.S
new file mode 100644
index 0000000..5de3381
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/other.S
@@ -0,0 +1,318 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC
+ movzwl 2(rPC), %eax # eax <- BBBB
+ movl %eax, OUT_ARG0(%esp)
+ movl rINST, OUT_ARG1(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp)
+ call SYMBOL($helper) # (index, tgt_reg, shadow_frame, self)
+ RESTORE_IBASE
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ jmp MterpFallback
+
+%def op_const():
+ /* const vAA, #+BBBBbbbb */
+ movl 2(rPC), %eax # grab all 32 bits at once
+ SET_VREG %eax, rINST # vAA<- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_16():
+ /* const/16 vAA, #+BBBB */
+ movswl 2(rPC), %ecx # ecx <- ssssBBBB
+ SET_VREG %ecx, rINST # vAA <- ssssBBBB
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_4():
+ /* const/4 vA, #+B */
+ movsx rINSTbl, %eax # eax <-ssssssBx
+ movl $$0xf, rINST
+ andl %eax, rINST # rINST <- A
+ sarl $$4, %eax
+ SET_VREG %eax, rINST
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, #+BBBB0000 */
+ movzwl 2(rPC), %eax # eax <- 0000BBBB
+ sall $$16, %eax # eax <- BBBB0000
+ SET_VREG %eax, rINST # vAA <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, String@BBBBBBBB */
+ EXPORT_PC
+ movl 2(rPC), %eax # eax <- BBBB
+ movl %eax, OUT_ARG0(%esp)
+ movl rINST, OUT_ARG1(%esp)
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp)
+ call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self)
+ RESTORE_IBASE
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_wide():
+ /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
+ movl 2(rPC), %eax # eax <- lsw
+ movzbl rINSTbl, %ecx # ecx <- AA
+ movl 6(rPC), rINST # rINST <- msw
+ SET_VREG %eax, %ecx
+ SET_VREG_HIGH rINST, %ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 5
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, #+BBBB */
+ movswl 2(rPC), %eax # eax <- ssssBBBB
+ movl rIBASE, %ecx # preserve rIBASE (cltd trashes it)
+ cltd # rIBASE:eax <- ssssssssssssBBBB
+ SET_VREG_HIGH rIBASE, rINST # store msw
+ SET_VREG %eax, rINST # store lsw
+ movl %ecx, rIBASE # restore rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, #+BBBBbbbb */
+ movl 2(rPC), %eax # eax <- BBBBbbbb
+ movl rIBASE, %ecx # preserve rIBASE (cltd trashes it)
+ cltd # rIBASE:eax <- ssssssssssssBBBB
+ SET_VREG_HIGH rIBASE, rINST # store msw
+ SET_VREG %eax, rINST # store lsw
+ movl %ecx, rIBASE # restore rIBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, #+BBBB000000000000 */
+ movzwl 2(rPC), %eax # eax <- 0000BBBB
+ sall $$16, %eax # eax <- BBBB0000
+ SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax
+ xorl %eax, %eax
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_monitor_enter():
+/*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ EXPORT_PC
+ GET_VREG %ecx, rINST
+ movl %ecx, OUT_ARG0(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG1(%esp)
+ call SYMBOL(artLockObjectFromCode) # (object, self)
+ RESTORE_IBASE
+ testb %al, %al
+ jnz MterpException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_monitor_exit():
+/*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ EXPORT_PC
+ GET_VREG %ecx, rINST
+ movl %ecx, OUT_ARG0(%esp)
+ movl rSELF, %eax
+ movl %eax, OUT_ARG1(%esp)
+ call SYMBOL(artUnlockObjectFromCode) # (object, self)
+ RESTORE_IBASE
+ testb %al, %al
+ jnz MterpException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ movzbl rINSTbl, %eax # eax <- BA
+ andb $$0xf, %al # eax <- A
+ shrl $$4, rINST # rINST <- B
+ GET_VREG rINST, rINST
+ .if $is_object
+ SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
+ .else
+ SET_VREG rINST, %eax # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ movzwl 4(rPC), %ecx # ecx <- BBBB
+ movzwl 2(rPC), %eax # eax <- AAAA
+ GET_VREG rINST, %ecx
+ .if $is_object
+ SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
+ .else
+ SET_VREG rINST, %eax # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_move_exception():
+ /* move-exception vAA */
+ movl rSELF, %ecx
+ movl THREAD_EXCEPTION_OFFSET(%ecx), %eax
+ SET_VREG_OBJECT %eax, rINST # fp[AA] <- exception object
+ movl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ movzx rINSTbl, %eax # eax <- AA
+ movw 2(rPC), rINSTw # rINSTw <- BBBB
+ GET_VREG rINST, rINST # rINST <- fp[BBBB]
+ .if $is_object
+ SET_VREG_OBJECT rINST, %eax # fp[A] <- fp[B]
+ .else
+ SET_VREG rINST, %eax # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ movl OFF_FP_RESULT_REGISTER(rFP), %eax # get pointer to result JType.
+ movl (%eax), %eax # r0 <- result.i.
+ .if $is_object
+ SET_VREG_OBJECT %eax, rINST # fp[A] <- fp[B]
+ .else
+ SET_VREG %eax, rINST # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* move-result-wide vAA */
+ movl OFF_FP_RESULT_REGISTER(rFP), %eax # get pointer to result JType.
+ movl 4(%eax), %ecx # Get high
+ movl (%eax), %eax # Get low
+ SET_VREG %eax, rINST # v[AA+0] <- eax
+ SET_VREG_HIGH %ecx, rINST # v[AA+1] <- ecx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movzbl rINSTbl, %ecx # ecx <- BA
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_WIDE_FP_VREG %xmm0, rINST # xmm0 <- v[B]
+ SET_WIDE_FP_VREG %xmm0, %ecx # v[A] <- xmm0
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movzwl 4(rPC), %ecx # ecx<- BBBB
+ movzwl 2(rPC), %eax # eax<- AAAA
+ GET_WIDE_FP_VREG %xmm0, %ecx # xmm0 <- v[B]
+ SET_WIDE_FP_VREG %xmm0, %eax # v[A] <- xmm0
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movzwl 2(rPC), %ecx # ecx <- BBBB
+ movzbl rINSTbl, %eax # eax <- AAAA
+ GET_WIDE_FP_VREG %xmm0, %ecx # xmm0 <- v[B]
+ SET_WIDE_FP_VREG %xmm0, %eax # v[A] <- xmm0
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_nop():
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/x86/shop2addr.S b/runtime/interpreter/mterp/x86/shop2addr.S
deleted file mode 100644
index 9a57677..0000000
--- a/runtime/interpreter/mterp/x86/shop2addr.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def shop2addr(result="%eax", instr=""):
-/*
- * Generic 32-bit "shift/2addr" operation.
- */
- /* shift/2addr vA, vB */
- movzx rINSTbl, %ecx # eax <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx # eax <- vBB
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG %eax, rINST # eax <- vAA
- $instr # ex: sarl %cl, %eax
- SET_VREG $result, rINST
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/sseBinop.S b/runtime/interpreter/mterp/x86/sseBinop.S
deleted file mode 100644
index a20db7c..0000000
--- a/runtime/interpreter/mterp/x86/sseBinop.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def sseBinop(instr="", suff=""):
- movzbl 2(rPC), %ecx # ecx <- BB
- movzbl 3(rPC), %eax # eax <- CC
- movs${suff} VREG_ADDRESS(%ecx), %xmm0 # %xmm0 <- 1st src
- ${instr}${suff} VREG_ADDRESS(%eax), %xmm0
- movs${suff} %xmm0, VREG_ADDRESS(rINST) # vAA <- %xmm0
- pxor %xmm0, %xmm0
- movs${suff} %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/sseBinop2Addr.S b/runtime/interpreter/mterp/x86/sseBinop2Addr.S
deleted file mode 100644
index 1186fb7..0000000
--- a/runtime/interpreter/mterp/x86/sseBinop2Addr.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def sseBinop2Addr(instr="", suff=""):
- movzx rINSTbl, %ecx # ecx <- A+
- andl $$0xf, %ecx # ecx <- A
- movs${suff} VREG_ADDRESS(%ecx), %xmm0 # %xmm0 <- 1st src
- sarl $$4, rINST # rINST<- B
- ${instr}${suff} VREG_ADDRESS(rINST), %xmm0
- movs${suff} %xmm0, VREG_ADDRESS(%ecx) # vAA<- %xmm0
- pxor %xmm0, %xmm0
- movs${suff} %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/unop.S b/runtime/interpreter/mterp/x86/unop.S
deleted file mode 100644
index 5594cb9..0000000
--- a/runtime/interpreter/mterp/x86/unop.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def unop(instr=""):
-/*
- * Generic 32-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op eax".
- */
- /* unop vA, vB */
- movzbl rINSTbl,%ecx # ecx <- A+
- sarl $$4,rINST # rINST <- B
- GET_VREG %eax, rINST # eax <- vB
- andb $$0xf,%cl # ecx <- A
- $instr
- SET_VREG %eax, %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86/unused.S b/runtime/interpreter/mterp/x86/unused.S
deleted file mode 100644
index ef35b6e..0000000
--- a/runtime/interpreter/mterp/x86/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- jmp MterpFallback
diff --git a/runtime/interpreter/mterp/x86/zcmp.S b/runtime/interpreter/mterp/x86/zcmp.S
deleted file mode 100644
index 120f1ed..0000000
--- a/runtime/interpreter/mterp/x86/zcmp.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def zcmp(revcmp=""):
-/*
- * Generic one-operand compare-and-branch operation. Provide a "revcmp"
- * fragment that specifies the *reverse* comparison to perform, e.g.
- * for "if-le" you would use "gt".
- *
- * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- cmpl $$0, VREG_ADDRESS(rINST) # compare (vA, 0)
- j${revcmp} 1f
- movswl 2(rPC), rINST # fetch signed displacement
- testl rINST, rINST
- jmp MterpCommonTakenBranch
-1:
- cmpw $$JIT_CHECK_OSR, rPROFILE
- je .L_check_not_taken_osr
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/alt_stub.S b/runtime/interpreter/mterp/x86_64/alt_stub.S
deleted file mode 100644
index 0c71716..0000000
--- a/runtime/interpreter/mterp/x86_64/alt_stub.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def alt_stub():
-/*
- * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
- * any interesting requests and then jump to the real instruction
- * handler. Unlike the Arm handler, we can't do this as a tail call
- * because rIBASE is caller save and we need to reload it.
- *
- * Note that unlike in the Arm implementation, we should never arrive
- * here with a zero breakFlag because we always refresh rIBASE on
- * return.
- */
- .extern MterpCheckBefore
- REFRESH_IBASE
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movq rPC, OUT_ARG2
- call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr)
- jmp .L_op_nop+(${opnum}*${handler_size_bytes})
diff --git a/runtime/interpreter/mterp/x86_64/arithmetic.S b/runtime/interpreter/mterp/x86_64/arithmetic.S
new file mode 100644
index 0000000..ffe2008
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/arithmetic.S
@@ -0,0 +1,575 @@
+%def bindiv(result="", second="", wide="", suffix="", rem="0", ext="cdq"):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op1=-1.
+ */
+ /* div/rem vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # rax <- BB
+ movzbq 3(rPC), %rcx # rcx <- CC
+ .if $wide
+ GET_WIDE_VREG %rax, %rax # eax <- vBB
+ GET_WIDE_VREG $second, %rcx # ecx <- vCC
+ .else
+ GET_VREG %eax, %rax # eax <- vBB
+ GET_VREG $second, %rcx # ecx <- vCC
+ .endif
+ test${suffix} $second, $second
+ jz common_errDivideByZero
+ cmp${suffix} $$-1, $second
+ je 2f
+ $ext # rdx:rax <- sign-extended of rax
+ idiv${suffix} $second
+1:
+ .if $wide
+ SET_WIDE_VREG $result, rINSTq # eax <- vBB
+ .else
+ SET_VREG $result, rINSTq # eax <- vBB
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+2:
+ .if $rem
+ xor${suffix} $result, $result
+ .else
+ neg${suffix} $result
+ .endif
+ jmp 1b
+
+%def bindiv2addr(result="", second="", wide="", suffix="", rem="0", ext="cdq"):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op1=-1.
+ */
+ /* div/rem/2addr vA, vB */
+ movl rINST, %ecx # rcx <- BA
+ sarl $$4, %ecx # rcx <- B
+ andb $$0xf, rINSTbl # rINST <- A
+ .if $wide
+ GET_WIDE_VREG %rax, rINSTq # eax <- vA
+ GET_WIDE_VREG $second, %rcx # ecx <- vB
+ .else
+ GET_VREG %eax, rINSTq # eax <- vA
+ GET_VREG $second, %rcx # ecx <- vB
+ .endif
+ test${suffix} $second, $second
+ jz common_errDivideByZero
+ cmp${suffix} $$-1, $second
+ je 2f
+ $ext # rdx:rax <- sign-extended of rax
+ idiv${suffix} $second
+1:
+ .if $wide
+ SET_WIDE_VREG $result, rINSTq # vA <- result
+ .else
+ SET_VREG $result, rINSTq # vA <- result
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+2:
+ .if $rem
+ xor${suffix} $result, $result
+ .else
+ neg${suffix} $result
+ .endif
+ jmp 1b
+
+%def bindivLit16(result="", rem="0"):
+/*
+ * 32-bit binary div/rem operation. Handles special case of op1=-1.
+ */
+ /* div/rem/lit16 vA, vB, #+CCCC */
+ /* Need A in rINST, ssssCCCC in ecx, vB in eax */
+ movl rINST, %eax # rax <- 000000BA
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %rax # eax <- vB
+ movswl 2(rPC), %ecx # ecx <- ssssCCCC
+ andb $$0xf, rINSTbl # rINST <- A
+ testl %ecx, %ecx
+ jz common_errDivideByZero
+ cmpl $$-1, %ecx
+ je 2f
+ cdq # rax <- sign-extended of eax
+ idivl %ecx
+1:
+ SET_VREG $result, rINSTq # vA <- result
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+2:
+ .if $rem
+ xorl $result, $result
+ .else
+ negl $result
+ .endif
+ jmp 1b
+
+%def bindivLit8(result="", rem="0"):
+/*
+ * 32-bit div/rem "lit8" binary operation. Handles special case of
+ * op0=minint & op1=-1
+ */
+ /* div/rem/lit8 vAA, vBB, #+CC */
+ movzbq 2(rPC), %rax # eax <- BB
+ movsbl 3(rPC), %ecx # ecx <- ssssssCC
+ GET_VREG %eax, %rax # eax <- rBB
+ testl %ecx, %ecx
+ je common_errDivideByZero
+ cmpl $$-1, %ecx
+ je 2f
+ cdq # rax <- sign-extended of eax
+ idivl %ecx
+1:
+ SET_VREG $result, rINSTq # vA <- result
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+2:
+ .if $rem
+ xorl $result, $result
+ .else
+ negl $result
+ .endif
+ jmp 1b
+
+%def binop(result="%eax", instr=""):
+/*
+ * Generic 32-bit binary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than eax, you can override "result".)
+ *
+ * For: add-int, sub-int, and-int, or-int,
+ * xor-int, shl-int, shr-int, ushr-int
+ */
+ /* binop vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # rax <- BB
+ movzbq 3(rPC), %rcx # rcx <- CC
+ GET_VREG %eax, %rax # eax <- vBB
+ $instr # ex: addl (rFP,%rcx,4),%eax
+ SET_VREG $result, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binop1(wide="0", instr=""):
+/*
+ * Generic 32-bit binary operation in which both operands loaded to
+ * registers (op0 in eax, op1 in ecx).
+ */
+ /* binop vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # eax <- BB
+ movzbq 3(rPC), %rcx # ecx <- CC
+ GET_VREG %ecx, %rcx # eax <- vCC
+ .if $wide
+ GET_WIDE_VREG %rax, %rax # rax <- vBB
+ $instr # ex: addl %ecx,%eax
+ SET_WIDE_VREG %rax, rINSTq
+ .else
+ GET_VREG %eax, %rax # eax <- vBB
+ $instr # ex: addl %ecx,%eax
+ SET_VREG %eax, rINSTq
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binop2addr(result="%eax", instr=""):
+/*
+ * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = r0 op r1".
+ * This could be an instruction or a function call.
+ *
+ * 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 */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_VREG %eax, rINSTq # eax <- vB
+ $instr # for ex: addl %eax,(rFP,%ecx,4)
+ CLEAR_REF %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def binopLit16(result="%eax", instr=""):
+/*
+ * Generic 32-bit "lit16" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = eax op ecx".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than eax, you can override "result".)
+ *
+ * For: add-int/lit16, rsub-int,
+ * and-int/lit16, or-int/lit16, xor-int/lit16
+ */
+ /* binop/lit16 vA, vB, #+CCCC */
+ movl rINST, %eax # rax <- 000000BA
+ sarl $$4, %eax # eax <- B
+ GET_VREG %eax, %rax # eax <- vB
+ andb $$0xf, rINSTbl # rINST <- A
+ movswl 2(rPC), %ecx # ecx <- ssssCCCC
+ $instr # for example: addl %ecx, %eax
+ SET_VREG $result, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopLit8(result="%eax", instr=""):
+/*
+ * Generic 32-bit "lit8" binary operation. Provide an "instr" line
+ * that specifies an instruction that performs "result = eax op ecx".
+ * This could be an x86 instruction or a function call. (If the result
+ * comes back in a register other than r0, you can override "result".)
+ *
+ * For: add-int/lit8, rsub-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 */
+ movzbq 2(rPC), %rax # rax <- BB
+ movsbl 3(rPC), %ecx # rcx <- ssssssCC
+ GET_VREG %eax, %rax # eax <- rBB
+ $instr # ex: addl %ecx,%eax
+ SET_VREG $result, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopWide(instr=""):
+/*
+ * Generic 64-bit binary operation.
+ */
+ /* binop vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # eax <- BB
+ movzbq 3(rPC), %rcx # ecx <- CC
+ GET_WIDE_VREG %rax, %rax # rax <- v[BB]
+ $instr # ex: addq (rFP,%rcx,4),%rax
+ SET_WIDE_VREG %rax, rINSTq # v[AA] <- rax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def binopWide2addr(instr=""):
+/*
+ * Generic 64-bit binary operation.
+ */
+ /* binop/2addr vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_WIDE_VREG %rax, rINSTq # rax <- vB
+ $instr # for ex: addq %rax,(rFP,%rcx,4)
+ CLEAR_WIDE_REF %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def cvtfp_int(fp_suffix="", i_suffix="", max_const="", result_reg="", wide=""):
+/* On fp to int conversions, Java requires that
+ * if the result > maxint, it should be clamped to maxint. If it is less
+ * than minint, it should be clamped to minint. If it is a nan, the result
+ * should be zero. Further, the rounding mode is to truncate.
+ */
+ /* float/double to int/long vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ movs${fp_suffix} VREG_ADDRESS(rINSTq), %xmm0
+ mov${i_suffix} ${max_const}, ${result_reg}
+ cvtsi2s${fp_suffix}${i_suffix} ${result_reg}, %xmm1
+ comis${fp_suffix} %xmm1, %xmm0
+ jae 1f
+ jp 2f
+ cvtts${fp_suffix}2si${i_suffix} %xmm0, ${result_reg}
+ jmp 1f
+2:
+ xor${i_suffix} ${result_reg}, ${result_reg}
+1:
+ .if $wide
+ SET_WIDE_VREG ${result_reg}, %rcx
+ .else
+ SET_VREG ${result_reg}, %rcx
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def shop2addr(wide="0", instr=""):
+/*
+ * Generic 32-bit "shift/2addr" operation.
+ */
+ /* shift/2addr vA, vB */
+ movl rINST, %ecx # ecx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %rcx # ecx <- vBB
+ andb $$0xf, rINSTbl # rINST <- A
+ .if $wide
+ GET_WIDE_VREG %rax, rINSTq # rax <- vAA
+ $instr # ex: sarl %cl, %eax
+ SET_WIDE_VREG %rax, rINSTq
+ .else
+ GET_VREG %eax, rINSTq # eax <- vAA
+ $instr # ex: sarl %cl, %eax
+ SET_VREG %eax, rINSTq
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def unop(preinstr="", instr="", wide="0"):
+/*
+ * Generic 32/64-bit unary operation. Provide an "instr" line that
+ * specifies an instruction that performs "result = op eax".
+ */
+ /* unop vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4,rINST # rINST <- B
+ .if ${wide}
+ GET_WIDE_VREG %rax, rINSTq # rax <- vB
+ .else
+ GET_VREG %eax, rINSTq # eax <- vB
+ .endif
+ andb $$0xf,%cl # ecx <- A
+$preinstr
+$instr
+ .if ${wide}
+ SET_WIDE_VREG %rax, %rcx
+ .else
+ SET_VREG %eax, %rcx
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_add_int():
+% binop(instr="addl (rFP,%rcx,4), %eax")
+
+%def op_add_int_2addr():
+% binop2addr(instr="addl %eax, (rFP,%rcx,4)")
+
+%def op_add_int_lit16():
+% binopLit16(instr="addl %ecx, %eax")
+
+%def op_add_int_lit8():
+% binopLit8(instr="addl %ecx, %eax")
+
+%def op_add_long():
+% binopWide(instr="addq (rFP,%rcx,4), %rax")
+
+%def op_add_long_2addr():
+% binopWide2addr(instr="addq %rax, (rFP,%rcx,4)")
+
+%def op_and_int():
+% binop(instr="andl (rFP,%rcx,4), %eax")
+
+%def op_and_int_2addr():
+% binop2addr(instr="andl %eax, (rFP,%rcx,4)")
+
+%def op_and_int_lit16():
+% binopLit16(instr="andl %ecx, %eax")
+
+%def op_and_int_lit8():
+% binopLit8(instr="andl %ecx, %eax")
+
+%def op_and_long():
+% binopWide(instr="andq (rFP,%rcx,4), %rax")
+
+%def op_and_long_2addr():
+% binopWide2addr(instr="andq %rax, (rFP,%rcx,4)")
+
+%def op_cmp_long():
+/*
+ * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
+ * register based on the results of the comparison.
+ */
+ /* cmp-long vAA, vBB, vCC */
+ movzbq 2(rPC), %rdx # edx <- BB
+ movzbq 3(rPC), %rcx # ecx <- CC
+ GET_WIDE_VREG %rdx, %rdx # rdx <- v[BB]
+ xorl %eax, %eax
+ xorl %edi, %edi
+ addb $$1, %al
+ movl $$-1, %esi
+ cmpq VREG_ADDRESS(%rcx), %rdx
+ cmovl %esi, %edi
+ cmovg %eax, %edi
+ SET_VREG %edi, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_div_int():
+% bindiv(result="%eax", second="%ecx", wide="0", suffix="l")
+
+%def op_div_int_2addr():
+% bindiv2addr(result="%eax", second="%ecx", wide="0", suffix="l")
+
+%def op_div_int_lit16():
+% bindivLit16(result="%eax")
+
+%def op_div_int_lit8():
+% bindivLit8(result="%eax")
+
+%def op_div_long():
+% bindiv(result="%rax", second="%rcx", wide="1", suffix="q", ext="cqo")
+
+%def op_div_long_2addr():
+% bindiv2addr(result="%rax", second="%rcx", wide="1", suffix="q", ext="cqo")
+
+%def op_int_to_byte():
+% unop(instr="movsbl %al, %eax")
+
+%def op_int_to_char():
+% unop(instr="movzwl %ax,%eax")
+
+%def op_int_to_long():
+ /* int to long vA, vB */
+ movzbq rINSTbl, %rax # rax <- +A
+ sarl $$4, %eax # eax <- B
+ andb $$0xf, rINSTbl # rINST <- A
+ movslq VREG_ADDRESS(%rax), %rax
+ SET_WIDE_VREG %rax, rINSTq # v[A] <- %rax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+
+%def op_int_to_short():
+% unop(instr="movswl %ax, %eax")
+
+%def op_long_to_int():
+/* we ignore the high word, making this equivalent to a 32-bit reg move */
+% op_move()
+
+%def op_mul_int():
+% binop(instr="imull (rFP,%rcx,4), %eax")
+
+%def op_mul_int_2addr():
+ /* mul vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_VREG %eax, %rcx # eax <- vA
+ imull (rFP,rINSTq,4), %eax
+ SET_VREG %eax, %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_mul_int_lit16():
+% binopLit16(instr="imull %ecx, %eax")
+
+%def op_mul_int_lit8():
+% binopLit8(instr="imull %ecx, %eax")
+
+%def op_mul_long():
+% binopWide(instr="imulq (rFP,%rcx,4), %rax")
+
+%def op_mul_long_2addr():
+ /* mul vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_WIDE_VREG %rax, %rcx # rax <- vA
+ imulq (rFP,rINSTq,4), %rax
+ SET_WIDE_VREG %rax, %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_neg_int():
+% unop(instr=" negl %eax")
+
+%def op_neg_long():
+% unop(instr=" negq %rax", wide="1")
+
+%def op_not_int():
+% unop(instr=" notl %eax")
+
+%def op_not_long():
+% unop(instr=" notq %rax", wide="1")
+
+%def op_or_int():
+% binop(instr="orl (rFP,%rcx,4), %eax")
+
+%def op_or_int_2addr():
+% binop2addr(instr="orl %eax, (rFP,%rcx,4)")
+
+%def op_or_int_lit16():
+% binopLit16(instr="orl %ecx, %eax")
+
+%def op_or_int_lit8():
+% binopLit8(instr="orl %ecx, %eax")
+
+%def op_or_long():
+% binopWide(instr="orq (rFP,%rcx,4), %rax")
+
+%def op_or_long_2addr():
+% binopWide2addr(instr="orq %rax, (rFP,%rcx,4)")
+
+%def op_rem_int():
+% bindiv(result="%edx", second="%ecx", wide="0", suffix="l", rem="1")
+
+%def op_rem_int_2addr():
+% bindiv2addr(result="%edx", second="%ecx", wide="0", suffix="l", rem="1")
+
+%def op_rem_int_lit16():
+% bindivLit16(result="%edx", rem="1")
+
+%def op_rem_int_lit8():
+% bindivLit8(result="%edx", rem="1")
+
+%def op_rem_long():
+% bindiv(result="%rdx", second="%rcx", wide="1", suffix="q", ext="cqo", rem="1")
+
+%def op_rem_long_2addr():
+% bindiv2addr(result="%rdx", second="%rcx", wide="1", suffix="q", rem="1", ext="cqo")
+
+%def op_rsub_int():
+/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
+% binopLit16(instr="subl %eax, %ecx", result="%ecx")
+
+%def op_rsub_int_lit8():
+% binopLit8(instr="subl %eax, %ecx", result="%ecx")
+
+%def op_shl_int():
+% binop1(instr="sall %cl, %eax")
+
+%def op_shl_int_2addr():
+% shop2addr(instr="sall %cl, %eax")
+
+%def op_shl_int_lit8():
+% binopLit8(instr="sall %cl, %eax")
+
+%def op_shl_long():
+% binop1(instr="salq %cl, %rax", wide="1")
+
+%def op_shl_long_2addr():
+% shop2addr(instr="salq %cl, %rax", wide="1")
+
+%def op_shr_int():
+% binop1(instr="sarl %cl, %eax")
+
+%def op_shr_int_2addr():
+% shop2addr(instr="sarl %cl, %eax")
+
+%def op_shr_int_lit8():
+% binopLit8(instr="sarl %cl, %eax")
+
+%def op_shr_long():
+% binop1(instr="sarq %cl, %rax", wide="1")
+
+%def op_shr_long_2addr():
+% shop2addr(instr="sarq %cl, %rax", wide="1")
+
+%def op_sub_int():
+% binop(instr="subl (rFP,%rcx,4), %eax")
+
+%def op_sub_int_2addr():
+% binop2addr(instr="subl %eax, (rFP,%rcx,4)")
+
+%def op_sub_long():
+% binopWide(instr="subq (rFP,%rcx,4), %rax")
+
+%def op_sub_long_2addr():
+% binopWide2addr(instr="subq %rax, (rFP,%rcx,4)")
+
+%def op_ushr_int():
+% binop1(instr="shrl %cl, %eax")
+
+%def op_ushr_int_2addr():
+% shop2addr(instr="shrl %cl, %eax")
+
+%def op_ushr_int_lit8():
+% binopLit8(instr="shrl %cl, %eax")
+
+%def op_ushr_long():
+% binop1(instr="shrq %cl, %rax", wide="1")
+
+%def op_ushr_long_2addr():
+% shop2addr(instr="shrq %cl, %rax", wide="1")
+
+%def op_xor_int():
+% binop(instr="xorl (rFP,%rcx,4), %eax")
+
+%def op_xor_int_2addr():
+% binop2addr(instr="xorl %eax, (rFP,%rcx,4)")
+
+%def op_xor_int_lit16():
+% binopLit16(instr="xorl %ecx, %eax")
+
+%def op_xor_int_lit8():
+% binopLit8(instr="xorl %ecx, %eax")
+
+%def op_xor_long():
+% binopWide(instr="xorq (rFP,%rcx,4), %rax")
+
+%def op_xor_long_2addr():
+% binopWide2addr(instr="xorq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/array.S b/runtime/interpreter/mterp/x86_64/array.S
new file mode 100644
index 0000000..e49c097
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/array.S
@@ -0,0 +1,178 @@
+%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
+/*
+ * Array get, 32 bits or less. vAA <- vBB[vCC].
+ *
+ * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide
+ *
+ */
+ /* op vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # eax <- BB
+ movzbq 3(rPC), %rcx # ecx <- CC
+ GET_VREG %eax, %rax # eax <- vBB (array object)
+ GET_VREG %ecx, %rcx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ .if $wide
+ movq $data_offset(%rax,%rcx,8), %rax
+ SET_WIDE_VREG %rax, rINSTq
+ .else
+ $load $data_offset(%rax,%rcx,$shift), %eax
+ SET_VREG %eax, rINSTq
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aget_boolean():
+% op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aget_byte():
+% op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aget_char():
+% op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aget_object():
+/*
+ * Array object get. vAA <- vBB[vCC].
+ *
+ * for: aget-object
+ */
+ /* op vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # rax <- BB
+ movzbq 3(rPC), %rcx # rcx <- CC
+ GET_VREG OUT_32_ARG0, %rax # eax <- vBB (array object)
+ GET_VREG OUT_32_ARG1, %rcx # ecx <- vCC (requested index)
+ EXPORT_PC
+ call SYMBOL(artAGetObjectFromMterp) # (array, index)
+ movq rSELF, %rcx
+ cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
+ jnz MterpException
+ SET_VREG_OBJECT %eax, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aget_short():
+% op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aget_wide():
+% op_aget(load="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
+
+%def op_aput(reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
+/*
+ * Array put, 32 bits or less. vBB[vCC] <- vAA.
+ *
+ * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide
+ *
+ */
+ /* op vAA, vBB, vCC */
+ movzbq 2(rPC), %rax # rax <- BB
+ movzbq 3(rPC), %rcx # rcx <- CC
+ GET_VREG %eax, %rax # eax <- vBB (array object)
+ GET_VREG %ecx, %rcx # ecx <- vCC (requested index)
+ testl %eax, %eax # null array object?
+ je common_errNullObject # bail if so
+ cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
+ jae common_errArrayIndex # index >= length, bail.
+ .if $wide
+ GET_WIDE_VREG rINSTq, rINSTq
+ .else
+ GET_VREG rINST, rINSTq
+ .endif
+ $store $reg, $data_offset(%rax,%rcx,$shift)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aput_boolean():
+% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
+
+%def op_aput_byte():
+% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
+
+%def op_aput_char():
+% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
+
+%def op_aput_object():
+/*
+ * Store an object into an array. vBB[vCC] <- vAA.
+ */
+ /* op vAA, vBB, vCC */
+ EXPORT_PC
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
+ movq rPC, OUT_ARG1
+ REFRESH_INST ${opnum}
+ movq rINSTq, OUT_ARG2
+ call SYMBOL(MterpAputObject) # (array, index)
+ testb %al, %al
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_aput_short():
+% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
+
+%def op_aput_wide():
+% op_aput(reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
+
+%def op_array_length():
+/*
+ * Return the length of an array.
+ */
+ movl rINST, %eax # eax <- BA
+ sarl $$4, rINST # rINST <- B
+ GET_VREG %ecx, rINSTq # ecx <- vB (object ref)
+ testl %ecx, %ecx # is null?
+ je common_errNullObject
+ andb $$0xf, %al # eax <- A
+ movl MIRROR_ARRAY_LENGTH_OFFSET(%rcx), rINST
+ SET_VREG rINST, %rax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_fill_array_data():
+ /* fill-array-data vAA, +BBBBBBBB */
+ EXPORT_PC
+ movslq 2(rPC), %rcx # rcx <- ssssssssBBBBbbbb
+ leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + ssssssssBBBBbbbb*2
+ GET_VREG OUT_32_ARG0, rINSTq # OUT_ARG0 <- vAA (array object)
+ call SYMBOL(MterpFillArrayData) # (obj, payload)
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_filled_new_array(helper="MterpFilledNewArray"):
+/*
+ * Create a new array with elements filled from registers.
+ *
+ * for: filled-new-array, filled-new-array/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
+ .extern $helper
+ EXPORT_PC
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
+ movq rPC, OUT_ARG1
+ movq rSELF, OUT_ARG2
+ call SYMBOL($helper)
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_filled_new_array_range():
+% op_filled_new_array(helper="MterpFilledNewArrayRange")
+
+%def op_new_array():
+/*
+ * Allocate an array of objects, specified with the array class
+ * and a count.
+ *
+ * The verifier guarantees that this is an array class, so we don't
+ * check for it here.
+ */
+ /* new-array vA, vB, class@CCCC */
+ EXPORT_PC
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
+ movq rPC, OUT_ARG1
+ REFRESH_INST ${opnum}
+ movq rINSTq, OUT_ARG2
+ movq rSELF, OUT_ARG3
+ call SYMBOL(MterpNewArray)
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/bincmp.S b/runtime/interpreter/mterp/x86_64/bincmp.S
deleted file mode 100644
index 64a118c..0000000
--- a/runtime/interpreter/mterp/x86_64/bincmp.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def bincmp(revcmp=""):
-/*
- * Generic two-operand compare-and-branch operation. Provide a "revcmp"
- * fragment that specifies the *reverse* comparison to perform, e.g.
- * for "if-le" you would use "gt".
- *
- * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
- */
- /* if-cmp vA, vB, +CCCC */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # rcx <- A
- GET_VREG %eax, %rcx # eax <- vA
- cmpl VREG_ADDRESS(rINSTq), %eax # compare (vA, vB)
- j${revcmp} 1f
- movswq 2(rPC), rINSTq # Get signed branch offset
- testq rINSTq, rINSTq
- jmp MterpCommonTakenBranch
-1:
- cmpl $$JIT_CHECK_OSR, rPROFILE
- je .L_check_not_taken_osr
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/bindiv.S b/runtime/interpreter/mterp/x86_64/bindiv.S
deleted file mode 100644
index d7e5333..0000000
--- a/runtime/interpreter/mterp/x86_64/bindiv.S
+++ /dev/null
@@ -1,34 +0,0 @@
-%def bindiv(result="", second="", wide="", suffix="", rem="0", ext="cdq"):
-/*
- * 32-bit binary div/rem operation. Handles special case of op1=-1.
- */
- /* div/rem vAA, vBB, vCC */
- movzbq 2(rPC), %rax # rax <- BB
- movzbq 3(rPC), %rcx # rcx <- CC
- .if $wide
- GET_WIDE_VREG %rax, %rax # eax <- vBB
- GET_WIDE_VREG $second, %rcx # ecx <- vCC
- .else
- GET_VREG %eax, %rax # eax <- vBB
- GET_VREG $second, %rcx # ecx <- vCC
- .endif
- test${suffix} $second, $second
- jz common_errDivideByZero
- cmp${suffix} $$-1, $second
- je 2f
- $ext # rdx:rax <- sign-extended of rax
- idiv${suffix} $second
-1:
- .if $wide
- SET_WIDE_VREG $result, rINSTq # eax <- vBB
- .else
- SET_VREG $result, rINSTq # eax <- vBB
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-2:
- .if $rem
- xor${suffix} $result, $result
- .else
- neg${suffix} $result
- .endif
- jmp 1b
diff --git a/runtime/interpreter/mterp/x86_64/bindiv2addr.S b/runtime/interpreter/mterp/x86_64/bindiv2addr.S
deleted file mode 100644
index c55351e..0000000
--- a/runtime/interpreter/mterp/x86_64/bindiv2addr.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def bindiv2addr(result="", second="", wide="", suffix="", rem="0", ext="cdq"):
-/*
- * 32-bit binary div/rem operation. Handles special case of op1=-1.
- */
- /* div/rem/2addr vA, vB */
- movl rINST, %ecx # rcx <- BA
- sarl $$4, %ecx # rcx <- B
- andb $$0xf, rINSTbl # rINST <- A
- .if $wide
- GET_WIDE_VREG %rax, rINSTq # eax <- vA
- GET_WIDE_VREG $second, %rcx # ecx <- vB
- .else
- GET_VREG %eax, rINSTq # eax <- vA
- GET_VREG $second, %rcx # ecx <- vB
- .endif
- test${suffix} $second, $second
- jz common_errDivideByZero
- cmp${suffix} $$-1, $second
- je 2f
- $ext # rdx:rax <- sign-extended of rax
- idiv${suffix} $second
-1:
- .if $wide
- SET_WIDE_VREG $result, rINSTq # vA <- result
- .else
- SET_VREG $result, rINSTq # vA <- result
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-2:
- .if $rem
- xor${suffix} $result, $result
- .else
- neg${suffix} $result
- .endif
- jmp 1b
diff --git a/runtime/interpreter/mterp/x86_64/bindivLit16.S b/runtime/interpreter/mterp/x86_64/bindivLit16.S
deleted file mode 100644
index dbda834..0000000
--- a/runtime/interpreter/mterp/x86_64/bindivLit16.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def bindivLit16(result="", rem="0"):
-/*
- * 32-bit binary div/rem operation. Handles special case of op1=-1.
- */
- /* div/rem/lit16 vA, vB, #+CCCC */
- /* Need A in rINST, ssssCCCC in ecx, vB in eax */
- movl rINST, %eax # rax <- 000000BA
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %rax # eax <- vB
- movswl 2(rPC), %ecx # ecx <- ssssCCCC
- andb $$0xf, rINSTbl # rINST <- A
- testl %ecx, %ecx
- jz common_errDivideByZero
- cmpl $$-1, %ecx
- je 2f
- cdq # rax <- sign-extended of eax
- idivl %ecx
-1:
- SET_VREG $result, rINSTq # vA <- result
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-2:
- .if $rem
- xorl $result, $result
- .else
- negl $result
- .endif
- jmp 1b
diff --git a/runtime/interpreter/mterp/x86_64/bindivLit8.S b/runtime/interpreter/mterp/x86_64/bindivLit8.S
deleted file mode 100644
index a5164b5..0000000
--- a/runtime/interpreter/mterp/x86_64/bindivLit8.S
+++ /dev/null
@@ -1,25 +0,0 @@
-%def bindivLit8(result="", rem="0"):
-/*
- * 32-bit div/rem "lit8" binary operation. Handles special case of
- * op0=minint & op1=-1
- */
- /* div/rem/lit8 vAA, vBB, #+CC */
- movzbq 2(rPC), %rax # eax <- BB
- movsbl 3(rPC), %ecx # ecx <- ssssssCC
- GET_VREG %eax, %rax # eax <- rBB
- testl %ecx, %ecx
- je common_errDivideByZero
- cmpl $$-1, %ecx
- je 2f
- cdq # rax <- sign-extended of eax
- idivl %ecx
-1:
- SET_VREG $result, rINSTq # vA <- result
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-2:
- .if $rem
- xorl $result, $result
- .else
- negl $result
- .endif
- jmp 1b
diff --git a/runtime/interpreter/mterp/x86_64/binop.S b/runtime/interpreter/mterp/x86_64/binop.S
deleted file mode 100644
index fddeaa1..0000000
--- a/runtime/interpreter/mterp/x86_64/binop.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def binop(result="%eax", instr=""):
-/*
- * Generic 32-bit binary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than eax, you can override "result".)
- *
- * For: add-int, sub-int, and-int, or-int,
- * xor-int, shl-int, shr-int, ushr-int
- */
- /* binop vAA, vBB, vCC */
- movzbq 2(rPC), %rax # rax <- BB
- movzbq 3(rPC), %rcx # rcx <- CC
- GET_VREG %eax, %rax # eax <- vBB
- $instr # ex: addl (rFP,%rcx,4),%eax
- SET_VREG $result, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/binop1.S b/runtime/interpreter/mterp/x86_64/binop1.S
deleted file mode 100644
index 9915c32..0000000
--- a/runtime/interpreter/mterp/x86_64/binop1.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def binop1(wide="0", instr=""):
-/*
- * Generic 32-bit binary operation in which both operands loaded to
- * registers (op0 in eax, op1 in ecx).
- */
- /* binop vAA, vBB, vCC */
- movzbq 2(rPC), %rax # eax <- BB
- movzbq 3(rPC), %rcx # ecx <- CC
- GET_VREG %ecx, %rcx # eax <- vCC
- .if $wide
- GET_WIDE_VREG %rax, %rax # rax <- vBB
- $instr # ex: addl %ecx,%eax
- SET_WIDE_VREG %rax, rINSTq
- .else
- GET_VREG %eax, %rax # eax <- vBB
- $instr # ex: addl %ecx,%eax
- SET_VREG %eax, rINSTq
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/binop2addr.S b/runtime/interpreter/mterp/x86_64/binop2addr.S
deleted file mode 100644
index 1cdf7fd..0000000
--- a/runtime/interpreter/mterp/x86_64/binop2addr.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def binop2addr(result="%eax", instr=""):
-/*
- * Generic 32-bit "/2addr" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = r0 op r1".
- * This could be an instruction or a function call.
- *
- * 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 */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_VREG %eax, rINSTq # eax <- vB
- $instr # for ex: addl %eax,(rFP,%ecx,4)
- CLEAR_REF %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/binopLit16.S b/runtime/interpreter/mterp/x86_64/binopLit16.S
deleted file mode 100644
index bb882cb..0000000
--- a/runtime/interpreter/mterp/x86_64/binopLit16.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def binopLit16(result="%eax", instr=""):
-/*
- * Generic 32-bit "lit16" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = eax op ecx".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than eax, you can override "result".)
- *
- * For: add-int/lit16, rsub-int,
- * and-int/lit16, or-int/lit16, xor-int/lit16
- */
- /* binop/lit16 vA, vB, #+CCCC */
- movl rINST, %eax # rax <- 000000BA
- sarl $$4, %eax # eax <- B
- GET_VREG %eax, %rax # eax <- vB
- andb $$0xf, rINSTbl # rINST <- A
- movswl 2(rPC), %ecx # ecx <- ssssCCCC
- $instr # for example: addl %ecx, %eax
- SET_VREG $result, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/binopLit8.S b/runtime/interpreter/mterp/x86_64/binopLit8.S
deleted file mode 100644
index a30d2e8..0000000
--- a/runtime/interpreter/mterp/x86_64/binopLit8.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def binopLit8(result="%eax", instr=""):
-/*
- * Generic 32-bit "lit8" binary operation. Provide an "instr" line
- * that specifies an instruction that performs "result = eax op ecx".
- * This could be an x86 instruction or a function call. (If the result
- * comes back in a register other than r0, you can override "result".)
- *
- * For: add-int/lit8, rsub-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 */
- movzbq 2(rPC), %rax # rax <- BB
- movsbl 3(rPC), %ecx # rcx <- ssssssCC
- GET_VREG %eax, %rax # eax <- rBB
- $instr # ex: addl %ecx,%eax
- SET_VREG $result, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/binopWide.S b/runtime/interpreter/mterp/x86_64/binopWide.S
deleted file mode 100644
index 015d9ee..0000000
--- a/runtime/interpreter/mterp/x86_64/binopWide.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def binopWide(instr=""):
-/*
- * Generic 64-bit binary operation.
- */
- /* binop vAA, vBB, vCC */
- movzbq 2(rPC), %rax # eax <- BB
- movzbq 3(rPC), %rcx # ecx <- CC
- GET_WIDE_VREG %rax, %rax # rax <- v[BB]
- $instr # ex: addq (rFP,%rcx,4),%rax
- SET_WIDE_VREG %rax, rINSTq # v[AA] <- rax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/binopWide2addr.S b/runtime/interpreter/mterp/x86_64/binopWide2addr.S
deleted file mode 100644
index e4c1e4d..0000000
--- a/runtime/interpreter/mterp/x86_64/binopWide2addr.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def binopWide2addr(instr=""):
-/*
- * Generic 64-bit binary operation.
- */
- /* binop/2addr vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_WIDE_VREG %rax, rINSTq # rax <- vB
- $instr # for ex: addq %rax,(rFP,%rcx,4)
- CLEAR_WIDE_REF %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/const.S b/runtime/interpreter/mterp/x86_64/const.S
deleted file mode 100644
index fa98637..0000000
--- a/runtime/interpreter/mterp/x86_64/const.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def const(helper="UndefinedConstHandler"):
- /* const/class vAA, type@BBBB */
- /* const/method-handle vAA, method_handle@BBBB */
- /* const/method-type vAA, proto@BBBB */
- /* const/string vAA, string@@BBBB */
- .extern $helper
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # eax <- OUT_ARG0
- movq rINSTq, OUT_ARG1
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL($helper) # (index, tgt_reg, shadow_frame, self)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/control_flow.S b/runtime/interpreter/mterp/x86_64/control_flow.S
new file mode 100644
index 0000000..2f3b5e5
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/control_flow.S
@@ -0,0 +1,206 @@
+%def bincmp(revcmp=""):
+/*
+ * Generic two-operand compare-and-branch operation. Provide a "revcmp"
+ * fragment that specifies the *reverse* comparison to perform, e.g.
+ * for "if-le" you would use "gt".
+ *
+ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
+ */
+ /* if-cmp vA, vB, +CCCC */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # rcx <- A
+ GET_VREG %eax, %rcx # eax <- vA
+ cmpl VREG_ADDRESS(rINSTq), %eax # compare (vA, vB)
+ j${revcmp} 1f
+ movswq 2(rPC), rINSTq # Get signed branch offset
+ testq rINSTq, rINSTq
+ jmp MterpCommonTakenBranch
+1:
+ cmpl $$JIT_CHECK_OSR, rPROFILE
+ je .L_check_not_taken_osr
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def zcmp(revcmp=""):
+/*
+ * Generic one-operand compare-and-branch operation. Provide a "revcmp"
+ * fragment that specifies the *reverse* comparison to perform, e.g.
+ * for "if-le" you would use "gt".
+ *
+ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
+ */
+ /* if-cmp vAA, +BBBB */
+ cmpl $$0, VREG_ADDRESS(rINSTq) # compare (vA, 0)
+ j${revcmp} 1f
+ movswq 2(rPC), rINSTq # fetch signed displacement
+ testq rINSTq, rINSTq
+ jmp MterpCommonTakenBranch
+1:
+ cmpl $$JIT_CHECK_OSR, rPROFILE
+ je .L_check_not_taken_osr
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_goto():
+/*
+ * Unconditional branch, 8-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto +AA */
+ movsbq rINSTbl, rINSTq # rINSTq <- ssssssAA
+ testq rINSTq, rINSTq
+ jmp MterpCommonTakenBranch
+
+%def op_goto_16():
+/*
+ * Unconditional branch, 16-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ */
+ /* goto/16 +AAAA */
+ movswq 2(rPC), rINSTq # rINSTq <- ssssAAAA
+ testq rINSTq, rINSTq
+ jmp MterpCommonTakenBranch
+
+%def op_goto_32():
+/*
+ * Unconditional branch, 32-bit offset.
+ *
+ * The branch distance is a signed code-unit offset, which we need to
+ * double to get a byte offset.
+ *
+ * Because we need the SF bit set, we'll use an adds
+ * to convert from Dalvik offset to byte offset.
+ */
+ /* goto/32 +AAAAAAAA */
+ movslq 2(rPC), rINSTq # rINSTq <- AAAAAAAA
+ testq rINSTq, rINSTq
+ jmp MterpCommonTakenBranch
+
+%def op_if_eq():
+% bincmp(revcmp="ne")
+
+%def op_if_eqz():
+% zcmp(revcmp="ne")
+
+%def op_if_ge():
+% bincmp(revcmp="l")
+
+%def op_if_gez():
+% zcmp(revcmp="l")
+
+%def op_if_gt():
+% bincmp(revcmp="le")
+
+%def op_if_gtz():
+% zcmp(revcmp="le")
+
+%def op_if_le():
+% bincmp(revcmp="g")
+
+%def op_if_lez():
+% zcmp(revcmp="g")
+
+%def op_if_lt():
+% bincmp(revcmp="ge")
+
+%def op_if_ltz():
+% zcmp(revcmp="ge")
+
+%def op_if_ne():
+% bincmp(revcmp="e")
+
+%def op_if_nez():
+% zcmp(revcmp="e")
+
+%def op_packed_switch(func="MterpDoPackedSwitch"):
+/*
+ * Handle a packed-switch or sparse-switch instruction. In both cases
+ * we decode it and hand it off to a helper function.
+ *
+ * We don't really expect backward branches in a switch statement, but
+ * they're perfectly legal, so we check for them here.
+ *
+ * for: packed-switch, sparse-switch
+ */
+ /* op vAA, +BBBB */
+ movslq 2(rPC), OUT_ARG0 # rcx <- ssssssssBBBBbbbb
+ leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + ssssssssBBBBbbbb*2
+ GET_VREG OUT_32_ARG1, rINSTq # eax <- vAA
+ call SYMBOL($func)
+ testl %eax, %eax
+ movslq %eax, rINSTq
+ jmp MterpCommonTakenBranch
+
+%def op_return():
+/*
+ * Return a 32-bit value.
+ *
+ * for: return, return-object
+ */
+ /* op vAA */
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movq rSELF, OUT_ARG0
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
+ jz 1f
+ call SYMBOL(MterpSuspendCheck)
+1:
+ GET_VREG %eax, rINSTq # eax <- vAA
+ jmp MterpReturn
+
+%def op_return_object():
+% op_return()
+
+%def op_return_void():
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movq rSELF, OUT_ARG0
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
+ jz 1f
+ call SYMBOL(MterpSuspendCheck)
+1:
+ xorq %rax, %rax
+ jmp MterpReturn
+
+%def op_return_void_no_barrier():
+ movq rSELF, OUT_ARG0
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
+ jz 1f
+ call SYMBOL(MterpSuspendCheck)
+1:
+ xorq %rax, %rax
+ jmp MterpReturn
+
+%def op_return_wide():
+/*
+ * Return a 64-bit value.
+ */
+ /* return-wide vAA */
+ .extern MterpThreadFenceForConstructor
+ call SYMBOL(MterpThreadFenceForConstructor)
+ movq rSELF, OUT_ARG0
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
+ jz 1f
+ call SYMBOL(MterpSuspendCheck)
+1:
+ GET_WIDE_VREG %rax, rINSTq # eax <- v[AA]
+ jmp MterpReturn
+
+%def op_sparse_switch():
+% op_packed_switch(func="MterpDoSparseSwitch")
+
+%def op_throw():
+/*
+ * Throw an exception object in the current thread.
+ */
+ /* throw vAA */
+ EXPORT_PC
+ GET_VREG %eax, rINSTq # eax<- vAA (exception object)
+ testb %al, %al
+ jz common_errNullObject
+ movq rSELF, %rcx
+ movq %rax, THREAD_EXCEPTION_OFFSET(%rcx)
+ jmp MterpException
diff --git a/runtime/interpreter/mterp/x86_64/cvtfp_int.S b/runtime/interpreter/mterp/x86_64/cvtfp_int.S
deleted file mode 100644
index e18986f..0000000
--- a/runtime/interpreter/mterp/x86_64/cvtfp_int.S
+++ /dev/null
@@ -1,27 +0,0 @@
-%def cvtfp_int(fp_suffix="", i_suffix="", max_const="", result_reg="", wide=""):
-/* On fp to int conversions, Java requires that
- * if the result > maxint, it should be clamped to maxint. If it is less
- * than minint, it should be clamped to minint. If it is a nan, the result
- * should be zero. Further, the rounding mode is to truncate.
- */
- /* float/double to int/long vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- movs${fp_suffix} VREG_ADDRESS(rINSTq), %xmm0
- mov${i_suffix} ${max_const}, ${result_reg}
- cvtsi2s${fp_suffix}${i_suffix} ${result_reg}, %xmm1
- comis${fp_suffix} %xmm1, %xmm0
- jae 1f
- jp 2f
- cvtts${fp_suffix}2si${i_suffix} %xmm0, ${result_reg}
- jmp 1f
-2:
- xor${i_suffix} ${result_reg}, ${result_reg}
-1:
- .if $wide
- SET_WIDE_VREG ${result_reg}, %rcx
- .else
- SET_VREG ${result_reg}, %rcx
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/entry.S b/runtime/interpreter/mterp/x86_64/entry.S
deleted file mode 100644
index 515ffbc..0000000
--- a/runtime/interpreter/mterp/x86_64/entry.S
+++ /dev/null
@@ -1,80 +0,0 @@
-%def entry():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Interpreter entry point.
- */
-
- .text
- ASM_HIDDEN SYMBOL(ExecuteMterpImpl)
- .global SYMBOL(ExecuteMterpImpl)
- FUNCTION_TYPE(ExecuteMterpImpl)
-
-/*
- * On entry:
- * 0 Thread* self
- * 1 insns_
- * 2 ShadowFrame
- * 3 JValue* result_register
- *
- */
-
-SYMBOL(ExecuteMterpImpl):
- .cfi_startproc
- .cfi_def_cfa rsp, 8
-
- /* Spill callee save regs */
- PUSH %rbx
- PUSH %rbp
- PUSH %r12
- PUSH %r13
- PUSH %r14
- PUSH %r15
-
- /* Allocate frame */
- subq $$FRAME_SIZE, %rsp
- .cfi_adjust_cfa_offset FRAME_SIZE
-
- /* Remember the return register */
- movq IN_ARG3, SHADOWFRAME_RESULT_REGISTER_OFFSET(IN_ARG2)
-
- /* Remember the code_item */
- movq IN_ARG1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(IN_ARG2)
-
- /* set up "named" registers */
- movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(IN_ARG2), %eax
- leaq SHADOWFRAME_VREGS_OFFSET(IN_ARG2), rFP
- leaq (rFP, %rax, 4), rREFS
- movl SHADOWFRAME_DEX_PC_OFFSET(IN_ARG2), %eax
- leaq (IN_ARG1, %rax, 2), rPC
- CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
- EXPORT_PC
-
- /* Starting ibase */
- movq IN_ARG0, rSELF
- REFRESH_IBASE_REG IN_ARG0
-
- /* Set up for backwards branches & osr profiling */
- movq IN_ARG0, OUT_ARG2 /* Set up OUT_ARG2 before clobbering IN_ARG0 */
- movq OFF_FP_METHOD(rFP), OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpSetUpHotnessCountdown)
- movswl %ax, rPROFILE
-
- /* start executing the instruction at rPC */
- FETCH_INST
- GOTO_NEXT
- /* NOTE: no fallthrough */
diff --git a/runtime/interpreter/mterp/x86_64/fallback.S b/runtime/interpreter/mterp/x86_64/fallback.S
deleted file mode 100644
index e3c2e2b..0000000
--- a/runtime/interpreter/mterp/x86_64/fallback.S
+++ /dev/null
@@ -1,4 +0,0 @@
-%def fallback():
-/* Transfer stub to alternate interpreter */
- jmp MterpFallback
-
diff --git a/runtime/interpreter/mterp/x86_64/field.S b/runtime/interpreter/mterp/x86_64/field.S
deleted file mode 100644
index f6c40eb..0000000
--- a/runtime/interpreter/mterp/x86_64/field.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def field(helper=""):
- /*
- * General field read / write (iget-* iput-* sget-* sput-*).
- */
- .extern $helper
- REFRESH_INST ${opnum} # fix rINST to include opcode
- movq rPC, OUT_ARG0 # arg0: Instruction* inst
- movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
- movq rSELF, OUT_ARG3 # arg3: Thread* self
- call SYMBOL($helper)
- testb %al, %al
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/floating_point.S b/runtime/interpreter/mterp/x86_64/floating_point.S
new file mode 100644
index 0000000..b40c0e6
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/floating_point.S
@@ -0,0 +1,236 @@
+%def fpcmp(suff="d", nanval="pos"):
+/*
+ * Compare two floating-point values. Puts 0, 1, or -1 into the
+ * destination register based on the results of the comparison.
+ *
+ * int compare(x, y) {
+ * if (x == y) {
+ * return 0;
+ * } else if (x < y) {
+ * return -1;
+ * } else if (x > y) {
+ * return 1;
+ * } else {
+ * return nanval ? 1 : -1;
+ * }
+ * }
+ */
+ /* op vAA, vBB, vCC */
+ movzbq 3(rPC), %rcx # ecx<- CC
+ movzbq 2(rPC), %rax # eax<- BB
+ movs${suff} VREG_ADDRESS(%rax), %xmm0
+ xor %eax, %eax
+ ucomis${suff} VREG_ADDRESS(%rcx), %xmm0
+ jp .L${opcode}_nan_is_${nanval}
+ je .L${opcode}_finish
+ jb .L${opcode}_less
+.L${opcode}_nan_is_pos:
+ addb $$1, %al
+ jmp .L${opcode}_finish
+.L${opcode}_nan_is_neg:
+.L${opcode}_less:
+ movl $$-1, %eax
+.L${opcode}_finish:
+ SET_VREG %eax, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def fpcvt(source_suffix="", dest_suffix="", wide=""):
+/*
+ * Generic 32-bit FP conversion operation.
+ */
+ /* unop vA, vB */
+ movl rINST, %ecx # rcx <- A+
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ cvts${source_suffix}2s${dest_suffix} VREG_ADDRESS(rINSTq), %xmm0
+ .if $wide
+ movsd %xmm0, VREG_ADDRESS(%rcx)
+ CLEAR_WIDE_REF %rcx
+ .else
+ movss %xmm0, VREG_ADDRESS(%rcx)
+ CLEAR_REF %rcx
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def sseBinop(instr="", suff=""):
+ movzbq 2(rPC), %rcx # ecx <- BB
+ movzbq 3(rPC), %rax # eax <- CC
+ movs${suff} VREG_ADDRESS(%rcx), %xmm0 # %xmm0 <- 1st src
+ ${instr}${suff} VREG_ADDRESS(%rax), %xmm0
+ movs${suff} %xmm0, VREG_ADDRESS(rINSTq) # vAA <- %xmm0
+ pxor %xmm0, %xmm0
+ movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def sseBinop2Addr(instr="", suff=""):
+ movl rINST, %ecx # ecx <- A+
+ andl $$0xf, %ecx # ecx <- A
+ movs${suff} VREG_ADDRESS(%rcx), %xmm0 # %xmm0 <- 1st src
+ sarl $$4, rINST # rINST<- B
+ ${instr}${suff} VREG_ADDRESS(rINSTq), %xmm0
+ movs${suff} %xmm0, VREG_ADDRESS(%rcx) # vAA<- %xmm0
+ pxor %xmm0, %xmm0
+ movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_add_double():
+% sseBinop(instr="adds", suff="d")
+
+%def op_add_double_2addr():
+% sseBinop2Addr(instr="adds", suff="d")
+
+%def op_add_float():
+% sseBinop(instr="adds", suff="s")
+
+%def op_add_float_2addr():
+% sseBinop2Addr(instr="adds", suff="s")
+
+%def op_cmpg_double():
+% fpcmp(suff="d", nanval="pos")
+
+%def op_cmpg_float():
+% fpcmp(suff="s", nanval="pos")
+
+%def op_cmpl_double():
+% fpcmp(suff="d", nanval="neg")
+
+%def op_cmpl_float():
+% fpcmp(suff="s", nanval="neg")
+
+%def op_div_double():
+% sseBinop(instr="divs", suff="d")
+
+%def op_div_double_2addr():
+% sseBinop2Addr(instr="divs", suff="d")
+
+%def op_div_float():
+% sseBinop(instr="divs", suff="s")
+
+%def op_div_float_2addr():
+% sseBinop2Addr(instr="divs", suff="s")
+
+%def op_double_to_float():
+% fpcvt(source_suffix="d", dest_suffix="s", wide="0")
+
+%def op_double_to_int():
+% cvtfp_int(fp_suffix="d", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
+
+%def op_double_to_long():
+% cvtfp_int(fp_suffix="d", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
+
+%def op_float_to_double():
+% fpcvt(source_suffix="s", dest_suffix="d", wide="1")
+
+%def op_float_to_int():
+% cvtfp_int(fp_suffix="s", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
+
+%def op_float_to_long():
+% cvtfp_int(fp_suffix="s", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
+
+%def op_int_to_double():
+% fpcvt(source_suffix="i", dest_suffix="dl", wide="1")
+
+%def op_int_to_float():
+% fpcvt(source_suffix="i", dest_suffix="sl", wide="0")
+
+%def op_long_to_double():
+% fpcvt(source_suffix="i", dest_suffix="dq", wide="1")
+
+%def op_long_to_float():
+% fpcvt(source_suffix="i", dest_suffix="sq", wide="0")
+
+%def op_mul_double():
+% sseBinop(instr="muls", suff="d")
+
+%def op_mul_double_2addr():
+% sseBinop2Addr(instr="muls", suff="d")
+
+%def op_mul_float():
+% sseBinop(instr="muls", suff="s")
+
+%def op_mul_float_2addr():
+% sseBinop2Addr(instr="muls", suff="s")
+
+%def op_neg_double():
+% unop(preinstr=" movq $0x8000000000000000, %rsi", instr=" xorq %rsi, %rax", wide="1")
+
+%def op_neg_float():
+% unop(instr=" xorl $0x80000000, %eax")
+
+%def op_rem_double():
+ /* rem_double vAA, vBB, vCC */
+ movzbq 3(rPC), %rcx # ecx <- BB
+ movzbq 2(rPC), %rax # eax <- CC
+ fldl VREG_ADDRESS(%rcx) # %st1 <- fp[vBB]
+ fldl VREG_ADDRESS(%rax) # %st0 <- fp[vCC]
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstpl VREG_ADDRESS(rINSTq) # fp[vAA] <- %st
+ CLEAR_WIDE_REF rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_rem_double_2addr():
+ /* rem_double/2addr vA, vB */
+ movzbq rINSTbl, %rcx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ fldl VREG_ADDRESS(rINSTq) # vB to fp stack
+ andb $$0xf, %cl # ecx <- A
+ fldl VREG_ADDRESS(%rcx) # vA to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstpl VREG_ADDRESS(%rcx) # %st to vA
+ CLEAR_WIDE_REF %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_rem_float():
+ /* rem_float vAA, vBB, vCC */
+ movzbq 3(rPC), %rcx # ecx <- BB
+ movzbq 2(rPC), %rax # eax <- CC
+ flds VREG_ADDRESS(%rcx) # vBB to fp stack
+ flds VREG_ADDRESS(%rax) # vCC to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstps VREG_ADDRESS(rINSTq) # %st to vAA
+ CLEAR_REF rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_rem_float_2addr():
+ /* rem_float/2addr vA, vB */
+ movzbq rINSTbl, %rcx # ecx <- A+
+ sarl $$4, rINST # rINST <- B
+ flds VREG_ADDRESS(rINSTq) # vB to fp stack
+ andb $$0xf, %cl # ecx <- A
+ flds VREG_ADDRESS(%rcx) # vA to fp stack
+1:
+ fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ fstps VREG_ADDRESS(%rcx) # %st to vA
+ CLEAR_REF %rcx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_sub_double():
+% sseBinop(instr="subs", suff="d")
+
+%def op_sub_double_2addr():
+% sseBinop2Addr(instr="subs", suff="d")
+
+%def op_sub_float():
+% sseBinop(instr="subs", suff="s")
+
+%def op_sub_float_2addr():
+% sseBinop2Addr(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/footer.S b/runtime/interpreter/mterp/x86_64/footer.S
deleted file mode 100644
index 140fbae..0000000
--- a/runtime/interpreter/mterp/x86_64/footer.S
+++ /dev/null
@@ -1,298 +0,0 @@
-%def footer():
-/*
- * ===========================================================================
- * Common subroutines and data
- * ===========================================================================
- */
-
- .text
- .align 2
-
-/*
- * We've detected a condition that will result in an exception, but the exception
- * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
- * TUNING: for consistency, we may want to just go ahead and handle these here.
- */
-common_errDivideByZero:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogDivideByZeroException)
-#endif
- jmp MterpCommonFallback
-
-common_errArrayIndex:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogArrayIndexException)
-#endif
- jmp MterpCommonFallback
-
-common_errNegativeArraySize:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogNegativeArraySizeException)
-#endif
- jmp MterpCommonFallback
-
-common_errNoSuchMethod:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogNoSuchMethodException)
-#endif
- jmp MterpCommonFallback
-
-common_errNullObject:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogNullObjectException)
-#endif
- jmp MterpCommonFallback
-
-common_exceptionThrown:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogExceptionThrownException)
-#endif
- jmp MterpCommonFallback
-
-MterpSuspendFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movl THREAD_FLAGS_OFFSET(OUT_ARG0), OUT_32_ARG2
- call SYMBOL(MterpLogSuspendFallback)
-#endif
- jmp MterpCommonFallback
-
-/*
- * If we're here, something is out of the ordinary. If there is a pending
- * exception, handle it. Otherwise, roll back and retry with the reference
- * interpreter.
- */
-MterpPossibleException:
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jz MterpFallback
- /* intentional fallthrough - handle pending exception. */
-
-/*
- * On return from a runtime helper routine, we've found a pending exception.
- * Can we handle it here - or need to bail out to caller?
- *
- */
-MterpException:
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpHandleException)
- testb %al, %al
- jz MterpExceptionReturn
- movq OFF_FP_DEX_INSTRUCTIONS(rFP), %rax
- mov OFF_FP_DEX_PC(rFP), %ecx
- leaq (%rax, %rcx, 2), rPC
- movq rPC, OFF_FP_DEX_PC_PTR(rFP)
- /* Do we need to switch interpreters? */
- call SYMBOL(MterpShouldSwitchInterpreters)
- testb %al, %al
- jnz MterpFallback
- /* resume execution at catch block */
- REFRESH_IBASE
- FETCH_INST
- GOTO_NEXT
- /* NOTE: no fallthrough */
-
-/*
- * Common handling for branches with support for Jit profiling.
- * On entry:
- * rINST <= signed offset
- * rPROFILE <= signed hotness countdown (expanded to 32 bits)
- * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
- *
- * We have quite a few different cases for branch profiling, OSR detection and
- * suspend check support here.
- *
- * Taken backward branches:
- * If profiling active, do hotness countdown and report if we hit zero.
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- * Is there a pending suspend request? If so, suspend.
- *
- * Taken forward branches and not-taken backward branches:
- * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
- *
- * Our most common case is expected to be a taken backward branch with active jit profiling,
- * but no full OSR check and no pending suspend request.
- * Next most common case is not-taken branch with no full OSR check.
- *
- */
-MterpCommonTakenBranch:
- jg .L_forward_branch # don't add forward branches to hotness
-/*
- * We need to subtract 1 from positive values and we should not see 0 here,
- * so we may use the result of the comparison with -1.
- */
-#if JIT_CHECK_OSR != -1
-# error "JIT_CHECK_OSR must be -1."
-#endif
- cmpl $$JIT_CHECK_OSR, rPROFILE
- je .L_osr_check
- decl rPROFILE
- je .L_add_batch # counted down to zero - report
-.L_resume_backward_branch:
- movq rSELF, %rax
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%rax)
- REFRESH_IBASE_REG %rax
- leaq (rPC, rINSTq, 2), rPC
- FETCH_INST
- jnz .L_suspend_request_pending
- GOTO_NEXT
-
-.L_suspend_request_pending:
- EXPORT_PC
- movq rSELF, OUT_ARG0
- call SYMBOL(MterpSuspendCheck) # (self)
- testb %al, %al
- jnz MterpFallback
- REFRESH_IBASE # might have changed during suspend
- GOTO_NEXT
-
-.L_no_count_backwards:
- cmpl $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
- jne .L_resume_backward_branch
-.L_osr_check:
- EXPORT_PC
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movq rINSTq, OUT_ARG2
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- jz .L_resume_backward_branch
- jmp MterpOnStackReplacement
-
-.L_forward_branch:
- cmpl $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
- je .L_check_osr_forward
-.L_resume_forward_branch:
- leaq (rPC, rINSTq, 2), rPC
- FETCH_INST
- GOTO_NEXT
-
-.L_check_osr_forward:
- EXPORT_PC
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movq rINSTq, OUT_ARG2
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- jz .L_resume_forward_branch
- jmp MterpOnStackReplacement
-
-.L_add_batch:
- movl rPROFILE, %eax
- movq OFF_FP_METHOD(rFP), OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movw %ax, OFF_FP_COUNTDOWN_OFFSET(rFP)
- movq rSELF, OUT_ARG2
- call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- movswl %ax, rPROFILE
- jmp .L_no_count_backwards
-
-/*
- * Entered from the conditional branch handlers when OSR check request active on
- * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
- */
-.L_check_not_taken_osr:
- EXPORT_PC
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movl $$2, OUT_32_ARG2
- call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
- testb %al, %al
- jnz MterpOnStackReplacement
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
-
-/*
- * On-stack replacement has happened, and now we've returned from the compiled method.
- */
-MterpOnStackReplacement:
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movl rINST, OUT_32_ARG2
- call SYMBOL(MterpLogOSR)
-#endif
- movl $$1, %eax
- jmp MterpDone
-
-/*
- * Bail out to reference interpreter.
- */
-MterpFallback:
- EXPORT_PC
-#if MTERP_LOGGING
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- call SYMBOL(MterpLogFallback)
-#endif
-MterpCommonFallback:
- xorl %eax, %eax
- jmp MterpDone
-
-/*
- * On entry:
- * uint32_t* rFP (should still be live, pointer to base of vregs)
- */
-MterpExceptionReturn:
- movl $$1, %eax
- jmp MterpDone
-MterpReturn:
- movq OFF_FP_RESULT_REGISTER(rFP), %rdx
- movq %rax, (%rdx)
- movl $$1, %eax
-MterpDone:
-/*
- * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
- * checking for OSR. If greater than zero, we might have unreported hotness to register
- * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
- * should only reach zero immediately after a hotness decrement, and is then reset to either
- * a negative special state or the new non-zero countdown value.
- */
- testl rPROFILE, rPROFILE
- jle MRestoreFrame # if > 0, we may have some counts to report.
-
- movl %eax, rINST # stash return value
- /* Report cached hotness counts */
- movl rPROFILE, %eax
- movq OFF_FP_METHOD(rFP), OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movw %ax, OFF_FP_COUNTDOWN_OFFSET(rFP)
- movq rSELF, OUT_ARG2
- call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
- movl rINST, %eax # restore return value
-
- /* pop up frame */
-MRestoreFrame:
- addq $$FRAME_SIZE, %rsp
- .cfi_adjust_cfa_offset -FRAME_SIZE
-
- /* Restore callee save register */
- POP %r15
- POP %r14
- POP %r13
- POP %r12
- POP %rbp
- POP %rbx
- ret
- .cfi_endproc
- SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
diff --git a/runtime/interpreter/mterp/x86_64/fpcmp.S b/runtime/interpreter/mterp/x86_64/fpcmp.S
deleted file mode 100644
index 15161c8..0000000
--- a/runtime/interpreter/mterp/x86_64/fpcmp.S
+++ /dev/null
@@ -1,35 +0,0 @@
-%def fpcmp(suff="d", nanval="pos"):
-/*
- * Compare two floating-point values. Puts 0, 1, or -1 into the
- * destination register based on the results of the comparison.
- *
- * int compare(x, y) {
- * if (x == y) {
- * return 0;
- * } else if (x < y) {
- * return -1;
- * } else if (x > y) {
- * return 1;
- * } else {
- * return nanval ? 1 : -1;
- * }
- * }
- */
- /* op vAA, vBB, vCC */
- movzbq 3(rPC), %rcx # ecx<- CC
- movzbq 2(rPC), %rax # eax<- BB
- movs${suff} VREG_ADDRESS(%rax), %xmm0
- xor %eax, %eax
- ucomis${suff} VREG_ADDRESS(%rcx), %xmm0
- jp .L${opcode}_nan_is_${nanval}
- je .L${opcode}_finish
- jb .L${opcode}_less
-.L${opcode}_nan_is_pos:
- addb $$1, %al
- jmp .L${opcode}_finish
-.L${opcode}_nan_is_neg:
-.L${opcode}_less:
- movl $$-1, %eax
-.L${opcode}_finish:
- SET_VREG %eax, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/fpcvt.S b/runtime/interpreter/mterp/x86_64/fpcvt.S
deleted file mode 100644
index 6647ff3..0000000
--- a/runtime/interpreter/mterp/x86_64/fpcvt.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def fpcvt(source_suffix="", dest_suffix="", wide=""):
-/*
- * Generic 32-bit FP conversion operation.
- */
- /* unop vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- cvts${source_suffix}2s${dest_suffix} VREG_ADDRESS(rINSTq), %xmm0
- .if $wide
- movsd %xmm0, VREG_ADDRESS(%rcx)
- CLEAR_WIDE_REF %rcx
- .else
- movss %xmm0, VREG_ADDRESS(%rcx)
- CLEAR_REF %rcx
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/header.S b/runtime/interpreter/mterp/x86_64/header.S
deleted file mode 100644
index 44ece2e..0000000
--- a/runtime/interpreter/mterp/x86_64/header.S
+++ /dev/null
@@ -1,303 +0,0 @@
-%def header():
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- Art assembly interpreter notes:
-
- First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
- handle invoke, allows higher-level code to create frame & shadow frame.
-
- Once that's working, support direct entry code & eliminate shadow frame (and
- excess locals allocation.
-
- Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
- base of the vreg array within the shadow frame. Access the other fields,
- dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
- the shadow frame mechanism of double-storing object references - via rFP &
- number_of_vregs_.
-
- */
-
-/*
-x86_64 ABI general notes:
-
-Caller save set:
- rax, rdx, rcx, rsi, rdi, r8-r11, st(0)-st(7)
-Callee save set:
- rbx, rbp, r12-r15
-Return regs:
- 32-bit in eax
- 64-bit in rax
- fp on xmm0
-
-First 8 fp parameters came in xmm0-xmm7.
-First 6 non-fp parameters came in rdi, rsi, rdx, rcx, r8, r9.
-Other parameters passed on stack, pushed right-to-left. On entry to target, first
-param is at 8(%esp). Traditional entry code is:
-
-Stack must be 16-byte aligned to support SSE in native code.
-
-If we're not doing variable stack allocation (alloca), the frame pointer can be
-eliminated and all arg references adjusted to be esp relative.
-*/
-
-/*
-Mterp and x86_64 notes:
-
-Some key interpreter variables will be assigned to registers.
-
- nick reg purpose
- rPROFILE rbp countdown register for jit profiling
- rPC r12 interpreted program counter, used for fetching instructions
- rFP r13 interpreted frame pointer, used for accessing locals and args
- rINSTw bx first 16-bit code of current instruction
- rINSTbl bl opcode portion of instruction word
- rINSTbh bh high byte of inst word, usually contains src/tgt reg names
- rIBASE r14 base of instruction handler table
- rREFS r15 base of object references in shadow frame.
-
-Notes:
- o High order 16 bits of ebx must be zero on entry to handler
- o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
- o eax and ecx are scratch, rINSTw/ebx sometimes scratch
-
-Macros are provided for common operations. Each macro MUST emit only
-one instruction to make instruction-counting easier. They MUST NOT alter
-unspecified registers or condition codes.
-*/
-
-/*
- * This is a #include, not a %include, because we want the C pre-processor
- * to expand the macros into assembler assignment statements.
- */
-#include "asm_support.h"
-#include "interpreter/cfi_asm_support.h"
-
-/*
- * Handle mac compiler specific
- */
-#if defined(__APPLE__)
- #define MACRO_LITERAL(value) $$(value)
- #define FUNCTION_TYPE(name)
- #define OBJECT_TYPE(name)
- #define SIZE(start,end)
- // Mac OS' symbols have an _ prefix.
- #define SYMBOL(name) _ ## name
- #define ASM_HIDDEN .private_extern
-#else
- #define MACRO_LITERAL(value) $$value
- #define FUNCTION_TYPE(name) .type name, @function
- #define OBJECT_TYPE(name) .type name, @object
- #define SIZE(start,end) .size start, .-end
- #define SYMBOL(name) name
- #define ASM_HIDDEN .hidden
-#endif
-
-.macro PUSH _reg
- pushq \_reg
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset \_reg, 0
-.endm
-
-.macro POP _reg
- popq \_reg
- .cfi_adjust_cfa_offset -8
- .cfi_restore \_reg
-.endm
-
-/*
- * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
- * to access other shadow frame fields, we need to use a backwards offset. Define those here.
- */
-#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
-#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
-#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
-#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
-#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
-#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
-#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
-#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
-#define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET)
-#define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET)
-
-/* Frame size must be 16-byte aligned.
- * Remember about 8 bytes for return address + 6 * 8 for spills.
- */
-#define FRAME_SIZE 8
-
-/* Frame diagram while executing ExecuteMterpImpl, high to low addresses */
-#define IN_ARG3 %rcx
-#define IN_ARG2 %rdx
-#define IN_ARG1 %rsi
-#define IN_ARG0 %rdi
-/* Spill offsets relative to %esp */
-#define SELF_SPILL (FRAME_SIZE - 8)
-/* Out Args */
-#define OUT_ARG3 %rcx
-#define OUT_ARG2 %rdx
-#define OUT_ARG1 %rsi
-#define OUT_ARG0 %rdi
-#define OUT_32_ARG3 %ecx
-#define OUT_32_ARG2 %edx
-#define OUT_32_ARG1 %esi
-#define OUT_32_ARG0 %edi
-#define OUT_FP_ARG1 %xmm1
-#define OUT_FP_ARG0 %xmm0
-
-/* During bringup, we'll use the shadow frame model instead of rFP */
-/* single-purpose registers, given names for clarity */
-#define rSELF SELF_SPILL(%rsp)
-#define rPC %r12
-#define CFI_DEX 12 // DWARF register number of the register holding dex-pc (rPC).
-#define CFI_TMP 5 // DWARF register number of the first argument register (rdi).
-#define rFP %r13
-#define rINST %ebx
-#define rINSTq %rbx
-#define rINSTw %bx
-#define rINSTbh %bh
-#define rINSTbl %bl
-#define rIBASE %r14
-#define rREFS %r15
-#define rPROFILE %ebp
-
-#define MTERP_LOGGING 0
-
-/*
- * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
- * be done *before* something throws.
- *
- * It's okay to do this more than once.
- *
- * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
- * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
- * offset into the code_items_[] array. For effiency, we will "export" the
- * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
- * to convert to a dex pc when needed.
- */
-.macro EXPORT_PC
- movq rPC, OFF_FP_DEX_PC_PTR(rFP)
-.endm
-
-/*
- * Refresh handler table.
- * IBase handles uses the caller save register so we must restore it after each call.
- * Also it is used as a result of some 64-bit operations (like imul) and we should
- * restore it in such cases also.
- *
- */
-.macro REFRESH_IBASE_REG self_reg
- movq THREAD_CURRENT_IBASE_OFFSET(\self_reg), rIBASE
-.endm
-.macro REFRESH_IBASE
- movq rSELF, rIBASE
- REFRESH_IBASE_REG rIBASE
-.endm
-
-/*
- * Refresh rINST.
- * At enter to handler rINST does not contain the opcode number.
- * However some utilities require the full value, so this macro
- * restores the opcode number.
- */
-.macro REFRESH_INST _opnum
- movb rINSTbl, rINSTbh
- movb $$\_opnum, rINSTbl
-.endm
-
-/*
- * Fetch the next instruction from rPC into rINSTw. Does not advance rPC.
- */
-.macro FETCH_INST
- movzwq (rPC), rINSTq
-.endm
-
-/*
- * Remove opcode from rINST, compute the address of handler and jump to it.
- */
-.macro GOTO_NEXT
- movzx rINSTbl,%eax
- movzbl rINSTbh,rINST
- shll MACRO_LITERAL(${handler_size_bits}), %eax
- addq rIBASE, %rax
- jmp *%rax
-.endm
-
-/*
- * Advance rPC by instruction count.
- */
-.macro ADVANCE_PC _count
- leaq 2*\_count(rPC), rPC
-.endm
-
-/*
- * Advance rPC by instruction count, fetch instruction and jump to handler.
- */
-.macro ADVANCE_PC_FETCH_AND_GOTO_NEXT _count
- ADVANCE_PC \_count
- FETCH_INST
- GOTO_NEXT
-.endm
-
-/*
- * Get/set the 32-bit value from a Dalvik register.
- */
-#define VREG_ADDRESS(_vreg) (rFP,_vreg,4)
-#define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4)
-
-.macro GET_VREG _reg _vreg
- movl (rFP,\_vreg,4), \_reg
-.endm
-
-/* Read wide value. */
-.macro GET_WIDE_VREG _reg _vreg
- movq (rFP,\_vreg,4), \_reg
-.endm
-
-.macro SET_VREG _reg _vreg
- movl \_reg, (rFP,\_vreg,4)
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
-.endm
-
-/* Write wide value. reg is clobbered. */
-.macro SET_WIDE_VREG _reg _vreg
- movq \_reg, (rFP,\_vreg,4)
- xorq \_reg, \_reg
- movq \_reg, (rREFS,\_vreg,4)
-.endm
-
-.macro SET_VREG_OBJECT _reg _vreg
- movl \_reg, (rFP,\_vreg,4)
- movl \_reg, (rREFS,\_vreg,4)
-.endm
-
-.macro GET_VREG_HIGH _reg _vreg
- movl 4(rFP,\_vreg,4), \_reg
-.endm
-
-.macro SET_VREG_HIGH _reg _vreg
- movl \_reg, 4(rFP,\_vreg,4)
- movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
-.endm
-
-.macro CLEAR_REF _vreg
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
-.endm
-
-.macro CLEAR_WIDE_REF _vreg
- movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
- movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
-.endm
diff --git a/runtime/interpreter/mterp/x86_64/instruction_end.S b/runtime/interpreter/mterp/x86_64/instruction_end.S
deleted file mode 100644
index 5a24b66..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_end.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end():
-
- OBJECT_TYPE(artMterpAsmInstructionEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmInstructionEnd)
- .global SYMBOL(artMterpAsmInstructionEnd)
-SYMBOL(artMterpAsmInstructionEnd):
diff --git a/runtime/interpreter/mterp/x86_64/instruction_end_alt.S b/runtime/interpreter/mterp/x86_64/instruction_end_alt.S
deleted file mode 100644
index d037db9..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_end_alt.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_alt():
-
- OBJECT_TYPE(artMterpAsmAltInstructionEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
- .global SYMBOL(artMterpAsmAltInstructionEnd)
-SYMBOL(artMterpAsmAltInstructionEnd):
diff --git a/runtime/interpreter/mterp/x86_64/instruction_end_sister.S b/runtime/interpreter/mterp/x86_64/instruction_end_sister.S
deleted file mode 100644
index 7b1ec89..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_end_sister.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def instruction_end_sister():
-
- OBJECT_TYPE(artMterpAsmSisterEnd)
- ASM_HIDDEN SYMBOL(artMterpAsmSisterEnd)
- .global SYMBOL(artMterpAsmSisterEnd)
-SYMBOL(artMterpAsmSisterEnd):
diff --git a/runtime/interpreter/mterp/x86_64/instruction_start.S b/runtime/interpreter/mterp/x86_64/instruction_start.S
deleted file mode 100644
index dee581b..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_start.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start():
-
- OBJECT_TYPE(artMterpAsmInstructionStart)
- ASM_HIDDEN SYMBOL(artMterpAsmInstructionStart)
- .global SYMBOL(artMterpAsmInstructionStart)
-SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
- .text
diff --git a/runtime/interpreter/mterp/x86_64/instruction_start_alt.S b/runtime/interpreter/mterp/x86_64/instruction_start_alt.S
deleted file mode 100644
index 66650e7..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_start_alt.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def instruction_start_alt():
-
- OBJECT_TYPE(artMterpAsmAltInstructionStart)
- ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart)
- .global SYMBOL(artMterpAsmAltInstructionStart)
- .text
-SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
diff --git a/runtime/interpreter/mterp/x86_64/instruction_start_sister.S b/runtime/interpreter/mterp/x86_64/instruction_start_sister.S
deleted file mode 100644
index 8c156ad..0000000
--- a/runtime/interpreter/mterp/x86_64/instruction_start_sister.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def instruction_start_sister():
-
- OBJECT_TYPE(artMterpAsmSisterStart)
- ASM_HIDDEN SYMBOL(artMterpAsmSisterStart)
- .global SYMBOL(artMterpAsmSisterStart)
- .text
- .balign 4
-SYMBOL(artMterpAsmSisterStart):
diff --git a/runtime/interpreter/mterp/x86_64/invoke.S b/runtime/interpreter/mterp/x86_64/invoke.S
index 42b50f2..63c233c 100644
--- a/runtime/interpreter/mterp/x86_64/invoke.S
+++ b/runtime/interpreter/mterp/x86_64/invoke.S
@@ -20,3 +20,96 @@
jnz MterpFallback
FETCH_INST
GOTO_NEXT
+
+%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
+ /*
+ * invoke-polymorphic handler wrapper.
+ */
+ /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
+ .extern $helper
+ EXPORT_PC
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movq rPC, OUT_ARG2
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_32_ARG3
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpException
+ ADVANCE_PC 4
+ call SYMBOL(MterpShouldSwitchInterpreters)
+ testb %al, %al
+ jnz MterpFallback
+ FETCH_INST
+ GOTO_NEXT
+
+%def op_invoke_custom():
+% invoke(helper="MterpInvokeCustom")
+
+%def op_invoke_custom_range():
+% invoke(helper="MterpInvokeCustomRange")
+
+%def op_invoke_direct():
+% invoke(helper="MterpInvokeDirect")
+
+%def op_invoke_direct_range():
+% invoke(helper="MterpInvokeDirectRange")
+
+%def op_invoke_interface():
+% invoke(helper="MterpInvokeInterface")
+/*
+ * Handle an interface method call.
+ *
+ * for: invoke-interface, invoke-interface/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_interface_range():
+% invoke(helper="MterpInvokeInterfaceRange")
+
+%def op_invoke_polymorphic():
+% invoke_polymorphic(helper="MterpInvokePolymorphic")
+
+%def op_invoke_polymorphic_range():
+% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
+
+%def op_invoke_static():
+% invoke(helper="MterpInvokeStatic")
+
+
+%def op_invoke_static_range():
+% invoke(helper="MterpInvokeStaticRange")
+
+%def op_invoke_super():
+% invoke(helper="MterpInvokeSuper")
+/*
+ * Handle a "super" method call.
+ *
+ * for: invoke-super, invoke-super/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_super_range():
+% invoke(helper="MterpInvokeSuperRange")
+
+%def op_invoke_virtual():
+% invoke(helper="MterpInvokeVirtual")
+/*
+ * Handle a virtual method call.
+ *
+ * for: invoke-virtual, invoke-virtual/range
+ */
+ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
+ /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
+
+%def op_invoke_virtual_quick():
+% invoke(helper="MterpInvokeVirtualQuick")
+
+%def op_invoke_virtual_range():
+% invoke(helper="MterpInvokeVirtualRange")
+
+%def op_invoke_virtual_range_quick():
+% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/x86_64/invoke_polymorphic.S b/runtime/interpreter/mterp/x86_64/invoke_polymorphic.S
deleted file mode 100644
index 18fd5e6..0000000
--- a/runtime/interpreter/mterp/x86_64/invoke_polymorphic.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def invoke_polymorphic(helper="UndefinedInvokeHandler"):
- /*
- * invoke-polymorphic handler wrapper.
- */
- /* op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB, proto@HHHH */
- .extern $helper
- EXPORT_PC
- movq rSELF, OUT_ARG0
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
- movq rPC, OUT_ARG2
- REFRESH_INST ${opnum}
- movl rINST, OUT_32_ARG3
- call SYMBOL($helper)
- testb %al, %al
- jz MterpException
- ADVANCE_PC 4
- call SYMBOL(MterpShouldSwitchInterpreters)
- testb %al, %al
- jnz MterpFallback
- FETCH_INST
- GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/main.S b/runtime/interpreter/mterp/x86_64/main.S
new file mode 100644
index 0000000..aa47c6d
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/main.S
@@ -0,0 +1,753 @@
+%def header():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ Art assembly interpreter notes:
+
+ First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't
+ handle invoke, allows higher-level code to create frame & shadow frame.
+
+ Once that's working, support direct entry code & eliminate shadow frame (and
+ excess locals allocation.
+
+ Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the
+ base of the vreg array within the shadow frame. Access the other fields,
+ dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue
+ the shadow frame mechanism of double-storing object references - via rFP &
+ number_of_vregs_.
+
+ */
+
+/*
+x86_64 ABI general notes:
+
+Caller save set:
+ rax, rdx, rcx, rsi, rdi, r8-r11, st(0)-st(7)
+Callee save set:
+ rbx, rbp, r12-r15
+Return regs:
+ 32-bit in eax
+ 64-bit in rax
+ fp on xmm0
+
+First 8 fp parameters came in xmm0-xmm7.
+First 6 non-fp parameters came in rdi, rsi, rdx, rcx, r8, r9.
+Other parameters passed on stack, pushed right-to-left. On entry to target, first
+param is at 8(%esp). Traditional entry code is:
+
+Stack must be 16-byte aligned to support SSE in native code.
+
+If we're not doing variable stack allocation (alloca), the frame pointer can be
+eliminated and all arg references adjusted to be esp relative.
+*/
+
+/*
+Mterp and x86_64 notes:
+
+Some key interpreter variables will be assigned to registers.
+
+ nick reg purpose
+ rPROFILE rbp countdown register for jit profiling
+ rPC r12 interpreted program counter, used for fetching instructions
+ rFP r13 interpreted frame pointer, used for accessing locals and args
+ rINSTw bx first 16-bit code of current instruction
+ rINSTbl bl opcode portion of instruction word
+ rINSTbh bh high byte of inst word, usually contains src/tgt reg names
+ rIBASE r14 base of instruction handler table
+ rREFS r15 base of object references in shadow frame.
+
+Notes:
+ o High order 16 bits of ebx must be zero on entry to handler
+ o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
+ o eax and ecx are scratch, rINSTw/ebx sometimes scratch
+
+Macros are provided for common operations. Each macro MUST emit only
+one instruction to make instruction-counting easier. They MUST NOT alter
+unspecified registers or condition codes.
+*/
+
+/*
+ * This is a #include, not a %include, because we want the C pre-processor
+ * to expand the macros into assembler assignment statements.
+ */
+#include "asm_support.h"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * Handle mac compiler specific
+ */
+#if defined(__APPLE__)
+ #define MACRO_LITERAL(value) $$(value)
+ #define FUNCTION_TYPE(name)
+ #define OBJECT_TYPE(name)
+ #define SIZE(start,end)
+ // Mac OS' symbols have an _ prefix.
+ #define SYMBOL(name) _ ## name
+ #define ASM_HIDDEN .private_extern
+#else
+ #define MACRO_LITERAL(value) $$value
+ #define FUNCTION_TYPE(name) .type name, @function
+ #define OBJECT_TYPE(name) .type name, @object
+ #define SIZE(start,end) .size start, .-end
+ #define SYMBOL(name) name
+ #define ASM_HIDDEN .hidden
+#endif
+
+.macro PUSH _reg
+ pushq \_reg
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset \_reg, 0
+.endm
+
+.macro POP _reg
+ popq \_reg
+ .cfi_adjust_cfa_offset -8
+ .cfi_restore \_reg
+.endm
+
+/*
+ * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So,
+ * to access other shadow frame fields, we need to use a backwards offset. Define those here.
+ */
+#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
+#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
+#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
+#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
+#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
+#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
+#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
+#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
+#define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET)
+#define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET)
+
+/* Frame size must be 16-byte aligned.
+ * Remember about 8 bytes for return address + 6 * 8 for spills.
+ */
+#define FRAME_SIZE 8
+
+/* Frame diagram while executing ExecuteMterpImpl, high to low addresses */
+#define IN_ARG3 %rcx
+#define IN_ARG2 %rdx
+#define IN_ARG1 %rsi
+#define IN_ARG0 %rdi
+/* Spill offsets relative to %esp */
+#define SELF_SPILL (FRAME_SIZE - 8)
+/* Out Args */
+#define OUT_ARG3 %rcx
+#define OUT_ARG2 %rdx
+#define OUT_ARG1 %rsi
+#define OUT_ARG0 %rdi
+#define OUT_32_ARG3 %ecx
+#define OUT_32_ARG2 %edx
+#define OUT_32_ARG1 %esi
+#define OUT_32_ARG0 %edi
+#define OUT_FP_ARG1 %xmm1
+#define OUT_FP_ARG0 %xmm0
+
+/* During bringup, we'll use the shadow frame model instead of rFP */
+/* single-purpose registers, given names for clarity */
+#define rSELF SELF_SPILL(%rsp)
+#define rPC %r12
+#define CFI_DEX 12 // DWARF register number of the register holding dex-pc (rPC).
+#define CFI_TMP 5 // DWARF register number of the first argument register (rdi).
+#define rFP %r13
+#define rINST %ebx
+#define rINSTq %rbx
+#define rINSTw %bx
+#define rINSTbh %bh
+#define rINSTbl %bl
+#define rIBASE %r14
+#define rREFS %r15
+#define rPROFILE %ebp
+
+#define MTERP_LOGGING 0
+
+/*
+ * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must
+ * be done *before* something throws.
+ *
+ * It's okay to do this more than once.
+ *
+ * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
+ * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction
+ * offset into the code_items_[] array. For effiency, we will "export" the
+ * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
+ * to convert to a dex pc when needed.
+ */
+.macro EXPORT_PC
+ movq rPC, OFF_FP_DEX_PC_PTR(rFP)
+.endm
+
+/*
+ * Refresh handler table.
+ * IBase handles uses the caller save register so we must restore it after each call.
+ * Also it is used as a result of some 64-bit operations (like imul) and we should
+ * restore it in such cases also.
+ *
+ */
+.macro REFRESH_IBASE_REG self_reg
+ movq THREAD_CURRENT_IBASE_OFFSET(\self_reg), rIBASE
+.endm
+.macro REFRESH_IBASE
+ movq rSELF, rIBASE
+ REFRESH_IBASE_REG rIBASE
+.endm
+
+/*
+ * Refresh rINST.
+ * At enter to handler rINST does not contain the opcode number.
+ * However some utilities require the full value, so this macro
+ * restores the opcode number.
+ */
+.macro REFRESH_INST _opnum
+ movb rINSTbl, rINSTbh
+ movb $$\_opnum, rINSTbl
+.endm
+
+/*
+ * Fetch the next instruction from rPC into rINSTw. Does not advance rPC.
+ */
+.macro FETCH_INST
+ movzwq (rPC), rINSTq
+.endm
+
+/*
+ * Remove opcode from rINST, compute the address of handler and jump to it.
+ */
+.macro GOTO_NEXT
+ movzx rINSTbl,%eax
+ movzbl rINSTbh,rINST
+ shll MACRO_LITERAL(${handler_size_bits}), %eax
+ addq rIBASE, %rax
+ jmp *%rax
+.endm
+
+/*
+ * Advance rPC by instruction count.
+ */
+.macro ADVANCE_PC _count
+ leaq 2*\_count(rPC), rPC
+.endm
+
+/*
+ * Advance rPC by instruction count, fetch instruction and jump to handler.
+ */
+.macro ADVANCE_PC_FETCH_AND_GOTO_NEXT _count
+ ADVANCE_PC \_count
+ FETCH_INST
+ GOTO_NEXT
+.endm
+
+/*
+ * Get/set the 32-bit value from a Dalvik register.
+ */
+#define VREG_ADDRESS(_vreg) (rFP,_vreg,4)
+#define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4)
+
+.macro GET_VREG _reg _vreg
+ movl (rFP,\_vreg,4), \_reg
+.endm
+
+/* Read wide value. */
+.macro GET_WIDE_VREG _reg _vreg
+ movq (rFP,\_vreg,4), \_reg
+.endm
+
+.macro SET_VREG _reg _vreg
+ movl \_reg, (rFP,\_vreg,4)
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+.endm
+
+/* Write wide value. reg is clobbered. */
+.macro SET_WIDE_VREG _reg _vreg
+ movq \_reg, (rFP,\_vreg,4)
+ xorq \_reg, \_reg
+ movq \_reg, (rREFS,\_vreg,4)
+.endm
+
+.macro SET_VREG_OBJECT _reg _vreg
+ movl \_reg, (rFP,\_vreg,4)
+ movl \_reg, (rREFS,\_vreg,4)
+.endm
+
+.macro GET_VREG_HIGH _reg _vreg
+ movl 4(rFP,\_vreg,4), \_reg
+.endm
+
+.macro SET_VREG_HIGH _reg _vreg
+ movl \_reg, 4(rFP,\_vreg,4)
+ movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
+.endm
+
+.macro CLEAR_REF _vreg
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+.endm
+
+.macro CLEAR_WIDE_REF _vreg
+ movl MACRO_LITERAL(0), (rREFS,\_vreg,4)
+ movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4)
+.endm
+
+%def entry():
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Interpreter entry point.
+ */
+
+ .text
+ ASM_HIDDEN SYMBOL(ExecuteMterpImpl)
+ .global SYMBOL(ExecuteMterpImpl)
+ FUNCTION_TYPE(ExecuteMterpImpl)
+
+/*
+ * On entry:
+ * 0 Thread* self
+ * 1 insns_
+ * 2 ShadowFrame
+ * 3 JValue* result_register
+ *
+ */
+
+SYMBOL(ExecuteMterpImpl):
+ .cfi_startproc
+ .cfi_def_cfa rsp, 8
+
+ /* Spill callee save regs */
+ PUSH %rbx
+ PUSH %rbp
+ PUSH %r12
+ PUSH %r13
+ PUSH %r14
+ PUSH %r15
+
+ /* Allocate frame */
+ subq $$FRAME_SIZE, %rsp
+ .cfi_adjust_cfa_offset FRAME_SIZE
+
+ /* Remember the return register */
+ movq IN_ARG3, SHADOWFRAME_RESULT_REGISTER_OFFSET(IN_ARG2)
+
+ /* Remember the code_item */
+ movq IN_ARG1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(IN_ARG2)
+
+ /* set up "named" registers */
+ movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(IN_ARG2), %eax
+ leaq SHADOWFRAME_VREGS_OFFSET(IN_ARG2), rFP
+ leaq (rFP, %rax, 4), rREFS
+ movl SHADOWFRAME_DEX_PC_OFFSET(IN_ARG2), %eax
+ leaq (IN_ARG1, %rax, 2), rPC
+ CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
+ EXPORT_PC
+
+ /* Starting ibase */
+ movq IN_ARG0, rSELF
+ REFRESH_IBASE_REG IN_ARG0
+
+ /* Set up for backwards branches & osr profiling */
+ movq IN_ARG0, OUT_ARG2 /* Set up OUT_ARG2 before clobbering IN_ARG0 */
+ movq OFF_FP_METHOD(rFP), OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpSetUpHotnessCountdown)
+ movswl %ax, rPROFILE
+
+ /* start executing the instruction at rPC */
+ FETCH_INST
+ GOTO_NEXT
+ /* NOTE: no fallthrough */
+
+%def alt_stub():
+/*
+ * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle
+ * any interesting requests and then jump to the real instruction
+ * handler. Unlike the Arm handler, we can't do this as a tail call
+ * because rIBASE is caller save and we need to reload it.
+ *
+ * Note that unlike in the Arm implementation, we should never arrive
+ * here with a zero breakFlag because we always refresh rIBASE on
+ * return.
+ */
+ .extern MterpCheckBefore
+ REFRESH_IBASE
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movq rPC, OUT_ARG2
+ call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr)
+ jmp .L_op_nop+(${opnum}*${handler_size_bytes})
+
+%def fallback():
+/* Transfer stub to alternate interpreter */
+ jmp MterpFallback
+
+
+%def footer():
+/*
+ * ===========================================================================
+ * Common subroutines and data
+ * ===========================================================================
+ */
+
+ .text
+ .align 2
+
+/*
+ * We've detected a condition that will result in an exception, but the exception
+ * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
+ * TUNING: for consistency, we may want to just go ahead and handle these here.
+ */
+common_errDivideByZero:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogDivideByZeroException)
+#endif
+ jmp MterpCommonFallback
+
+common_errArrayIndex:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogArrayIndexException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNegativeArraySize:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogNegativeArraySizeException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNoSuchMethod:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogNoSuchMethodException)
+#endif
+ jmp MterpCommonFallback
+
+common_errNullObject:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogNullObjectException)
+#endif
+ jmp MterpCommonFallback
+
+common_exceptionThrown:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogExceptionThrownException)
+#endif
+ jmp MterpCommonFallback
+
+MterpSuspendFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movl THREAD_FLAGS_OFFSET(OUT_ARG0), OUT_32_ARG2
+ call SYMBOL(MterpLogSuspendFallback)
+#endif
+ jmp MterpCommonFallback
+
+/*
+ * If we're here, something is out of the ordinary. If there is a pending
+ * exception, handle it. Otherwise, roll back and retry with the reference
+ * interpreter.
+ */
+MterpPossibleException:
+ movq rSELF, %rcx
+ cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
+ jz MterpFallback
+ /* intentional fallthrough - handle pending exception. */
+
+/*
+ * On return from a runtime helper routine, we've found a pending exception.
+ * Can we handle it here - or need to bail out to caller?
+ *
+ */
+MterpException:
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpHandleException)
+ testb %al, %al
+ jz MterpExceptionReturn
+ movq OFF_FP_DEX_INSTRUCTIONS(rFP), %rax
+ mov OFF_FP_DEX_PC(rFP), %ecx
+ leaq (%rax, %rcx, 2), rPC
+ movq rPC, OFF_FP_DEX_PC_PTR(rFP)
+ /* Do we need to switch interpreters? */
+ call SYMBOL(MterpShouldSwitchInterpreters)
+ testb %al, %al
+ jnz MterpFallback
+ /* resume execution at catch block */
+ REFRESH_IBASE
+ FETCH_INST
+ GOTO_NEXT
+ /* NOTE: no fallthrough */
+
+/*
+ * Common handling for branches with support for Jit profiling.
+ * On entry:
+ * rINST <= signed offset
+ * rPROFILE <= signed hotness countdown (expanded to 32 bits)
+ * condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
+ *
+ * We have quite a few different cases for branch profiling, OSR detection and
+ * suspend check support here.
+ *
+ * Taken backward branches:
+ * If profiling active, do hotness countdown and report if we hit zero.
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ * Is there a pending suspend request? If so, suspend.
+ *
+ * Taken forward branches and not-taken backward branches:
+ * If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
+ *
+ * Our most common case is expected to be a taken backward branch with active jit profiling,
+ * but no full OSR check and no pending suspend request.
+ * Next most common case is not-taken branch with no full OSR check.
+ *
+ */
+MterpCommonTakenBranch:
+ jg .L_forward_branch # don't add forward branches to hotness
+/*
+ * We need to subtract 1 from positive values and we should not see 0 here,
+ * so we may use the result of the comparison with -1.
+ */
+#if JIT_CHECK_OSR != -1
+# error "JIT_CHECK_OSR must be -1."
+#endif
+ cmpl $$JIT_CHECK_OSR, rPROFILE
+ je .L_osr_check
+ decl rPROFILE
+ je .L_add_batch # counted down to zero - report
+.L_resume_backward_branch:
+ movq rSELF, %rax
+ testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%rax)
+ REFRESH_IBASE_REG %rax
+ leaq (rPC, rINSTq, 2), rPC
+ FETCH_INST
+ jnz .L_suspend_request_pending
+ GOTO_NEXT
+
+.L_suspend_request_pending:
+ EXPORT_PC
+ movq rSELF, OUT_ARG0
+ call SYMBOL(MterpSuspendCheck) # (self)
+ testb %al, %al
+ jnz MterpFallback
+ REFRESH_IBASE # might have changed during suspend
+ GOTO_NEXT
+
+.L_no_count_backwards:
+ cmpl $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
+ jne .L_resume_backward_branch
+.L_osr_check:
+ EXPORT_PC
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movq rINSTq, OUT_ARG2
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ jz .L_resume_backward_branch
+ jmp MterpOnStackReplacement
+
+.L_forward_branch:
+ cmpl $$JIT_CHECK_OSR, rPROFILE # possible OSR re-entry?
+ je .L_check_osr_forward
+.L_resume_forward_branch:
+ leaq (rPC, rINSTq, 2), rPC
+ FETCH_INST
+ GOTO_NEXT
+
+.L_check_osr_forward:
+ EXPORT_PC
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movq rINSTq, OUT_ARG2
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ jz .L_resume_forward_branch
+ jmp MterpOnStackReplacement
+
+.L_add_batch:
+ movl rPROFILE, %eax
+ movq OFF_FP_METHOD(rFP), OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movw %ax, OFF_FP_COUNTDOWN_OFFSET(rFP)
+ movq rSELF, OUT_ARG2
+ call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ movswl %ax, rPROFILE
+ jmp .L_no_count_backwards
+
+/*
+ * Entered from the conditional branch handlers when OSR check request active on
+ * not-taken path. All Dalvik not-taken conditional branch offsets are 2.
+ */
+.L_check_not_taken_osr:
+ EXPORT_PC
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movl $$2, OUT_32_ARG2
+ call SYMBOL(MterpMaybeDoOnStackReplacement) # (self, shadow_frame, offset)
+ testb %al, %al
+ jnz MterpOnStackReplacement
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+/*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movl rINST, OUT_32_ARG2
+ call SYMBOL(MterpLogOSR)
+#endif
+ movl $$1, %eax
+ jmp MterpDone
+
+/*
+ * Bail out to reference interpreter.
+ */
+MterpFallback:
+ EXPORT_PC
+#if MTERP_LOGGING
+ movq rSELF, OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ call SYMBOL(MterpLogFallback)
+#endif
+MterpCommonFallback:
+ xorl %eax, %eax
+ jmp MterpDone
+
+/*
+ * On entry:
+ * uint32_t* rFP (should still be live, pointer to base of vregs)
+ */
+MterpExceptionReturn:
+ movl $$1, %eax
+ jmp MterpDone
+MterpReturn:
+ movq OFF_FP_RESULT_REGISTER(rFP), %rdx
+ movq %rax, (%rdx)
+ movl $$1, %eax
+MterpDone:
+/*
+ * At this point, we expect rPROFILE to be non-zero. If negative, hotness is disabled or we're
+ * checking for OSR. If greater than zero, we might have unreported hotness to register
+ * (the difference between the ending rPROFILE and the cached hotness counter). rPROFILE
+ * should only reach zero immediately after a hotness decrement, and is then reset to either
+ * a negative special state or the new non-zero countdown value.
+ */
+ testl rPROFILE, rPROFILE
+ jle MRestoreFrame # if > 0, we may have some counts to report.
+
+ movl %eax, rINST # stash return value
+ /* Report cached hotness counts */
+ movl rPROFILE, %eax
+ movq OFF_FP_METHOD(rFP), OUT_ARG0
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+ movw %ax, OFF_FP_COUNTDOWN_OFFSET(rFP)
+ movq rSELF, OUT_ARG2
+ call SYMBOL(MterpAddHotnessBatch) # (method, shadow_frame, self)
+ movl rINST, %eax # restore return value
+
+ /* pop up frame */
+MRestoreFrame:
+ addq $$FRAME_SIZE, %rsp
+ .cfi_adjust_cfa_offset -FRAME_SIZE
+
+ /* Restore callee save register */
+ POP %r15
+ POP %r14
+ POP %r13
+ POP %r12
+ POP %rbp
+ POP %rbx
+ ret
+ .cfi_endproc
+ SIZE(ExecuteMterpImpl,ExecuteMterpImpl)
+
+%def instruction_end():
+
+ OBJECT_TYPE(artMterpAsmInstructionEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmInstructionEnd)
+ .global SYMBOL(artMterpAsmInstructionEnd)
+SYMBOL(artMterpAsmInstructionEnd):
+
+%def instruction_end_alt():
+
+ OBJECT_TYPE(artMterpAsmAltInstructionEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd)
+ .global SYMBOL(artMterpAsmAltInstructionEnd)
+SYMBOL(artMterpAsmAltInstructionEnd):
+
+%def instruction_end_sister():
+
+ OBJECT_TYPE(artMterpAsmSisterEnd)
+ ASM_HIDDEN SYMBOL(artMterpAsmSisterEnd)
+ .global SYMBOL(artMterpAsmSisterEnd)
+SYMBOL(artMterpAsmSisterEnd):
+
+%def instruction_start():
+
+ OBJECT_TYPE(artMterpAsmInstructionStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmInstructionStart)
+ .global SYMBOL(artMterpAsmInstructionStart)
+SYMBOL(artMterpAsmInstructionStart) = .L_op_nop
+ .text
+
+%def instruction_start_alt():
+
+ OBJECT_TYPE(artMterpAsmAltInstructionStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart)
+ .global SYMBOL(artMterpAsmAltInstructionStart)
+ .text
+SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop
+
+%def instruction_start_sister():
+
+ OBJECT_TYPE(artMterpAsmSisterStart)
+ ASM_HIDDEN SYMBOL(artMterpAsmSisterStart)
+ .global SYMBOL(artMterpAsmSisterStart)
+ .text
+ .balign 4
+SYMBOL(artMterpAsmSisterStart):
diff --git a/runtime/interpreter/mterp/x86_64/object.S b/runtime/interpreter/mterp/x86_64/object.S
new file mode 100644
index 0000000..fa85f69
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/object.S
@@ -0,0 +1,254 @@
+%def field(helper=""):
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_check_cast():
+/*
+ * Check to see if a cast from one class to another is allowed.
+ */
+ /* check-cast vAA, class@BBBB */
+ EXPORT_PC
+ movzwq 2(rPC), OUT_ARG0 # OUT_ARG0 <- BBBB
+ leaq VREG_ADDRESS(rINSTq), OUT_ARG1
+ movq OFF_FP_METHOD(rFP), OUT_ARG2
+ movq rSELF, OUT_ARG3
+ call SYMBOL(MterpCheckCast) # (index, &obj, method, self)
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget(is_object="0", helper="MterpIGetU32"):
+% field(helper=helper)
+
+%def op_iget_boolean():
+% op_iget(helper="MterpIGetU8")
+
+%def op_iget_boolean_quick():
+% op_iget_quick(load="movsbl")
+
+%def op_iget_byte():
+% op_iget(helper="MterpIGetI8")
+
+%def op_iget_byte_quick():
+% op_iget_quick(load="movsbl")
+
+%def op_iget_char():
+% op_iget(helper="MterpIGetU16")
+
+%def op_iget_char_quick():
+% op_iget_quick(load="movzwl")
+
+%def op_iget_object():
+% op_iget(is_object="1", helper="MterpIGetObj")
+
+%def op_iget_object_quick():
+ /* For: iget-object-quick */
+ /* op vA, vB, offset@CCCC */
+ .extern artIGetObjectFromMterp
+ movzbq rINSTbl, %rcx # rcx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG OUT_32_ARG0, %rcx # vB (object we're operating on)
+ movzwl 2(rPC), OUT_32_ARG1 # eax <- field byte offset
+ EXPORT_PC
+ callq SYMBOL(artIGetObjectFromMterp) # (obj, offset)
+ movq rSELF, %rcx
+ cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
+ jnz MterpException # bail out
+ andb $$0xf, rINSTbl # rINST <- A
+ SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget_quick(load="movl", wide="0"):
+ /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick, iget-wide-quick */
+ /* op vA, vB, offset@CCCC */
+ movl rINST, %ecx # rcx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %rcx # vB (object we're operating on)
+ movzwq 2(rPC), %rax # eax <- field byte offset
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ andb $$0xf,rINSTbl # rINST <- A
+ .if $wide
+ movq (%rcx,%rax,1), %rax
+ SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
+ .else
+ ${load} (%rcx,%rax,1), %eax
+ SET_VREG %eax, rINSTq # fp[A] <- value
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iget_short():
+% op_iget(helper="MterpIGetI16")
+
+%def op_iget_short_quick():
+% op_iget_quick(load="movswl")
+
+%def op_iget_wide():
+% op_iget(helper="MterpIGetU64")
+
+%def op_iget_wide_quick():
+% op_iget_quick(load="movswl", wide="1")
+
+%def op_instance_of():
+/*
+ * Check to see if an object reference is an instance of a class.
+ *
+ * Most common situation is a non-null object, being compared against
+ * an already-resolved class.
+ */
+ /* instance-of vA, vB, class@CCCC */
+ EXPORT_PC
+ movzwl 2(rPC), OUT_32_ARG0 # OUT_32_ARG0 <- CCCC
+ movl rINST, %eax # eax <- BA
+ sarl $$4, %eax # eax <- B
+ leaq VREG_ADDRESS(%rax), OUT_ARG1 # Get object address
+ movq OFF_FP_METHOD(rFP), OUT_ARG2
+ movq rSELF, OUT_ARG3
+ call SYMBOL(MterpInstanceOf) # (index, &obj, method, self)
+ movsbl %al, %eax
+ movq rSELF, %rcx
+ cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
+ jnz MterpException
+ andb $$0xf, rINSTbl # rINSTbl <- A
+ SET_VREG %eax, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput(is_object="0", helper="MterpIPutU32"):
+% field(helper=helper)
+
+%def op_iput_boolean():
+% op_iput(helper="MterpIPutU8")
+
+%def op_iput_boolean_quick():
+% op_iput_quick(reg="rINSTbl", store="movb")
+
+%def op_iput_byte():
+% op_iput(helper="MterpIPutI8")
+
+%def op_iput_byte_quick():
+% op_iput_quick(reg="rINSTbl", store="movb")
+
+%def op_iput_char():
+% op_iput(helper="MterpIPutU16")
+
+%def op_iput_char_quick():
+% op_iput_quick(reg="rINSTw", store="movw")
+
+%def op_iput_object():
+% op_iput(is_object="1", helper="MterpIPutObj")
+
+%def op_iput_object_quick():
+ EXPORT_PC
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
+ movq rPC, OUT_ARG1
+ REFRESH_INST ${opnum}
+ movl rINST, OUT_32_ARG2
+ call SYMBOL(MterpIputObjectQuick)
+ testb %al, %al
+ jz MterpException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput_quick(reg="rINST", store="movl"):
+ /* For: iput-quick, iput-object-quick */
+ /* op vA, vB, offset@CCCC */
+ movzbq rINSTbl, %rcx # rcx <- BA
+ sarl $$4, %ecx # ecx <- B
+ GET_VREG %ecx, %rcx # vB (object we're operating on)
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ andb $$0xf, rINSTbl # rINST <- A
+ GET_VREG rINST, rINSTq # rINST <- v[A]
+ movzwq 2(rPC), %rax # rax <- field byte offset
+ ${store} ${reg}, (%rcx,%rax,1)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_iput_short():
+% op_iput(helper="MterpIPutI16")
+
+%def op_iput_short_quick():
+% op_iput_quick(reg="rINSTw", store="movw")
+
+%def op_iput_wide():
+% op_iput(helper="MterpIPutU64")
+
+%def op_iput_wide_quick():
+ /* iput-wide-quick vA, vB, offset@CCCC */
+ movzbq rINSTbl, %rcx # rcx<- BA
+ sarl $$4, %ecx # ecx<- B
+ GET_VREG %ecx, %rcx # vB (object we're operating on)
+ testl %ecx, %ecx # is object null?
+ je common_errNullObject
+ movzwq 2(rPC), %rax # rax<- field byte offset
+ leaq (%rcx,%rax,1), %rcx # ecx<- Address of 64-bit target
+ andb $$0xf, rINSTbl # rINST<- A
+ GET_WIDE_VREG %rax, rINSTq # rax<- fp[A]/fp[A+1]
+ movq %rax, (%rcx) # obj.field<- r0/r1
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_new_instance():
+/*
+ * Create a new instance of a class.
+ */
+ /* new-instance vAA, class@BBBB */
+ EXPORT_PC
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
+ movq rSELF, OUT_ARG1
+ REFRESH_INST ${opnum}
+ movq rINSTq, OUT_ARG2
+ call SYMBOL(MterpNewInstance)
+ testb %al, %al # 0 means an exception is thrown
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_sget(is_object="0", helper="MterpSGetU32"):
+% field(helper=helper)
+
+%def op_sget_boolean():
+% op_sget(helper="MterpSGetU8")
+
+%def op_sget_byte():
+% op_sget(helper="MterpSGetI8")
+
+%def op_sget_char():
+% op_sget(helper="MterpSGetU16")
+
+%def op_sget_object():
+% op_sget(is_object="1", helper="MterpSGetObj")
+
+%def op_sget_short():
+% op_sget(helper="MterpSGetI16")
+
+%def op_sget_wide():
+% op_sget(helper="MterpSGetU64")
+
+%def op_sput(is_object="0", helper="MterpSPutU32"):
+% field(helper=helper)
+
+%def op_sput_boolean():
+% op_sput(helper="MterpSPutU8")
+
+%def op_sput_byte():
+% op_sput(helper="MterpSPutI8")
+
+%def op_sput_char():
+% op_sput(helper="MterpSPutU16")
+
+%def op_sput_object():
+% op_sput(is_object="1", helper="MterpSPutObj")
+
+%def op_sput_short():
+% op_sput(helper="MterpSPutI16")
+
+%def op_sput_wide():
+% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_double.S b/runtime/interpreter/mterp/x86_64/op_add_double.S
deleted file mode 100644
index a009239..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double():
-% sseBinop(instr="adds", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_double_2addr.S b/runtime/interpreter/mterp/x86_64/op_add_double_2addr.S
deleted file mode 100644
index 8cb45a9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_double_2addr():
-% sseBinop2Addr(instr="adds", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_float.S b/runtime/interpreter/mterp/x86_64/op_add_float.S
deleted file mode 100644
index dee28c7..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float():
-% sseBinop(instr="adds", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_float_2addr.S b/runtime/interpreter/mterp/x86_64/op_add_float_2addr.S
deleted file mode 100644
index 4deb445..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_float_2addr():
-% sseBinop2Addr(instr="adds", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_int.S b/runtime/interpreter/mterp/x86_64/op_add_int.S
deleted file mode 100644
index aaf0b35..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int():
-% binop(instr="addl (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_add_int_2addr.S
deleted file mode 100644
index 8ce26f6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_2addr():
-% binop2addr(instr="addl %eax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_add_int_lit16.S
deleted file mode 100644
index a431030..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit16():
-% binopLit16(instr="addl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_add_int_lit8.S
deleted file mode 100644
index 3205aee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_int_lit8():
-% binopLit8(instr="addl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_long.S b/runtime/interpreter/mterp/x86_64/op_add_long.S
deleted file mode 100644
index fac8163..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long():
-% binopWide(instr="addq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_add_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_add_long_2addr.S
deleted file mode 100644
index 17684e6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_add_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_add_long_2addr():
-% binopWide2addr(instr="addq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_aget.S b/runtime/interpreter/mterp/x86_64/op_aget.S
deleted file mode 100644
index b45f43a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget.S
+++ /dev/null
@@ -1,24 +0,0 @@
-%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
-/*
- * Array get, 32 bits or less. vAA <- vBB[vCC].
- *
- * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide
- *
- */
- /* op vAA, vBB, vCC */
- movzbq 2(rPC), %rax # eax <- BB
- movzbq 3(rPC), %rcx # ecx <- CC
- GET_VREG %eax, %rax # eax <- vBB (array object)
- GET_VREG %ecx, %rcx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- .if $wide
- movq $data_offset(%rax,%rcx,8), %rax
- SET_WIDE_VREG %rax, rINSTq
- .else
- $load $data_offset(%rax,%rcx,$shift), %eax
- SET_VREG %eax, rINSTq
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_boolean.S b/runtime/interpreter/mterp/x86_64/op_aget_boolean.S
deleted file mode 100644
index 279e6fc..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_boolean():
-% op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_byte.S b/runtime/interpreter/mterp/x86_64/op_aget_byte.S
deleted file mode 100644
index 1989450..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_byte():
-% op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_char.S b/runtime/interpreter/mterp/x86_64/op_aget_char.S
deleted file mode 100644
index a35269b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_char():
-% op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_object.S b/runtime/interpreter/mterp/x86_64/op_aget_object.S
deleted file mode 100644
index fc099dc..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_object.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_aget_object():
-/*
- * Array object get. vAA <- vBB[vCC].
- *
- * for: aget-object
- */
- /* op vAA, vBB, vCC */
- movzbq 2(rPC), %rax # rax <- BB
- movzbq 3(rPC), %rcx # rcx <- CC
- GET_VREG OUT_32_ARG0, %rax # eax <- vBB (array object)
- GET_VREG OUT_32_ARG1, %rcx # ecx <- vCC (requested index)
- EXPORT_PC
- call SYMBOL(artAGetObjectFromMterp) # (array, index)
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- SET_VREG_OBJECT %eax, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_short.S b/runtime/interpreter/mterp/x86_64/op_aget_short.S
deleted file mode 100644
index ca51ec8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_short():
-% op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aget_wide.S b/runtime/interpreter/mterp/x86_64/op_aget_wide.S
deleted file mode 100644
index 42513fc..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aget_wide():
-% op_aget(load="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_int.S b/runtime/interpreter/mterp/x86_64/op_and_int.S
deleted file mode 100644
index afe2d67..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int():
-% binop(instr="andl (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_and_int_2addr.S
deleted file mode 100644
index ed9fc65..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_2addr():
-% binop2addr(instr="andl %eax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_and_int_lit16.S
deleted file mode 100644
index d7752b1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit16():
-% binopLit16(instr="andl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_and_int_lit8.S
deleted file mode 100644
index a353178..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_int_lit8():
-% binopLit8(instr="andl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_long.S b/runtime/interpreter/mterp/x86_64/op_and_long.S
deleted file mode 100644
index 7375154..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long():
-% binopWide(instr="andq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_and_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_and_long_2addr.S
deleted file mode 100644
index 41938ac..0000000
--- a/runtime/interpreter/mterp/x86_64/op_and_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_and_long_2addr():
-% binopWide2addr(instr="andq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_aput.S b/runtime/interpreter/mterp/x86_64/op_aput.S
deleted file mode 100644
index bef2e2a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_aput(reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
-/*
- * Array put, 32 bits or less. vBB[vCC] <- vAA.
- *
- * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide
- *
- */
- /* op vAA, vBB, vCC */
- movzbq 2(rPC), %rax # rax <- BB
- movzbq 3(rPC), %rcx # rcx <- CC
- GET_VREG %eax, %rax # eax <- vBB (array object)
- GET_VREG %ecx, %rcx # ecx <- vCC (requested index)
- testl %eax, %eax # null array object?
- je common_errNullObject # bail if so
- cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
- jae common_errArrayIndex # index >= length, bail.
- .if $wide
- GET_WIDE_VREG rINSTq, rINSTq
- .else
- GET_VREG rINST, rINSTq
- .endif
- $store $reg, $data_offset(%rax,%rcx,$shift)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_boolean.S b/runtime/interpreter/mterp/x86_64/op_aput_boolean.S
deleted file mode 100644
index 8420b5a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_boolean():
-% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_byte.S b/runtime/interpreter/mterp/x86_64/op_aput_byte.S
deleted file mode 100644
index 6c181a4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_byte():
-% op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_char.S b/runtime/interpreter/mterp/x86_64/op_aput_char.S
deleted file mode 100644
index 3f4602a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_char():
-% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_object.S b/runtime/interpreter/mterp/x86_64/op_aput_object.S
deleted file mode 100644
index cf4bdf1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_object.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_aput_object():
-/*
- * Store an object into an array. vBB[vCC] <- vAA.
- */
- /* op vAA, vBB, vCC */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movq rINSTq, OUT_ARG2
- call SYMBOL(MterpAputObject) # (array, index)
- testb %al, %al
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_short.S b/runtime/interpreter/mterp/x86_64/op_aput_short.S
deleted file mode 100644
index e76d833..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_short():
-% op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
diff --git a/runtime/interpreter/mterp/x86_64/op_aput_wide.S b/runtime/interpreter/mterp/x86_64/op_aput_wide.S
deleted file mode 100644
index c1ca1ef..0000000
--- a/runtime/interpreter/mterp/x86_64/op_aput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_aput_wide():
-% op_aput(reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_array_length.S b/runtime/interpreter/mterp/x86_64/op_array_length.S
deleted file mode 100644
index 7e6c5c0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_array_length.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_array_length():
-/*
- * Return the length of an array.
- */
- movl rINST, %eax # eax <- BA
- sarl $$4, rINST # rINST <- B
- GET_VREG %ecx, rINSTq # ecx <- vB (object ref)
- testl %ecx, %ecx # is null?
- je common_errNullObject
- andb $$0xf, %al # eax <- A
- movl MIRROR_ARRAY_LENGTH_OFFSET(%rcx), rINST
- SET_VREG rINST, %rax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_check_cast.S b/runtime/interpreter/mterp/x86_64/op_check_cast.S
deleted file mode 100644
index ac7051b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_check_cast.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_check_cast():
-/*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast vAA, class@BBBB */
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # OUT_ARG0 <- BBBB
- leaq VREG_ADDRESS(rINSTq), OUT_ARG1
- movq OFF_FP_METHOD(rFP), OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpCheckCast) # (index, &obj, method, self)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_cmp_long.S b/runtime/interpreter/mterp/x86_64/op_cmp_long.S
deleted file mode 100644
index f222813..0000000
--- a/runtime/interpreter/mterp/x86_64/op_cmp_long.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_cmp_long():
-/*
- * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
- * register based on the results of the comparison.
- */
- /* cmp-long vAA, vBB, vCC */
- movzbq 2(rPC), %rdx # edx <- BB
- movzbq 3(rPC), %rcx # ecx <- CC
- GET_WIDE_VREG %rdx, %rdx # rdx <- v[BB]
- xorl %eax, %eax
- xorl %edi, %edi
- addb $$1, %al
- movl $$-1, %esi
- cmpq VREG_ADDRESS(%rcx), %rdx
- cmovl %esi, %edi
- cmovg %eax, %edi
- SET_VREG %edi, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_cmpg_double.S b/runtime/interpreter/mterp/x86_64/op_cmpg_double.S
deleted file mode 100644
index 1c04e99..0000000
--- a/runtime/interpreter/mterp/x86_64/op_cmpg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_double():
-% fpcmp(suff="d", nanval="pos")
diff --git a/runtime/interpreter/mterp/x86_64/op_cmpg_float.S b/runtime/interpreter/mterp/x86_64/op_cmpg_float.S
deleted file mode 100644
index 797c3d5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_cmpg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpg_float():
-% fpcmp(suff="s", nanval="pos")
diff --git a/runtime/interpreter/mterp/x86_64/op_cmpl_double.S b/runtime/interpreter/mterp/x86_64/op_cmpl_double.S
deleted file mode 100644
index cbe8db7..0000000
--- a/runtime/interpreter/mterp/x86_64/op_cmpl_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_double():
-% fpcmp(suff="d", nanval="neg")
diff --git a/runtime/interpreter/mterp/x86_64/op_cmpl_float.S b/runtime/interpreter/mterp/x86_64/op_cmpl_float.S
deleted file mode 100644
index 068f4cb..0000000
--- a/runtime/interpreter/mterp/x86_64/op_cmpl_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_cmpl_float():
-% fpcmp(suff="s", nanval="neg")
diff --git a/runtime/interpreter/mterp/x86_64/op_const.S b/runtime/interpreter/mterp/x86_64/op_const.S
deleted file mode 100644
index 3622095..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const():
- /* const vAA, #+BBBBbbbb */
- movl 2(rPC), %eax # grab all 32 bits at once
- SET_VREG %eax, rINSTq # vAA<- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_const_16.S b/runtime/interpreter/mterp/x86_64/op_const_16.S
deleted file mode 100644
index fa86060..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_16.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const_16():
- /* const/16 vAA, #+BBBB */
- movswl 2(rPC), %ecx # ecx <- ssssBBBB
- SET_VREG %ecx, rINSTq # vAA <- ssssBBBB
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_const_4.S b/runtime/interpreter/mterp/x86_64/op_const_4.S
deleted file mode 100644
index 9f39cee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_4.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_const_4():
- /* const/4 vA, #+B */
- movsbl rINSTbl, %eax # eax <-ssssssBx
- movl $$0xf, rINST
- andl %eax, rINST # rINST <- A
- sarl $$4, %eax
- SET_VREG %eax, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_const_class.S b/runtime/interpreter/mterp/x86_64/op_const_class.S
deleted file mode 100644
index db12ec3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_class.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_class():
-% const(helper="MterpConstClass")
diff --git a/runtime/interpreter/mterp/x86_64/op_const_high16.S b/runtime/interpreter/mterp/x86_64/op_const_high16.S
deleted file mode 100644
index e1e61e3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_high16.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_const_high16():
- /* const/high16 vAA, #+BBBB0000 */
- movzwl 2(rPC), %eax # eax <- 0000BBBB
- sall $$16, %eax # eax <- BBBB0000
- SET_VREG %eax, rINSTq # vAA <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_const_method_handle.S b/runtime/interpreter/mterp/x86_64/op_const_method_handle.S
deleted file mode 100644
index 2680c17..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_method_handle.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_handle():
-% const(helper="MterpConstMethodHandle")
diff --git a/runtime/interpreter/mterp/x86_64/op_const_method_type.S b/runtime/interpreter/mterp/x86_64/op_const_method_type.S
deleted file mode 100644
index ea814bf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_method_type.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_method_type():
-% const(helper="MterpConstMethodType")
diff --git a/runtime/interpreter/mterp/x86_64/op_const_string.S b/runtime/interpreter/mterp/x86_64/op_const_string.S
deleted file mode 100644
index 41376f8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_string.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_const_string():
-% const(helper="MterpConstString")
diff --git a/runtime/interpreter/mterp/x86_64/op_const_string_jumbo.S b/runtime/interpreter/mterp/x86_64/op_const_string_jumbo.S
deleted file mode 100644
index c12abb1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_string_jumbo.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_const_string_jumbo():
- /* const/string vAA, String@BBBBBBBB */
- EXPORT_PC
- movl 2(rPC), OUT_32_ARG0 # OUT_32_ARG0 <- BBBB
- movq rINSTq, OUT_ARG1
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_const_wide.S b/runtime/interpreter/mterp/x86_64/op_const_wide.S
deleted file mode 100644
index f7a74c2..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_wide.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const_wide():
- /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
- movq 2(rPC), %rax # rax <- HHHHhhhhBBBBbbbb
- SET_WIDE_VREG %rax, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 5
diff --git a/runtime/interpreter/mterp/x86_64/op_const_wide_16.S b/runtime/interpreter/mterp/x86_64/op_const_wide_16.S
deleted file mode 100644
index 8d1e17c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_wide_16.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const_wide_16():
- /* const-wide/16 vAA, #+BBBB */
- movswq 2(rPC), %rax # rax <- ssssBBBB
- SET_WIDE_VREG %rax, rINSTq # store
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_const_wide_32.S b/runtime/interpreter/mterp/x86_64/op_const_wide_32.S
deleted file mode 100644
index 22b8074..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_wide_32.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def op_const_wide_32():
- /* const-wide/32 vAA, #+BBBBbbbb */
- movslq 2(rPC), %rax # eax <- ssssssssBBBBbbbb
- SET_WIDE_VREG %rax, rINSTq # store
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_const_wide_high16.S b/runtime/interpreter/mterp/x86_64/op_const_wide_high16.S
deleted file mode 100644
index d41b02a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_const_wide_high16.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_const_wide_high16():
- /* const-wide/high16 vAA, #+BBBB000000000000 */
- movzwq 2(rPC), %rax # eax <- 0000BBBB
- salq $$48, %rax # eax <- BBBB0000
- SET_WIDE_VREG %rax, rINSTq # v[AA+0] <- eax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_div_double.S b/runtime/interpreter/mterp/x86_64/op_div_double.S
deleted file mode 100644
index 6b342f8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double():
-% sseBinop(instr="divs", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_double_2addr.S b/runtime/interpreter/mterp/x86_64/op_div_double_2addr.S
deleted file mode 100644
index 212c825..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_double_2addr():
-% sseBinop2Addr(instr="divs", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_float.S b/runtime/interpreter/mterp/x86_64/op_div_float.S
deleted file mode 100644
index b6537d9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float():
-% sseBinop(instr="divs", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_float_2addr.S b/runtime/interpreter/mterp/x86_64/op_div_float_2addr.S
deleted file mode 100644
index 19ae27d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_float_2addr():
-% sseBinop2Addr(instr="divs", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_int.S b/runtime/interpreter/mterp/x86_64/op_div_int.S
deleted file mode 100644
index cd7f3db..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int():
-% bindiv(result="%eax", second="%ecx", wide="0", suffix="l")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_div_int_2addr.S
deleted file mode 100644
index 3a734db..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_2addr():
-% bindiv2addr(result="%eax", second="%ecx", wide="0", suffix="l")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_div_int_lit16.S
deleted file mode 100644
index cdcee2d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit16():
-% bindivLit16(result="%eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_div_int_lit8.S
deleted file mode 100644
index 7d258c8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_int_lit8():
-% bindivLit8(result="%eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_long.S b/runtime/interpreter/mterp/x86_64/op_div_long.S
deleted file mode 100644
index 59f9073..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long():
-% bindiv(result="%rax", second="%rcx", wide="1", suffix="q", ext="cqo")
diff --git a/runtime/interpreter/mterp/x86_64/op_div_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_div_long_2addr.S
deleted file mode 100644
index d7a46f5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_div_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_div_long_2addr():
-% bindiv2addr(result="%rax", second="%rcx", wide="1", suffix="q", ext="cqo")
diff --git a/runtime/interpreter/mterp/x86_64/op_double_to_float.S b/runtime/interpreter/mterp/x86_64/op_double_to_float.S
deleted file mode 100644
index e62aa4d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_double_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_float():
-% fpcvt(source_suffix="d", dest_suffix="s", wide="0")
diff --git a/runtime/interpreter/mterp/x86_64/op_double_to_int.S b/runtime/interpreter/mterp/x86_64/op_double_to_int.S
deleted file mode 100644
index 24fca63..0000000
--- a/runtime/interpreter/mterp/x86_64/op_double_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_int():
-% cvtfp_int(fp_suffix="d", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
diff --git a/runtime/interpreter/mterp/x86_64/op_double_to_long.S b/runtime/interpreter/mterp/x86_64/op_double_to_long.S
deleted file mode 100644
index 8f042c0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_double_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_double_to_long():
-% cvtfp_int(fp_suffix="d", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_fill_array_data.S b/runtime/interpreter/mterp/x86_64/op_fill_array_data.S
deleted file mode 100644
index 694ee79..0000000
--- a/runtime/interpreter/mterp/x86_64/op_fill_array_data.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_fill_array_data():
- /* fill-array-data vAA, +BBBBBBBB */
- EXPORT_PC
- movslq 2(rPC), %rcx # rcx <- ssssssssBBBBbbbb
- leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + ssssssssBBBBbbbb*2
- GET_VREG OUT_32_ARG0, rINSTq # OUT_ARG0 <- vAA (array object)
- call SYMBOL(MterpFillArrayData) # (obj, payload)
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_filled_new_array.S b/runtime/interpreter/mterp/x86_64/op_filled_new_array.S
deleted file mode 100644
index 0f8b20e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_filled_new_array.S
+++ /dev/null
@@ -1,17 +0,0 @@
-%def op_filled_new_array(helper="MterpFilledNewArray"):
-/*
- * Create a new array with elements filled from registers.
- *
- * for: filled-new-array, filled-new-array/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
- .extern $helper
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- movq rSELF, OUT_ARG2
- call SYMBOL($helper)
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_filled_new_array_range.S b/runtime/interpreter/mterp/x86_64/op_filled_new_array_range.S
deleted file mode 100644
index 1667de1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_filled_new_array_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_filled_new_array_range():
-% op_filled_new_array(helper="MterpFilledNewArrayRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_float_to_double.S b/runtime/interpreter/mterp/x86_64/op_float_to_double.S
deleted file mode 100644
index a7cf8d3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_float_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_double():
-% fpcvt(source_suffix="s", dest_suffix="d", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_float_to_int.S b/runtime/interpreter/mterp/x86_64/op_float_to_int.S
deleted file mode 100644
index 1195586..0000000
--- a/runtime/interpreter/mterp/x86_64/op_float_to_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_int():
-% cvtfp_int(fp_suffix="s", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
diff --git a/runtime/interpreter/mterp/x86_64/op_float_to_long.S b/runtime/interpreter/mterp/x86_64/op_float_to_long.S
deleted file mode 100644
index 4548d6a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_float_to_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_float_to_long():
-% cvtfp_int(fp_suffix="s", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_goto.S b/runtime/interpreter/mterp/x86_64/op_goto.S
deleted file mode 100644
index 0659bbc..0000000
--- a/runtime/interpreter/mterp/x86_64/op_goto.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto():
-/*
- * Unconditional branch, 8-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto +AA */
- movsbq rINSTbl, rINSTq # rINSTq <- ssssssAA
- testq rINSTq, rINSTq
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86_64/op_goto_16.S b/runtime/interpreter/mterp/x86_64/op_goto_16.S
deleted file mode 100644
index 1193f70..0000000
--- a/runtime/interpreter/mterp/x86_64/op_goto_16.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_goto_16():
-/*
- * Unconditional branch, 16-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- */
- /* goto/16 +AAAA */
- movswq 2(rPC), rINSTq # rINSTq <- ssssAAAA
- testq rINSTq, rINSTq
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86_64/op_goto_32.S b/runtime/interpreter/mterp/x86_64/op_goto_32.S
deleted file mode 100644
index cd0b522..0000000
--- a/runtime/interpreter/mterp/x86_64/op_goto_32.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_goto_32():
-/*
- * Unconditional branch, 32-bit offset.
- *
- * The branch distance is a signed code-unit offset, which we need to
- * double to get a byte offset.
- *
- * Because we need the SF bit set, we'll use an adds
- * to convert from Dalvik offset to byte offset.
- */
- /* goto/32 +AAAAAAAA */
- movslq 2(rPC), rINSTq # rINSTq <- AAAAAAAA
- testq rINSTq, rINSTq
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86_64/op_if_eq.S b/runtime/interpreter/mterp/x86_64/op_if_eq.S
deleted file mode 100644
index 4d1f6a5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_eq.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eq():
-% bincmp(revcmp="ne")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_eqz.S b/runtime/interpreter/mterp/x86_64/op_if_eqz.S
deleted file mode 100644
index 12de558..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_eqz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_eqz():
-% zcmp(revcmp="ne")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_ge.S b/runtime/interpreter/mterp/x86_64/op_if_ge.S
deleted file mode 100644
index 6849027..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_ge.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ge():
-% bincmp(revcmp="l")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_gez.S b/runtime/interpreter/mterp/x86_64/op_if_gez.S
deleted file mode 100644
index 87bdcbf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_gez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gez():
-% zcmp(revcmp="l")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_gt.S b/runtime/interpreter/mterp/x86_64/op_if_gt.S
deleted file mode 100644
index 4a52100..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_gt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gt():
-% bincmp(revcmp="le")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_gtz.S b/runtime/interpreter/mterp/x86_64/op_if_gtz.S
deleted file mode 100644
index a0b2e3a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_gtz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_gtz():
-% zcmp(revcmp="le")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_le.S b/runtime/interpreter/mterp/x86_64/op_if_le.S
deleted file mode 100644
index 69e94db..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_le.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_le():
-% bincmp(revcmp="g")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_lez.S b/runtime/interpreter/mterp/x86_64/op_if_lez.S
deleted file mode 100644
index 42e69d9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_lez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lez():
-% zcmp(revcmp="g")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_lt.S b/runtime/interpreter/mterp/x86_64/op_if_lt.S
deleted file mode 100644
index 052aabe..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_lt.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_lt():
-% bincmp(revcmp="ge")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_ltz.S b/runtime/interpreter/mterp/x86_64/op_if_ltz.S
deleted file mode 100644
index 8e13e48..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_ltz.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ltz():
-% zcmp(revcmp="ge")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_ne.S b/runtime/interpreter/mterp/x86_64/op_if_ne.S
deleted file mode 100644
index 2cfd8a9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_ne.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_ne():
-% bincmp(revcmp="e")
diff --git a/runtime/interpreter/mterp/x86_64/op_if_nez.S b/runtime/interpreter/mterp/x86_64/op_if_nez.S
deleted file mode 100644
index 261a173..0000000
--- a/runtime/interpreter/mterp/x86_64/op_if_nez.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_if_nez():
-% zcmp(revcmp="e")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget.S b/runtime/interpreter/mterp/x86_64/op_iget.S
deleted file mode 100644
index d09edc0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget(is_object="0", helper="MterpIGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_boolean.S b/runtime/interpreter/mterp/x86_64/op_iget_boolean.S
deleted file mode 100644
index cb8edee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean():
-% op_iget(helper="MterpIGetU8")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_boolean_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_boolean_quick.S
deleted file mode 100644
index 4e16768..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_boolean_quick():
-% op_iget_quick(load="movsbl")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_byte.S b/runtime/interpreter/mterp/x86_64/op_iget_byte.S
deleted file mode 100644
index 2b87fb1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte():
-% op_iget(helper="MterpIGetI8")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_byte_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_byte_quick.S
deleted file mode 100644
index b92936c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_byte_quick():
-% op_iget_quick(load="movsbl")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_char.S b/runtime/interpreter/mterp/x86_64/op_iget_char.S
deleted file mode 100644
index 001bd03..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char():
-% op_iget(helper="MterpIGetU16")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_char_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_char_quick.S
deleted file mode 100644
index d6f836b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_char_quick():
-% op_iget_quick(load="movzwl")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_object.S b/runtime/interpreter/mterp/x86_64/op_iget_object.S
deleted file mode 100644
index 4e5f769..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_object():
-% op_iget(is_object="1", helper="MterpIGetObj")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_object_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_object_quick.S
deleted file mode 100644
index 1969a25..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_object_quick.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_iget_object_quick():
- /* For: iget-object-quick */
- /* op vA, vB, offset@CCCC */
- .extern artIGetObjectFromMterp
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG0, %rcx # vB (object we're operating on)
- movzwl 2(rPC), OUT_32_ARG1 # eax <- field byte offset
- EXPORT_PC
- callq SYMBOL(artIGetObjectFromMterp) # (obj, offset)
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_quick.S
deleted file mode 100644
index ba9e8e4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_quick.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_iget_quick(load="movl", wide="0"):
- /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick, iget-wide-quick */
- /* op vA, vB, offset@CCCC */
- movl rINST, %ecx # rcx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %rcx # vB (object we're operating on)
- movzwq 2(rPC), %rax # eax <- field byte offset
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- andb $$0xf,rINSTbl # rINST <- A
- .if $wide
- movq (%rcx,%rax,1), %rax
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- ${load} (%rcx,%rax,1), %eax
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_short.S b/runtime/interpreter/mterp/x86_64/op_iget_short.S
deleted file mode 100644
index a62c4d9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short():
-% op_iget(helper="MterpIGetI16")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_short_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_short_quick.S
deleted file mode 100644
index f5e48d6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_short_quick():
-% op_iget_quick(load="movswl")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_wide.S b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
deleted file mode 100644
index 9643cc3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide():
-% op_iget(helper="MterpIGetU64")
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_wide_quick.S b/runtime/interpreter/mterp/x86_64/op_iget_wide_quick.S
deleted file mode 100644
index 263ea8c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iget_wide_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iget_wide_quick():
-% op_iget_quick(load="movswl", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_instance_of.S b/runtime/interpreter/mterp/x86_64/op_instance_of.S
deleted file mode 100644
index 237dd39..0000000
--- a/runtime/interpreter/mterp/x86_64/op_instance_of.S
+++ /dev/null
@@ -1,23 +0,0 @@
-%def op_instance_of():
-/*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- */
- /* instance-of vA, vB, class@CCCC */
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # OUT_32_ARG0 <- CCCC
- movl rINST, %eax # eax <- BA
- sarl $$4, %eax # eax <- B
- leaq VREG_ADDRESS(%rax), OUT_ARG1 # Get object address
- movq OFF_FP_METHOD(rFP), OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpInstanceOf) # (index, &obj, method, self)
- movsbl %al, %eax
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- andb $$0xf, rINSTbl # rINSTbl <- A
- SET_VREG %eax, rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_byte.S b/runtime/interpreter/mterp/x86_64/op_int_to_byte.S
deleted file mode 100644
index 80e4d5c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_byte():
-% unop(instr="movsbl %al, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_char.S b/runtime/interpreter/mterp/x86_64/op_int_to_char.S
deleted file mode 100644
index 83e9868..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_char():
-% unop(instr="movzwl %ax,%eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_double.S b/runtime/interpreter/mterp/x86_64/op_int_to_double.S
deleted file mode 100644
index 74e91ec..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_double():
-% fpcvt(source_suffix="i", dest_suffix="dl", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_float.S b/runtime/interpreter/mterp/x86_64/op_int_to_float.S
deleted file mode 100644
index b57fc84..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_float():
-% fpcvt(source_suffix="i", dest_suffix="sl", wide="0")
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_long.S b/runtime/interpreter/mterp/x86_64/op_int_to_long.S
deleted file mode 100644
index 473d6a2..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_long.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_int_to_long():
- /* int to long vA, vB */
- movzbq rINSTbl, %rax # rax <- +A
- sarl $$4, %eax # eax <- B
- andb $$0xf, rINSTbl # rINST <- A
- movslq VREG_ADDRESS(%rax), %rax
- SET_WIDE_VREG %rax, rINSTq # v[A] <- %rax
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
-
diff --git a/runtime/interpreter/mterp/x86_64/op_int_to_short.S b/runtime/interpreter/mterp/x86_64/op_int_to_short.S
deleted file mode 100644
index e4db90b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_int_to_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_int_to_short():
-% unop(instr="movswl %ax, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_custom.S b/runtime/interpreter/mterp/x86_64/op_invoke_custom.S
deleted file mode 100644
index 4bba9ee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_custom.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom():
-% invoke(helper="MterpInvokeCustom")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_custom_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_custom_range.S
deleted file mode 100644
index 57e61af..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_custom_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_custom_range():
-% invoke(helper="MterpInvokeCustomRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_direct.S b/runtime/interpreter/mterp/x86_64/op_invoke_direct.S
deleted file mode 100644
index d3139cf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_direct.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct():
-% invoke(helper="MterpInvokeDirect")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_direct_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_direct_range.S
deleted file mode 100644
index b4a161f..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_direct_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_direct_range():
-% invoke(helper="MterpInvokeDirectRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_interface.S b/runtime/interpreter/mterp/x86_64/op_invoke_interface.S
deleted file mode 100644
index 559b976..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_interface.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_interface():
-% invoke(helper="MterpInvokeInterface")
-/*
- * Handle an interface method call.
- *
- * for: invoke-interface, invoke-interface/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_interface_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_interface_range.S
deleted file mode 100644
index 2989115..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_interface_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_interface_range():
-% invoke(helper="MterpInvokeInterfaceRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic.S b/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic.S
deleted file mode 100644
index ce61f5a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic():
-% invoke_polymorphic(helper="MterpInvokePolymorphic")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic_range.S
deleted file mode 100644
index 16731bd..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_polymorphic_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_polymorphic_range():
-% invoke_polymorphic(helper="MterpInvokePolymorphicRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_static.S b/runtime/interpreter/mterp/x86_64/op_invoke_static.S
deleted file mode 100644
index 3e38d36..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_static.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_invoke_static():
-% invoke(helper="MterpInvokeStatic")
-
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_static_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_static_range.S
deleted file mode 100644
index e0a546c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_static_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_static_range():
-% invoke(helper="MterpInvokeStaticRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_super.S b/runtime/interpreter/mterp/x86_64/op_invoke_super.S
deleted file mode 100644
index 5b20550..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_super.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_super():
-% invoke(helper="MterpInvokeSuper")
-/*
- * Handle a "super" method call.
- *
- * for: invoke-super, invoke-super/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_super_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_super_range.S
deleted file mode 100644
index caeafaa..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_super_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_super_range():
-% invoke(helper="MterpInvokeSuperRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_virtual.S b/runtime/interpreter/mterp/x86_64/op_invoke_virtual.S
deleted file mode 100644
index e27eeed..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_virtual.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_invoke_virtual():
-% invoke(helper="MterpInvokeVirtual")
-/*
- * Handle a virtual method call.
- *
- * for: invoke-virtual, invoke-virtual/range
- */
- /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
- /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_quick.S b/runtime/interpreter/mterp/x86_64/op_invoke_virtual_quick.S
deleted file mode 100644
index ea72c17..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_quick():
-% invoke(helper="MterpInvokeVirtualQuick")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range.S b/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range.S
deleted file mode 100644
index baa0779..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range():
-% invoke(helper="MterpInvokeVirtualRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range_quick.S b/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range_quick.S
deleted file mode 100644
index 1d961a0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_invoke_virtual_range_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_invoke_virtual_range_quick():
-% invoke(helper="MterpInvokeVirtualQuickRange")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput.S b/runtime/interpreter/mterp/x86_64/op_iput.S
deleted file mode 100644
index e5351ba..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput(is_object="0", helper="MterpIPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_boolean.S b/runtime/interpreter/mterp/x86_64/op_iput_boolean.S
deleted file mode 100644
index 9eb8498..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean():
-% op_iput(helper="MterpIPutU8")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_boolean_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_boolean_quick.S
deleted file mode 100644
index c304c76..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_boolean_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_boolean_quick():
-% op_iput_quick(reg="rINSTbl", store="movb")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_byte.S b/runtime/interpreter/mterp/x86_64/op_iput_byte.S
deleted file mode 100644
index 4b74f9f..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte():
-% op_iput(helper="MterpIPutI8")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_byte_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_byte_quick.S
deleted file mode 100644
index dac18e6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_byte_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_byte_quick():
-% op_iput_quick(reg="rINSTbl", store="movb")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_char.S b/runtime/interpreter/mterp/x86_64/op_iput_char.S
deleted file mode 100644
index 64a249f..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char():
-% op_iput(helper="MterpIPutU16")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_char_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_char_quick.S
deleted file mode 100644
index 21a2581..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_char_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_char_quick():
-% op_iput_quick(reg="rINSTw", store="movw")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_object.S b/runtime/interpreter/mterp/x86_64/op_iput_object.S
deleted file mode 100644
index 131edd5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_object():
-% op_iput(is_object="1", helper="MterpIPutObj")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_object_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_object_quick.S
deleted file mode 100644
index e41540d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_object_quick.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_iput_object_quick():
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movl rINST, OUT_32_ARG2
- call SYMBOL(MterpIputObjectQuick)
- testb %al, %al
- jz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_quick.S
deleted file mode 100644
index 3cbb7e9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iput_quick(reg="rINST", store="movl"):
- /* For: iput-quick, iput-object-quick */
- /* op vA, vB, offset@CCCC */
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %rcx # vB (object we're operating on)
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- andb $$0xf, rINSTbl # rINST <- A
- GET_VREG rINST, rINSTq # rINST <- v[A]
- movzwq 2(rPC), %rax # rax <- field byte offset
- ${store} ${reg}, (%rcx,%rax,1)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_short.S b/runtime/interpreter/mterp/x86_64/op_iput_short.S
deleted file mode 100644
index e631a3b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short():
-% op_iput(helper="MterpIPutI16")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_short_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_short_quick.S
deleted file mode 100644
index 5eb28d6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_short_quick.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_short_quick():
-% op_iput_quick(reg="rINSTw", store="movw")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_wide.S b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
deleted file mode 100644
index 2f34fd3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_iput_wide():
-% op_iput(helper="MterpIPutU64")
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_wide_quick.S b/runtime/interpreter/mterp/x86_64/op_iput_wide_quick.S
deleted file mode 100644
index a13a634..0000000
--- a/runtime/interpreter/mterp/x86_64/op_iput_wide_quick.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_iput_wide_quick():
- /* iput-wide-quick vA, vB, offset@CCCC */
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG %ecx, %rcx # vB (object we're operating on)
- testl %ecx, %ecx # is object null?
- je common_errNullObject
- movzwq 2(rPC), %rax # rax<- field byte offset
- leaq (%rcx,%rax,1), %rcx # ecx<- Address of 64-bit target
- andb $$0xf, rINSTbl # rINST<- A
- GET_WIDE_VREG %rax, rINSTq # rax<- fp[A]/fp[A+1]
- movq %rax, (%rcx) # obj.field<- r0/r1
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_long_to_double.S b/runtime/interpreter/mterp/x86_64/op_long_to_double.S
deleted file mode 100644
index 6b2d7bf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_long_to_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_double():
-% fpcvt(source_suffix="i", dest_suffix="dq", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_long_to_float.S b/runtime/interpreter/mterp/x86_64/op_long_to_float.S
deleted file mode 100644
index 7c2edfd..0000000
--- a/runtime/interpreter/mterp/x86_64/op_long_to_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_long_to_float():
-% fpcvt(source_suffix="i", dest_suffix="sq", wide="0")
diff --git a/runtime/interpreter/mterp/x86_64/op_long_to_int.S b/runtime/interpreter/mterp/x86_64/op_long_to_int.S
deleted file mode 100644
index eacb8f5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_long_to_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_long_to_int():
-/* we ignore the high word, making this equivalent to a 32-bit reg move */
-% op_move()
diff --git a/runtime/interpreter/mterp/x86_64/op_monitor_enter.S b/runtime/interpreter/mterp/x86_64/op_monitor_enter.S
deleted file mode 100644
index 7865156..0000000
--- a/runtime/interpreter/mterp/x86_64/op_monitor_enter.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_monitor_enter():
-/*
- * Synchronize on an object.
- */
- /* monitor-enter vAA */
- EXPORT_PC
- GET_VREG OUT_32_ARG0, rINSTq
- movq rSELF, OUT_ARG1
- call SYMBOL(artLockObjectFromCode) # (object, self)
- testq %rax, %rax
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_monitor_exit.S b/runtime/interpreter/mterp/x86_64/op_monitor_exit.S
deleted file mode 100644
index 6422bc8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_monitor_exit.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_monitor_exit():
-/*
- * Unlock an object.
- *
- * Exceptions that occur when unlocking a monitor need to appear as
- * if they happened at the following instruction. See the Dalvik
- * instruction spec.
- */
- /* monitor-exit vAA */
- EXPORT_PC
- GET_VREG OUT_32_ARG0, rINSTq
- movq rSELF, OUT_ARG1
- call SYMBOL(artUnlockObjectFromCode) # (object, self)
- testq %rax, %rax
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move.S b/runtime/interpreter/mterp/x86_64/op_move.S
deleted file mode 100644
index 0ccf228..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move.S
+++ /dev/null
@@ -1,13 +0,0 @@
-%def op_move(is_object="0"):
- /* for move, move-object, long-to-int */
- /* op vA, vB */
- movl rINST, %eax # eax <- BA
- andb $$0xf, %al # eax <- A
- shrl $$4, rINST # rINST <- B
- GET_VREG %edx, rINSTq
- .if $is_object
- SET_VREG_OBJECT %edx, %rax # fp[A] <- fp[B]
- .else
- SET_VREG %edx, %rax # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move_16.S b/runtime/interpreter/mterp/x86_64/op_move_16.S
deleted file mode 100644
index 238f089..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_16.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_move_16(is_object="0"):
- /* for: move/16, move-object/16 */
- /* op vAAAA, vBBBB */
- movzwq 4(rPC), %rcx # ecx <- BBBB
- movzwq 2(rPC), %rax # eax <- AAAA
- GET_VREG %edx, %rcx
- .if $is_object
- SET_VREG_OBJECT %edx, %rax # fp[A] <- fp[B]
- .else
- SET_VREG %edx, %rax # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_move_exception.S b/runtime/interpreter/mterp/x86_64/op_move_exception.S
deleted file mode 100644
index 9d87f7c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_exception.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def op_move_exception():
- /* move-exception vAA */
- movq rSELF, %rcx
- movl THREAD_EXCEPTION_OFFSET(%rcx), %eax
- SET_VREG_OBJECT %eax, rINSTq # fp[AA] <- exception object
- movl $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move_from16.S b/runtime/interpreter/mterp/x86_64/op_move_from16.S
deleted file mode 100644
index 6163e6d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_from16.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_move_from16(is_object="0"):
- /* for: move/from16, move-object/from16 */
- /* op vAA, vBBBB */
- movzwq 2(rPC), %rax # eax <- BBBB
- GET_VREG %edx, %rax # edx <- fp[BBBB]
- .if $is_object
- SET_VREG_OBJECT %edx, rINSTq # fp[A] <- fp[B]
- .else
- SET_VREG %edx, rINSTq # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_move_object.S b/runtime/interpreter/mterp/x86_64/op_move_object.S
deleted file mode 100644
index dbb4d59..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object():
-% op_move(is_object="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_move_object_16.S b/runtime/interpreter/mterp/x86_64/op_move_object_16.S
deleted file mode 100644
index 4012037..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_object_16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_16():
-% op_move_16(is_object="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_move_object_from16.S b/runtime/interpreter/mterp/x86_64/op_move_object_from16.S
deleted file mode 100644
index c82698e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_object_from16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_object_from16():
-% op_move_from16(is_object="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_move_result.S b/runtime/interpreter/mterp/x86_64/op_move_result.S
deleted file mode 100644
index a089623..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_result.S
+++ /dev/null
@@ -1,11 +0,0 @@
-%def op_move_result(is_object="0"):
- /* for: move-result, move-result-object */
- /* op vAA */
- movq OFF_FP_RESULT_REGISTER(rFP), %rax # get pointer to result JType.
- movl (%rax), %eax # r0 <- result.i.
- .if $is_object
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- fp[B]
- .else
- SET_VREG %eax, rINSTq # fp[A] <- fp[B]
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move_result_object.S b/runtime/interpreter/mterp/x86_64/op_move_result_object.S
deleted file mode 100644
index 87aea26..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_result_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_move_result_object():
-% op_move_result(is_object="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_move_result_wide.S b/runtime/interpreter/mterp/x86_64/op_move_result_wide.S
deleted file mode 100644
index 80f49aa..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_result_wide.S
+++ /dev/null
@@ -1,6 +0,0 @@
-%def op_move_result_wide():
- /* move-result-wide vAA */
- movq OFF_FP_RESULT_REGISTER(rFP), %rax # get pointer to result JType.
- movq (%rax), %rdx # Get wide
- SET_WIDE_VREG %rdx, rINSTq # v[AA] <- rdx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move_wide.S b/runtime/interpreter/mterp/x86_64/op_move_wide.S
deleted file mode 100644
index afb67ef..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_wide.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_move_wide():
- /* move-wide vA, vB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movl rINST, %ecx # ecx <- BA
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_WIDE_VREG %rdx, rINSTq # rdx <- v[B]
- SET_WIDE_VREG %rdx, %rcx # v[A] <- rdx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_move_wide_16.S b/runtime/interpreter/mterp/x86_64/op_move_wide_16.S
deleted file mode 100644
index b4de520..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_wide_16.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_move_wide_16():
- /* move-wide/16 vAAAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movzwq 4(rPC), %rcx # ecx<- BBBB
- movzwq 2(rPC), %rax # eax<- AAAA
- GET_WIDE_VREG %rdx, %rcx # rdx <- v[B]
- SET_WIDE_VREG %rdx, %rax # v[A] <- rdx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
diff --git a/runtime/interpreter/mterp/x86_64/op_move_wide_from16.S b/runtime/interpreter/mterp/x86_64/op_move_wide_from16.S
deleted file mode 100644
index c4389a4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_move_wide_from16.S
+++ /dev/null
@@ -1,7 +0,0 @@
-%def op_move_wide_from16():
- /* move-wide/from16 vAA, vBBBB */
- /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
- movzwl 2(rPC), %ecx # ecx <- BBBB
- GET_WIDE_VREG %rdx, %rcx # rdx <- v[B]
- SET_WIDE_VREG %rdx, rINSTq # v[A] <- rdx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_double.S b/runtime/interpreter/mterp/x86_64/op_mul_double.S
deleted file mode 100644
index 5353028..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double():
-% sseBinop(instr="muls", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_double_2addr.S b/runtime/interpreter/mterp/x86_64/op_mul_double_2addr.S
deleted file mode 100644
index 7a6dcd0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_double_2addr():
-% sseBinop2Addr(instr="muls", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_float.S b/runtime/interpreter/mterp/x86_64/op_mul_float.S
deleted file mode 100644
index b9eeeee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float():
-% sseBinop(instr="muls", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_float_2addr.S b/runtime/interpreter/mterp/x86_64/op_mul_float_2addr.S
deleted file mode 100644
index 949af7b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_float_2addr():
-% sseBinop2Addr(instr="muls", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_int.S b/runtime/interpreter/mterp/x86_64/op_mul_int.S
deleted file mode 100644
index 51abae6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int():
-% binop(instr="imull (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_mul_int_2addr.S
deleted file mode 100644
index fb2ec89..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_int_2addr.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_mul_int_2addr():
- /* mul vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_VREG %eax, %rcx # eax <- vA
- imull (rFP,rINSTq,4), %eax
- SET_VREG %eax, %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_mul_int_lit16.S
deleted file mode 100644
index a0b1e71..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit16():
-% binopLit16(instr="imull %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_mul_int_lit8.S
deleted file mode 100644
index e68e7f7..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_int_lit8():
-% binopLit8(instr="imull %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_long.S b/runtime/interpreter/mterp/x86_64/op_mul_long.S
deleted file mode 100644
index e5bffa4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_mul_long():
-% binopWide(instr="imulq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_mul_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_mul_long_2addr.S
deleted file mode 100644
index 25ffc14..0000000
--- a/runtime/interpreter/mterp/x86_64/op_mul_long_2addr.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def op_mul_long_2addr():
- /* mul vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4, rINST # rINST <- B
- andb $$0xf, %cl # ecx <- A
- GET_WIDE_VREG %rax, %rcx # rax <- vA
- imulq (rFP,rINSTq,4), %rax
- SET_WIDE_VREG %rax, %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_neg_double.S b/runtime/interpreter/mterp/x86_64/op_neg_double.S
deleted file mode 100644
index 56e3804..0000000
--- a/runtime/interpreter/mterp/x86_64/op_neg_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_double():
-% unop(preinstr=" movq $0x8000000000000000, %rsi", instr=" xorq %rsi, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_neg_float.S b/runtime/interpreter/mterp/x86_64/op_neg_float.S
deleted file mode 100644
index 6a39444..0000000
--- a/runtime/interpreter/mterp/x86_64/op_neg_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_float():
-% unop(instr=" xorl $0x80000000, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_neg_int.S b/runtime/interpreter/mterp/x86_64/op_neg_int.S
deleted file mode 100644
index 44790ed..0000000
--- a/runtime/interpreter/mterp/x86_64/op_neg_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_int():
-% unop(instr=" negl %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_neg_long.S b/runtime/interpreter/mterp/x86_64/op_neg_long.S
deleted file mode 100644
index 2d296ee..0000000
--- a/runtime/interpreter/mterp/x86_64/op_neg_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_neg_long():
-% unop(instr=" negq %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_new_array.S b/runtime/interpreter/mterp/x86_64/op_new_array.S
deleted file mode 100644
index de1b001..0000000
--- a/runtime/interpreter/mterp/x86_64/op_new_array.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def op_new_array():
-/*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array vA, vB, class@CCCC */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movq rINSTq, OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpNewArray)
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_new_instance.S b/runtime/interpreter/mterp/x86_64/op_new_instance.S
deleted file mode 100644
index cc3f31c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_new_instance.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_new_instance():
-/*
- * Create a new instance of a class.
- */
- /* new-instance vAA, class@BBBB */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rSELF, OUT_ARG1
- REFRESH_INST ${opnum}
- movq rINSTq, OUT_ARG2
- call SYMBOL(MterpNewInstance)
- testb %al, %al # 0 means an exception is thrown
- jz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_nop.S b/runtime/interpreter/mterp/x86_64/op_nop.S
deleted file mode 100644
index aa4a843..0000000
--- a/runtime/interpreter/mterp/x86_64/op_nop.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_nop():
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_not_int.S b/runtime/interpreter/mterp/x86_64/op_not_int.S
deleted file mode 100644
index 55ac8a7..0000000
--- a/runtime/interpreter/mterp/x86_64/op_not_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_int():
-% unop(instr=" notl %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_not_long.S b/runtime/interpreter/mterp/x86_64/op_not_long.S
deleted file mode 100644
index c6c0f85..0000000
--- a/runtime/interpreter/mterp/x86_64/op_not_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_not_long():
-% unop(instr=" notq %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_int.S b/runtime/interpreter/mterp/x86_64/op_or_int.S
deleted file mode 100644
index 0e6dd67..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int():
-% binop(instr="orl (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_or_int_2addr.S
deleted file mode 100644
index c722938..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_2addr():
-% binop2addr(instr="orl %eax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_or_int_lit16.S
deleted file mode 100644
index ba9b6bf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit16():
-% binopLit16(instr="orl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_or_int_lit8.S
deleted file mode 100644
index 758109b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_int_lit8():
-% binopLit8(instr="orl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_long.S b/runtime/interpreter/mterp/x86_64/op_or_long.S
deleted file mode 100644
index b9c9321..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long():
-% binopWide(instr="orq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_or_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_or_long_2addr.S
deleted file mode 100644
index 616288e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_or_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_or_long_2addr():
-% binopWide2addr(instr="orq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_packed_switch.S b/runtime/interpreter/mterp/x86_64/op_packed_switch.S
deleted file mode 100644
index 8b2b18b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_packed_switch.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def op_packed_switch(func="MterpDoPackedSwitch"):
-/*
- * Handle a packed-switch or sparse-switch instruction. In both cases
- * we decode it and hand it off to a helper function.
- *
- * We don't really expect backward branches in a switch statement, but
- * they're perfectly legal, so we check for them here.
- *
- * for: packed-switch, sparse-switch
- */
- /* op vAA, +BBBB */
- movslq 2(rPC), OUT_ARG0 # rcx <- ssssssssBBBBbbbb
- leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + ssssssssBBBBbbbb*2
- GET_VREG OUT_32_ARG1, rINSTq # eax <- vAA
- call SYMBOL($func)
- testl %eax, %eax
- movslq %eax, rINSTq
- jmp MterpCommonTakenBranch
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_double.S b/runtime/interpreter/mterp/x86_64/op_rem_double.S
deleted file mode 100644
index 9b1c0b4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_double.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_rem_double():
- /* rem_double vAA, vBB, vCC */
- movzbq 3(rPC), %rcx # ecx <- BB
- movzbq 2(rPC), %rax # eax <- CC
- fldl VREG_ADDRESS(%rcx) # %st1 <- fp[vBB]
- fldl VREG_ADDRESS(%rax) # %st0 <- fp[vCC]
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstpl VREG_ADDRESS(rINSTq) # fp[vAA] <- %st
- CLEAR_WIDE_REF rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_double_2addr.S b/runtime/interpreter/mterp/x86_64/op_rem_double_2addr.S
deleted file mode 100644
index 0600e90..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_double_2addr.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_rem_double_2addr():
- /* rem_double/2addr vA, vB */
- movzbq rINSTbl, %rcx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- fldl VREG_ADDRESS(rINSTq) # vB to fp stack
- andb $$0xf, %cl # ecx <- A
- fldl VREG_ADDRESS(%rcx) # vA to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstpl VREG_ADDRESS(%rcx) # %st to vA
- CLEAR_WIDE_REF %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_float.S b/runtime/interpreter/mterp/x86_64/op_rem_float.S
deleted file mode 100644
index 28c1328..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_float.S
+++ /dev/null
@@ -1,15 +0,0 @@
-%def op_rem_float():
- /* rem_float vAA, vBB, vCC */
- movzbq 3(rPC), %rcx # ecx <- BB
- movzbq 2(rPC), %rax # eax <- CC
- flds VREG_ADDRESS(%rcx) # vBB to fp stack
- flds VREG_ADDRESS(%rax) # vCC to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstps VREG_ADDRESS(rINSTq) # %st to vAA
- CLEAR_REF rINSTq
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_float_2addr.S b/runtime/interpreter/mterp/x86_64/op_rem_float_2addr.S
deleted file mode 100644
index 8cfdca0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_float_2addr.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_rem_float_2addr():
- /* rem_float/2addr vA, vB */
- movzbq rINSTbl, %rcx # ecx <- A+
- sarl $$4, rINST # rINST <- B
- flds VREG_ADDRESS(rINSTq) # vB to fp stack
- andb $$0xf, %cl # ecx <- A
- flds VREG_ADDRESS(%rcx) # vA to fp stack
-1:
- fprem
- fstsw %ax
- sahf
- jp 1b
- fstp %st(1)
- fstps VREG_ADDRESS(%rcx) # %st to vA
- CLEAR_REF %rcx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_int.S b/runtime/interpreter/mterp/x86_64/op_rem_int.S
deleted file mode 100644
index 1530f5f..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int():
-% bindiv(result="%edx", second="%ecx", wide="0", suffix="l", rem="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_rem_int_2addr.S
deleted file mode 100644
index 742213a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_2addr():
-% bindiv2addr(result="%edx", second="%ecx", wide="0", suffix="l", rem="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_rem_int_lit16.S
deleted file mode 100644
index eaa44a4..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit16():
-% bindivLit16(result="%edx", rem="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_rem_int_lit8.S
deleted file mode 100644
index 3fef144..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_int_lit8():
-% bindivLit8(result="%edx", rem="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_long.S b/runtime/interpreter/mterp/x86_64/op_rem_long.S
deleted file mode 100644
index 60bfd3d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long():
-% bindiv(result="%rdx", second="%rcx", wide="1", suffix="q", ext="cqo", rem="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_rem_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_rem_long_2addr.S
deleted file mode 100644
index fc5a2d0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rem_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rem_long_2addr():
-% bindiv2addr(result="%rdx", second="%rcx", wide="1", suffix="q", rem="1", ext="cqo")
diff --git a/runtime/interpreter/mterp/x86_64/op_return.S b/runtime/interpreter/mterp/x86_64/op_return.S
deleted file mode 100644
index b838f18..0000000
--- a/runtime/interpreter/mterp/x86_64/op_return.S
+++ /dev/null
@@ -1,16 +0,0 @@
-%def op_return():
-/*
- * Return a 32-bit value.
- *
- * for: return, return-object
- */
- /* op vAA */
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movq rSELF, OUT_ARG0
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
- jz 1f
- call SYMBOL(MterpSuspendCheck)
-1:
- GET_VREG %eax, rINSTq # eax <- vAA
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86_64/op_return_object.S b/runtime/interpreter/mterp/x86_64/op_return_object.S
deleted file mode 100644
index 2eeec0b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_return_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_return_object():
-% op_return()
diff --git a/runtime/interpreter/mterp/x86_64/op_return_void.S b/runtime/interpreter/mterp/x86_64/op_return_void.S
deleted file mode 100644
index 301dc92..0000000
--- a/runtime/interpreter/mterp/x86_64/op_return_void.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def op_return_void():
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movq rSELF, OUT_ARG0
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
- jz 1f
- call SYMBOL(MterpSuspendCheck)
-1:
- xorq %rax, %rax
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86_64/op_return_void_no_barrier.S b/runtime/interpreter/mterp/x86_64/op_return_void_no_barrier.S
deleted file mode 100644
index cec739c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_return_void_no_barrier.S
+++ /dev/null
@@ -1,8 +0,0 @@
-%def op_return_void_no_barrier():
- movq rSELF, OUT_ARG0
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
- jz 1f
- call SYMBOL(MterpSuspendCheck)
-1:
- xorq %rax, %rax
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86_64/op_return_wide.S b/runtime/interpreter/mterp/x86_64/op_return_wide.S
deleted file mode 100644
index 90e0a42..0000000
--- a/runtime/interpreter/mterp/x86_64/op_return_wide.S
+++ /dev/null
@@ -1,14 +0,0 @@
-%def op_return_wide():
-/*
- * Return a 64-bit value.
- */
- /* return-wide vAA */
- .extern MterpThreadFenceForConstructor
- call SYMBOL(MterpThreadFenceForConstructor)
- movq rSELF, OUT_ARG0
- testl $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(OUT_ARG0)
- jz 1f
- call SYMBOL(MterpSuspendCheck)
-1:
- GET_WIDE_VREG %rax, rINSTq # eax <- v[AA]
- jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86_64/op_rsub_int.S b/runtime/interpreter/mterp/x86_64/op_rsub_int.S
deleted file mode 100644
index 05ba130..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rsub_int.S
+++ /dev/null
@@ -1,3 +0,0 @@
-%def op_rsub_int():
-/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
-% binopLit16(instr="subl %eax, %ecx", result="%ecx")
diff --git a/runtime/interpreter/mterp/x86_64/op_rsub_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_rsub_int_lit8.S
deleted file mode 100644
index d023047..0000000
--- a/runtime/interpreter/mterp/x86_64/op_rsub_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_rsub_int_lit8():
-% binopLit8(instr="subl %eax, %ecx", result="%ecx")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget.S b/runtime/interpreter/mterp/x86_64/op_sget.S
deleted file mode 100644
index 8a6a66a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget(is_object="0", helper="MterpSGetU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_boolean.S b/runtime/interpreter/mterp/x86_64/op_sget_boolean.S
deleted file mode 100644
index d9c12c9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_boolean():
-% op_sget(helper="MterpSGetU8")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_byte.S b/runtime/interpreter/mterp/x86_64/op_sget_byte.S
deleted file mode 100644
index 37c6879..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_byte():
-% op_sget(helper="MterpSGetI8")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_char.S b/runtime/interpreter/mterp/x86_64/op_sget_char.S
deleted file mode 100644
index 003bcd1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_char():
-% op_sget(helper="MterpSGetU16")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_object.S b/runtime/interpreter/mterp/x86_64/op_sget_object.S
deleted file mode 100644
index 7cf3597..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_object():
-% op_sget(is_object="1", helper="MterpSGetObj")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_short.S b/runtime/interpreter/mterp/x86_64/op_sget_short.S
deleted file mode 100644
index afacb57..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_short():
-% op_sget(helper="MterpSGetI16")
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_wide.S b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
deleted file mode 100644
index fff2be6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sget_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sget_wide():
-% op_sget(helper="MterpSGetU64")
diff --git a/runtime/interpreter/mterp/x86_64/op_shl_int.S b/runtime/interpreter/mterp/x86_64/op_shl_int.S
deleted file mode 100644
index a98b256..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shl_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int():
-% binop1(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shl_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_shl_int_2addr.S
deleted file mode 100644
index 987c7d1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shl_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_2addr():
-% shop2addr(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shl_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_shl_int_lit8.S
deleted file mode 100644
index ee1a15e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shl_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_int_lit8():
-% binopLit8(instr="sall %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shl_long.S b/runtime/interpreter/mterp/x86_64/op_shl_long.S
deleted file mode 100644
index c288b36..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shl_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long():
-% binop1(instr="salq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_shl_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_shl_long_2addr.S
deleted file mode 100644
index 820e703..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shl_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shl_long_2addr():
-% shop2addr(instr="salq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_shr_int.S b/runtime/interpreter/mterp/x86_64/op_shr_int.S
deleted file mode 100644
index 4d4d79c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int():
-% binop1(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shr_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_shr_int_2addr.S
deleted file mode 100644
index 8e4b055..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_2addr():
-% shop2addr(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shr_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_shr_int_lit8.S
deleted file mode 100644
index a7acf5f..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_int_lit8():
-% binopLit8(instr="sarl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_shr_long.S b/runtime/interpreter/mterp/x86_64/op_shr_long.S
deleted file mode 100644
index ed3e504..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long():
-% binop1(instr="sarq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_shr_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_shr_long_2addr.S
deleted file mode 100644
index be6898d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_shr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_shr_long_2addr():
-% shop2addr(instr="sarq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_sparse_switch.S b/runtime/interpreter/mterp/x86_64/op_sparse_switch.S
deleted file mode 100644
index b74d7da..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sparse_switch.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sparse_switch():
-% op_packed_switch(func="MterpDoSparseSwitch")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput.S b/runtime/interpreter/mterp/x86_64/op_sput.S
deleted file mode 100644
index cbd6ee9..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput(is_object="0", helper="MterpSPutU32"):
-% field(helper=helper)
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_boolean.S b/runtime/interpreter/mterp/x86_64/op_sput_boolean.S
deleted file mode 100644
index 36fba84..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_boolean.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_boolean():
-% op_sput(helper="MterpSPutU8")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_byte.S b/runtime/interpreter/mterp/x86_64/op_sput_byte.S
deleted file mode 100644
index 84ad4a0..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_byte.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_byte():
-% op_sput(helper="MterpSPutI8")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_char.S b/runtime/interpreter/mterp/x86_64/op_sput_char.S
deleted file mode 100644
index 9b8eeba..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_char.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_char():
-% op_sput(helper="MterpSPutU16")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_object.S b/runtime/interpreter/mterp/x86_64/op_sput_object.S
deleted file mode 100644
index 081360c..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_object.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_object():
-% op_sput(is_object="1", helper="MterpSPutObj")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_short.S b/runtime/interpreter/mterp/x86_64/op_sput_short.S
deleted file mode 100644
index ee16513..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_short.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_short():
-% op_sput(helper="MterpSPutI16")
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_wide.S b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
deleted file mode 100644
index 44c1a18..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sput_wide.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sput_wide():
-% op_sput(helper="MterpSPutU64")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_double.S b/runtime/interpreter/mterp/x86_64/op_sub_double.S
deleted file mode 100644
index 64a28c3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_double.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double():
-% sseBinop(instr="subs", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_double_2addr.S b/runtime/interpreter/mterp/x86_64/op_sub_double_2addr.S
deleted file mode 100644
index 753074b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_double_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_double_2addr():
-% sseBinop2Addr(instr="subs", suff="d")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_float.S b/runtime/interpreter/mterp/x86_64/op_sub_float.S
deleted file mode 100644
index 1a1966d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_float.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float():
-% sseBinop(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_float_2addr.S b/runtime/interpreter/mterp/x86_64/op_sub_float_2addr.S
deleted file mode 100644
index 9557907..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_float_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_float_2addr():
-% sseBinop2Addr(instr="subs", suff="s")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_int.S b/runtime/interpreter/mterp/x86_64/op_sub_int.S
deleted file mode 100644
index ecab19d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int():
-% binop(instr="subl (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_sub_int_2addr.S
deleted file mode 100644
index 61fc7a7..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_int_2addr():
-% binop2addr(instr="subl %eax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_long.S b/runtime/interpreter/mterp/x86_64/op_sub_long.S
deleted file mode 100644
index 9c38f88..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long():
-% binopWide(instr="subq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_sub_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_sub_long_2addr.S
deleted file mode 100644
index ab31aaf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_sub_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_sub_long_2addr():
-% binopWide2addr(instr="subq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_throw.S b/runtime/interpreter/mterp/x86_64/op_throw.S
deleted file mode 100644
index 09fc1ec..0000000
--- a/runtime/interpreter/mterp/x86_64/op_throw.S
+++ /dev/null
@@ -1,12 +0,0 @@
-%def op_throw():
-/*
- * Throw an exception object in the current thread.
- */
- /* throw vAA */
- EXPORT_PC
- GET_VREG %eax, rINSTq # eax<- vAA (exception object)
- testb %al, %al
- jz common_errNullObject
- movq rSELF, %rcx
- movq %rax, THREAD_EXCEPTION_OFFSET(%rcx)
- jmp MterpException
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_3e.S b/runtime/interpreter/mterp/x86_64/op_unused_3e.S
deleted file mode 100644
index d889f1a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_3e.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3e():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_3f.S b/runtime/interpreter/mterp/x86_64/op_unused_3f.S
deleted file mode 100644
index b3ebcfa..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_3f.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_3f():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_40.S b/runtime/interpreter/mterp/x86_64/op_unused_40.S
deleted file mode 100644
index 7920fb3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_40.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_40():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_41.S b/runtime/interpreter/mterp/x86_64/op_unused_41.S
deleted file mode 100644
index 5ed03b8..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_41.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_41():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_42.S b/runtime/interpreter/mterp/x86_64/op_unused_42.S
deleted file mode 100644
index ac32521..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_42.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_42():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_43.S b/runtime/interpreter/mterp/x86_64/op_unused_43.S
deleted file mode 100644
index 33e2aa1..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_43.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_43():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_79.S b/runtime/interpreter/mterp/x86_64/op_unused_79.S
deleted file mode 100644
index 3c6dafc..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_79.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_79():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_7a.S b/runtime/interpreter/mterp/x86_64/op_unused_7a.S
deleted file mode 100644
index 9c03cd5..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_7a.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_7a():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f3.S b/runtime/interpreter/mterp/x86_64/op_unused_f3.S
deleted file mode 100644
index ab10b78..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f3.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f3():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f4.S b/runtime/interpreter/mterp/x86_64/op_unused_f4.S
deleted file mode 100644
index 09229d6..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f4.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f4():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f5.S b/runtime/interpreter/mterp/x86_64/op_unused_f5.S
deleted file mode 100644
index 0d6149b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f5.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f5():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f6.S b/runtime/interpreter/mterp/x86_64/op_unused_f6.S
deleted file mode 100644
index 117b03d..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f6.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f6():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f7.S b/runtime/interpreter/mterp/x86_64/op_unused_f7.S
deleted file mode 100644
index 4e3a0f3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f7.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f7():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f8.S b/runtime/interpreter/mterp/x86_64/op_unused_f8.S
deleted file mode 100644
index d122075..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f8():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_f9.S b/runtime/interpreter/mterp/x86_64/op_unused_f9.S
deleted file mode 100644
index 7d09a0e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_f9.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_f9():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_fc.S b/runtime/interpreter/mterp/x86_64/op_unused_fc.S
deleted file mode 100644
index 0697819..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_fc.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fc():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_unused_fd.S b/runtime/interpreter/mterp/x86_64/op_unused_fd.S
deleted file mode 100644
index 4bc2b4b..0000000
--- a/runtime/interpreter/mterp/x86_64/op_unused_fd.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_unused_fd():
-% unused()
diff --git a/runtime/interpreter/mterp/x86_64/op_ushr_int.S b/runtime/interpreter/mterp/x86_64/op_ushr_int.S
deleted file mode 100644
index 38c8782..0000000
--- a/runtime/interpreter/mterp/x86_64/op_ushr_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int():
-% binop1(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_ushr_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_ushr_int_2addr.S
deleted file mode 100644
index f1da71a..0000000
--- a/runtime/interpreter/mterp/x86_64/op_ushr_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_2addr():
-% shop2addr(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_ushr_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_ushr_int_lit8.S
deleted file mode 100644
index 4298d36..0000000
--- a/runtime/interpreter/mterp/x86_64/op_ushr_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_int_lit8():
-% binopLit8(instr="shrl %cl, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_ushr_long.S b/runtime/interpreter/mterp/x86_64/op_ushr_long.S
deleted file mode 100644
index a0b4daf..0000000
--- a/runtime/interpreter/mterp/x86_64/op_ushr_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long():
-% binop1(instr="shrq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_ushr_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_ushr_long_2addr.S
deleted file mode 100644
index 2213cf3..0000000
--- a/runtime/interpreter/mterp/x86_64/op_ushr_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_ushr_long_2addr():
-% shop2addr(instr="shrq %cl, %rax", wide="1")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_int.S b/runtime/interpreter/mterp/x86_64/op_xor_int.S
deleted file mode 100644
index 5dc2603..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_int.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int():
-% binop(instr="xorl (rFP,%rcx,4), %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_int_2addr.S b/runtime/interpreter/mterp/x86_64/op_xor_int_2addr.S
deleted file mode 100644
index 2c84702..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_int_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_2addr():
-% binop2addr(instr="xorl %eax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_int_lit16.S b/runtime/interpreter/mterp/x86_64/op_xor_int_lit16.S
deleted file mode 100644
index f5dc00e..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_int_lit16.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit16():
-% binopLit16(instr="xorl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_int_lit8.S b/runtime/interpreter/mterp/x86_64/op_xor_int_lit8.S
deleted file mode 100644
index 98a1a43..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_int_lit8.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_int_lit8():
-% binopLit8(instr="xorl %ecx, %eax")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_long.S b/runtime/interpreter/mterp/x86_64/op_xor_long.S
deleted file mode 100644
index 1c26793..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_long.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long():
-% binopWide(instr="xorq (rFP,%rcx,4), %rax")
diff --git a/runtime/interpreter/mterp/x86_64/op_xor_long_2addr.S b/runtime/interpreter/mterp/x86_64/op_xor_long_2addr.S
deleted file mode 100644
index c649651..0000000
--- a/runtime/interpreter/mterp/x86_64/op_xor_long_2addr.S
+++ /dev/null
@@ -1,2 +0,0 @@
-%def op_xor_long_2addr():
-% binopWide2addr(instr="xorq %rax, (rFP,%rcx,4)")
diff --git a/runtime/interpreter/mterp/x86_64/other.S b/runtime/interpreter/mterp/x86_64/other.S
new file mode 100644
index 0000000..849155c
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/other.S
@@ -0,0 +1,287 @@
+%def const(helper="UndefinedConstHandler"):
+ /* const/class vAA, type@BBBB */
+ /* const/method-handle vAA, method_handle@BBBB */
+ /* const/method-type vAA, proto@BBBB */
+ /* const/string vAA, string@@BBBB */
+ .extern $helper
+ EXPORT_PC
+ movzwq 2(rPC), OUT_ARG0 # eax <- OUT_ARG0
+ movq rINSTq, OUT_ARG1
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2
+ movq rSELF, OUT_ARG3
+ call SYMBOL($helper) # (index, tgt_reg, shadow_frame, self)
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def unused():
+/*
+ * Bail to reference interpreter to throw.
+ */
+ jmp MterpFallback
+
+%def op_const():
+ /* const vAA, #+BBBBbbbb */
+ movl 2(rPC), %eax # grab all 32 bits at once
+ SET_VREG %eax, rINSTq # vAA<- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_16():
+ /* const/16 vAA, #+BBBB */
+ movswl 2(rPC), %ecx # ecx <- ssssBBBB
+ SET_VREG %ecx, rINSTq # vAA <- ssssBBBB
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_4():
+ /* const/4 vA, #+B */
+ movsbl rINSTbl, %eax # eax <-ssssssBx
+ movl $$0xf, rINST
+ andl %eax, rINST # rINST <- A
+ sarl $$4, %eax
+ SET_VREG %eax, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_const_class():
+% const(helper="MterpConstClass")
+
+%def op_const_high16():
+ /* const/high16 vAA, #+BBBB0000 */
+ movzwl 2(rPC), %eax # eax <- 0000BBBB
+ sall $$16, %eax # eax <- BBBB0000
+ SET_VREG %eax, rINSTq # vAA <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_method_handle():
+% const(helper="MterpConstMethodHandle")
+
+%def op_const_method_type():
+% const(helper="MterpConstMethodType")
+
+%def op_const_string():
+% const(helper="MterpConstString")
+
+%def op_const_string_jumbo():
+ /* const/string vAA, String@BBBBBBBB */
+ EXPORT_PC
+ movl 2(rPC), OUT_32_ARG0 # OUT_32_ARG0 <- BBBB
+ movq rINSTq, OUT_ARG1
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2
+ movq rSELF, OUT_ARG3
+ call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self)
+ testb %al, %al
+ jnz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_wide():
+ /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
+ movq 2(rPC), %rax # rax <- HHHHhhhhBBBBbbbb
+ SET_WIDE_VREG %rax, rINSTq
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 5
+
+%def op_const_wide_16():
+ /* const-wide/16 vAA, #+BBBB */
+ movswq 2(rPC), %rax # rax <- ssssBBBB
+ SET_WIDE_VREG %rax, rINSTq # store
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_const_wide_32():
+ /* const-wide/32 vAA, #+BBBBbbbb */
+ movslq 2(rPC), %rax # eax <- ssssssssBBBBbbbb
+ SET_WIDE_VREG %rax, rINSTq # store
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_const_wide_high16():
+ /* const-wide/high16 vAA, #+BBBB000000000000 */
+ movzwq 2(rPC), %rax # eax <- 0000BBBB
+ salq $$48, %rax # eax <- BBBB0000
+ SET_WIDE_VREG %rax, rINSTq # v[AA+0] <- eax
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_monitor_enter():
+/*
+ * Synchronize on an object.
+ */
+ /* monitor-enter vAA */
+ EXPORT_PC
+ GET_VREG OUT_32_ARG0, rINSTq
+ movq rSELF, OUT_ARG1
+ call SYMBOL(artLockObjectFromCode) # (object, self)
+ testq %rax, %rax
+ jnz MterpException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_monitor_exit():
+/*
+ * Unlock an object.
+ *
+ * Exceptions that occur when unlocking a monitor need to appear as
+ * if they happened at the following instruction. See the Dalvik
+ * instruction spec.
+ */
+ /* monitor-exit vAA */
+ EXPORT_PC
+ GET_VREG OUT_32_ARG0, rINSTq
+ movq rSELF, OUT_ARG1
+ call SYMBOL(artUnlockObjectFromCode) # (object, self)
+ testq %rax, %rax
+ jnz MterpException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move(is_object="0"):
+ /* for move, move-object, long-to-int */
+ /* op vA, vB */
+ movl rINST, %eax # eax <- BA
+ andb $$0xf, %al # eax <- A
+ shrl $$4, rINST # rINST <- B
+ GET_VREG %edx, rINSTq
+ .if $is_object
+ SET_VREG_OBJECT %edx, %rax # fp[A] <- fp[B]
+ .else
+ SET_VREG %edx, %rax # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_16(is_object="0"):
+ /* for: move/16, move-object/16 */
+ /* op vAAAA, vBBBB */
+ movzwq 4(rPC), %rcx # ecx <- BBBB
+ movzwq 2(rPC), %rax # eax <- AAAA
+ GET_VREG %edx, %rcx
+ .if $is_object
+ SET_VREG_OBJECT %edx, %rax # fp[A] <- fp[B]
+ .else
+ SET_VREG %edx, %rax # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_move_exception():
+ /* move-exception vAA */
+ movq rSELF, %rcx
+ movl THREAD_EXCEPTION_OFFSET(%rcx), %eax
+ SET_VREG_OBJECT %eax, rINSTq # fp[AA] <- exception object
+ movl $$0, THREAD_EXCEPTION_OFFSET(%rcx)
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_from16(is_object="0"):
+ /* for: move/from16, move-object/from16 */
+ /* op vAA, vBBBB */
+ movzwq 2(rPC), %rax # eax <- BBBB
+ GET_VREG %edx, %rax # edx <- fp[BBBB]
+ .if $is_object
+ SET_VREG_OBJECT %edx, rINSTq # fp[A] <- fp[B]
+ .else
+ SET_VREG %edx, rINSTq # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_move_object():
+% op_move(is_object="1")
+
+%def op_move_object_16():
+% op_move_16(is_object="1")
+
+%def op_move_object_from16():
+% op_move_from16(is_object="1")
+
+%def op_move_result(is_object="0"):
+ /* for: move-result, move-result-object */
+ /* op vAA */
+ movq OFF_FP_RESULT_REGISTER(rFP), %rax # get pointer to result JType.
+ movl (%rax), %eax # r0 <- result.i.
+ .if $is_object
+ SET_VREG_OBJECT %eax, rINSTq # fp[A] <- fp[B]
+ .else
+ SET_VREG %eax, rINSTq # fp[A] <- fp[B]
+ .endif
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_result_object():
+% op_move_result(is_object="1")
+
+%def op_move_result_wide():
+ /* move-result-wide vAA */
+ movq OFF_FP_RESULT_REGISTER(rFP), %rax # get pointer to result JType.
+ movq (%rax), %rdx # Get wide
+ SET_WIDE_VREG %rdx, rINSTq # v[AA] <- rdx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_wide():
+ /* move-wide vA, vB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movl rINST, %ecx # ecx <- BA
+ sarl $$4, rINST # rINST <- B
+ andb $$0xf, %cl # ecx <- A
+ GET_WIDE_VREG %rdx, rINSTq # rdx <- v[B]
+ SET_WIDE_VREG %rdx, %rcx # v[A] <- rdx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_move_wide_16():
+ /* move-wide/16 vAAAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movzwq 4(rPC), %rcx # ecx<- BBBB
+ movzwq 2(rPC), %rax # eax<- AAAA
+ GET_WIDE_VREG %rdx, %rcx # rdx <- v[B]
+ SET_WIDE_VREG %rdx, %rax # v[A] <- rdx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+
+%def op_move_wide_from16():
+ /* move-wide/from16 vAA, vBBBB */
+ /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
+ movzwl 2(rPC), %ecx # ecx <- BBBB
+ GET_WIDE_VREG %rdx, %rcx # rdx <- v[B]
+ SET_WIDE_VREG %rdx, rINSTq # v[A] <- rdx
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+%def op_nop():
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
+
+%def op_unused_3e():
+% unused()
+
+%def op_unused_3f():
+% unused()
+
+%def op_unused_40():
+% unused()
+
+%def op_unused_41():
+% unused()
+
+%def op_unused_42():
+% unused()
+
+%def op_unused_43():
+% unused()
+
+%def op_unused_79():
+% unused()
+
+%def op_unused_7a():
+% unused()
+
+%def op_unused_f3():
+% unused()
+
+%def op_unused_f4():
+% unused()
+
+%def op_unused_f5():
+% unused()
+
+%def op_unused_f6():
+% unused()
+
+%def op_unused_f7():
+% unused()
+
+%def op_unused_f8():
+% unused()
+
+%def op_unused_f9():
+% unused()
+
+%def op_unused_fc():
+% unused()
+
+%def op_unused_fd():
+% unused()
diff --git a/runtime/interpreter/mterp/x86_64/shop2addr.S b/runtime/interpreter/mterp/x86_64/shop2addr.S
deleted file mode 100644
index d0d838b..0000000
--- a/runtime/interpreter/mterp/x86_64/shop2addr.S
+++ /dev/null
@@ -1,19 +0,0 @@
-%def shop2addr(wide="0", instr=""):
-/*
- * Generic 32-bit "shift/2addr" operation.
- */
- /* shift/2addr vA, vB */
- movl rINST, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %rcx # ecx <- vBB
- andb $$0xf, rINSTbl # rINST <- A
- .if $wide
- GET_WIDE_VREG %rax, rINSTq # rax <- vAA
- $instr # ex: sarl %cl, %eax
- SET_WIDE_VREG %rax, rINSTq
- .else
- GET_VREG %eax, rINSTq # eax <- vAA
- $instr # ex: sarl %cl, %eax
- SET_VREG %eax, rINSTq
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/sseBinop.S b/runtime/interpreter/mterp/x86_64/sseBinop.S
deleted file mode 100644
index 638ea8e..0000000
--- a/runtime/interpreter/mterp/x86_64/sseBinop.S
+++ /dev/null
@@ -1,9 +0,0 @@
-%def sseBinop(instr="", suff=""):
- movzbq 2(rPC), %rcx # ecx <- BB
- movzbq 3(rPC), %rax # eax <- CC
- movs${suff} VREG_ADDRESS(%rcx), %xmm0 # %xmm0 <- 1st src
- ${instr}${suff} VREG_ADDRESS(%rax), %xmm0
- movs${suff} %xmm0, VREG_ADDRESS(rINSTq) # vAA <- %xmm0
- pxor %xmm0, %xmm0
- movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/sseBinop2Addr.S b/runtime/interpreter/mterp/x86_64/sseBinop2Addr.S
deleted file mode 100644
index 1292a36..0000000
--- a/runtime/interpreter/mterp/x86_64/sseBinop2Addr.S
+++ /dev/null
@@ -1,10 +0,0 @@
-%def sseBinop2Addr(instr="", suff=""):
- movl rINST, %ecx # ecx <- A+
- andl $$0xf, %ecx # ecx <- A
- movs${suff} VREG_ADDRESS(%rcx), %xmm0 # %xmm0 <- 1st src
- sarl $$4, rINST # rINST<- B
- ${instr}${suff} VREG_ADDRESS(rINSTq), %xmm0
- movs${suff} %xmm0, VREG_ADDRESS(%rcx) # vAA<- %xmm0
- pxor %xmm0, %xmm0
- movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/unop.S b/runtime/interpreter/mterp/x86_64/unop.S
deleted file mode 100644
index 1dd12a3..0000000
--- a/runtime/interpreter/mterp/x86_64/unop.S
+++ /dev/null
@@ -1,22 +0,0 @@
-%def unop(preinstr="", instr="", wide="0"):
-/*
- * Generic 32/64-bit unary operation. Provide an "instr" line that
- * specifies an instruction that performs "result = op eax".
- */
- /* unop vA, vB */
- movl rINST, %ecx # rcx <- A+
- sarl $$4,rINST # rINST <- B
- .if ${wide}
- GET_WIDE_VREG %rax, rINSTq # rax <- vB
- .else
- GET_VREG %eax, rINSTq # eax <- vB
- .endif
- andb $$0xf,%cl # ecx <- A
-$preinstr
-$instr
- .if ${wide}
- SET_WIDE_VREG %rax, %rcx
- .else
- SET_VREG %eax, %rcx
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
diff --git a/runtime/interpreter/mterp/x86_64/unused.S b/runtime/interpreter/mterp/x86_64/unused.S
deleted file mode 100644
index ef35b6e..0000000
--- a/runtime/interpreter/mterp/x86_64/unused.S
+++ /dev/null
@@ -1,5 +0,0 @@
-%def unused():
-/*
- * Bail to reference interpreter to throw.
- */
- jmp MterpFallback
diff --git a/runtime/interpreter/mterp/x86_64/zcmp.S b/runtime/interpreter/mterp/x86_64/zcmp.S
deleted file mode 100644
index e794fb0..0000000
--- a/runtime/interpreter/mterp/x86_64/zcmp.S
+++ /dev/null
@@ -1,18 +0,0 @@
-%def zcmp(revcmp=""):
-/*
- * Generic one-operand compare-and-branch operation. Provide a "revcmp"
- * fragment that specifies the *reverse* comparison to perform, e.g.
- * for "if-le" you would use "gt".
- *
- * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
- */
- /* if-cmp vAA, +BBBB */
- cmpl $$0, VREG_ADDRESS(rINSTq) # compare (vA, 0)
- j${revcmp} 1f
- movswq 2(rPC), rINSTq # fetch signed displacement
- testq rINSTq, rINSTq
- jmp MterpCommonTakenBranch
-1:
- cmpl $$JIT_CHECK_OSR, rPROFILE
- je .L_check_not_taken_osr
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2