diff options
Diffstat (limited to 'vm/mterp/arm-vfp')
34 files changed, 362 insertions, 0 deletions
diff --git a/vm/mterp/arm-vfp/OP_ADD_DOUBLE.S b/vm/mterp/arm-vfp/OP_ADD_DOUBLE.S new file mode 100644 index 0000000..5a5ad1d --- /dev/null +++ b/vm/mterp/arm-vfp/OP_ADD_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide.S" {"instr":"faddd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_ADD_DOUBLE_2ADDR.S b/vm/mterp/arm-vfp/OP_ADD_DOUBLE_2ADDR.S new file mode 100644 index 0000000..9823765 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_ADD_DOUBLE_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide2addr.S" {"instr":"faddd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_ADD_FLOAT.S b/vm/mterp/arm-vfp/OP_ADD_FLOAT.S new file mode 100644 index 0000000..22023ec --- /dev/null +++ b/vm/mterp/arm-vfp/OP_ADD_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop.S" {"instr":"fadds s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_ADD_FLOAT_2ADDR.S b/vm/mterp/arm-vfp/OP_ADD_FLOAT_2ADDR.S new file mode 100644 index 0000000..e787589 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_ADD_FLOAT_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop2addr.S" {"instr":"fadds s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_CMPG_DOUBLE.S b/vm/mterp/arm-vfp/OP_CMPG_DOUBLE.S new file mode 100644 index 0000000..b75216e --- /dev/null +++ b/vm/mterp/arm-vfp/OP_CMPG_DOUBLE.S @@ -0,0 +1,42 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * 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 + fcmped 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 + b .L${opcode}_finish @ argh + +%break +.L${opcode}_finish: + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction diff --git a/vm/mterp/arm-vfp/OP_CMPG_FLOAT.S b/vm/mterp/arm-vfp/OP_CMPG_FLOAT.S new file mode 100644 index 0000000..eade97d --- /dev/null +++ b/vm/mterp/arm-vfp/OP_CMPG_FLOAT.S @@ -0,0 +1,42 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * 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 + fcmpes 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 + b .L${opcode}_finish @ argh + +%break +.L${opcode}_finish: + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction diff --git a/vm/mterp/arm-vfp/OP_CMPL_DOUBLE.S b/vm/mterp/arm-vfp/OP_CMPL_DOUBLE.S new file mode 100644 index 0000000..6e85fe7 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_CMPL_DOUBLE.S @@ -0,0 +1,42 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * 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 + fcmped 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 + b .L${opcode}_finish @ argh + +%break +.L${opcode}_finish: + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction diff --git a/vm/mterp/arm-vfp/OP_CMPL_FLOAT.S b/vm/mterp/arm-vfp/OP_CMPL_FLOAT.S new file mode 100644 index 0000000..bdeb0be --- /dev/null +++ b/vm/mterp/arm-vfp/OP_CMPL_FLOAT.S @@ -0,0 +1,42 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * 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 + fcmpes 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 + b .L${opcode}_finish @ argh + +%break +.L${opcode}_finish: + SET_VREG(r0, r9) @ vAA<- r0 + GOTO_OPCODE(ip) @ jump to next instruction diff --git a/vm/mterp/arm-vfp/OP_DIV_DOUBLE.S b/vm/mterp/arm-vfp/OP_DIV_DOUBLE.S new file mode 100644 index 0000000..11770ad --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DIV_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide.S" {"instr":"fdivd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_DIV_DOUBLE_2ADDR.S b/vm/mterp/arm-vfp/OP_DIV_DOUBLE_2ADDR.S new file mode 100644 index 0000000..a52f434 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DIV_DOUBLE_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide2addr.S" {"instr":"fdivd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_DIV_FLOAT.S b/vm/mterp/arm-vfp/OP_DIV_FLOAT.S new file mode 100644 index 0000000..2e82ada --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DIV_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop.S" {"instr":"fdivs s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_DIV_FLOAT_2ADDR.S b/vm/mterp/arm-vfp/OP_DIV_FLOAT_2ADDR.S new file mode 100644 index 0000000..2147583 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DIV_FLOAT_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop2addr.S" {"instr":"fdivs s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_DOUBLE_TO_FLOAT.S b/vm/mterp/arm-vfp/OP_DOUBLE_TO_FLOAT.S new file mode 100644 index 0000000..33d5b61 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DOUBLE_TO_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funopNarrower.S" {"instr":"fcvtsd s0, d0"} diff --git a/vm/mterp/arm-vfp/OP_DOUBLE_TO_INT.S b/vm/mterp/arm-vfp/OP_DOUBLE_TO_INT.S new file mode 100644 index 0000000..2ef4838 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_DOUBLE_TO_INT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funopNarrower.S" {"instr":"ftosizd s0, d0"} diff --git a/vm/mterp/arm-vfp/OP_FLOAT_TO_DOUBLE.S b/vm/mterp/arm-vfp/OP_FLOAT_TO_DOUBLE.S new file mode 100644 index 0000000..0acb3d8 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_FLOAT_TO_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funopWider.S" {"instr":"fcvtds d0, s0"} diff --git a/vm/mterp/arm-vfp/OP_FLOAT_TO_INT.S b/vm/mterp/arm-vfp/OP_FLOAT_TO_INT.S new file mode 100644 index 0000000..d0a9a2e --- /dev/null +++ b/vm/mterp/arm-vfp/OP_FLOAT_TO_INT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funop.S" {"instr":"ftosizs s1, s0"} diff --git a/vm/mterp/arm-vfp/OP_INT_TO_DOUBLE.S b/vm/mterp/arm-vfp/OP_INT_TO_DOUBLE.S new file mode 100644 index 0000000..6eb430e --- /dev/null +++ b/vm/mterp/arm-vfp/OP_INT_TO_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funopWider.S" {"instr":"fsitod d0, s0"} diff --git a/vm/mterp/arm-vfp/OP_INT_TO_FLOAT.S b/vm/mterp/arm-vfp/OP_INT_TO_FLOAT.S new file mode 100644 index 0000000..698bdc7 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_INT_TO_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/funop.S" {"instr":"fsitos s1, s0"} diff --git a/vm/mterp/arm-vfp/OP_MUL_DOUBLE.S b/vm/mterp/arm-vfp/OP_MUL_DOUBLE.S new file mode 100644 index 0000000..7563191 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_MUL_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide.S" {"instr":"fmuld d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_MUL_DOUBLE_2ADDR.S b/vm/mterp/arm-vfp/OP_MUL_DOUBLE_2ADDR.S new file mode 100644 index 0000000..eadf101 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_MUL_DOUBLE_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide2addr.S" {"instr":"fmuld d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_MUL_FLOAT.S b/vm/mterp/arm-vfp/OP_MUL_FLOAT.S new file mode 100644 index 0000000..bb3ab42 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_MUL_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop.S" {"instr":"fmuls s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_MUL_FLOAT_2ADDR.S b/vm/mterp/arm-vfp/OP_MUL_FLOAT_2ADDR.S new file mode 100644 index 0000000..3918537 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_MUL_FLOAT_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop2addr.S" {"instr":"fmuls s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_SUB_DOUBLE.S b/vm/mterp/arm-vfp/OP_SUB_DOUBLE.S new file mode 100644 index 0000000..d40e083 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_SUB_DOUBLE.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide.S" {"instr":"fsubd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_SUB_DOUBLE_2ADDR.S b/vm/mterp/arm-vfp/OP_SUB_DOUBLE_2ADDR.S new file mode 100644 index 0000000..705124f --- /dev/null +++ b/vm/mterp/arm-vfp/OP_SUB_DOUBLE_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinopWide2addr.S" {"instr":"fsubd d2, d0, d1"} diff --git a/vm/mterp/arm-vfp/OP_SUB_FLOAT.S b/vm/mterp/arm-vfp/OP_SUB_FLOAT.S new file mode 100644 index 0000000..0bf2bc0 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_SUB_FLOAT.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop.S" {"instr":"fsubs s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/OP_SUB_FLOAT_2ADDR.S b/vm/mterp/arm-vfp/OP_SUB_FLOAT_2ADDR.S new file mode 100644 index 0000000..e214068 --- /dev/null +++ b/vm/mterp/arm-vfp/OP_SUB_FLOAT_2ADDR.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "arm-vfp/fbinop2addr.S" {"instr":"fsubs s2, s0, s1"} diff --git a/vm/mterp/arm-vfp/README.txt b/vm/mterp/arm-vfp/README.txt new file mode 100644 index 0000000..c94e1e8 --- /dev/null +++ b/vm/mterp/arm-vfp/README.txt @@ -0,0 +1,7 @@ +Instruction handlers that take advantage of ARM VFP. These work with VFP +v2 and v3 (VFPLite). + +The ARM code driving the floating-point calculations will run on ARMv5TE +and later. It assumes that word alignment is sufficient for double-word +accesses (which is true for some ARMv5 and all ARMv6/v7), to avoid having +to transfer double-precision values in two steps. diff --git a/vm/mterp/arm-vfp/fbinop.S b/vm/mterp/arm-vfp/fbinop.S new file mode 100644 index 0000000..ff9683e --- /dev/null +++ b/vm/mterp/arm-vfp/fbinop.S @@ -0,0 +1,23 @@ + /* + * 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/vm/mterp/arm-vfp/fbinop2addr.S b/vm/mterp/arm-vfp/fbinop2addr.S new file mode 100644 index 0000000..85b9fab --- /dev/null +++ b/vm/mterp/arm-vfp/fbinop2addr.S @@ -0,0 +1,21 @@ + /* + * 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 + mov r9, rINST, lsr #8 @ r9<- A+ + VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB + and r9, r9, #15 @ r9<- A + flds s1, [r3] @ s1<- vB + VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA + 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/vm/mterp/arm-vfp/fbinopWide.S b/vm/mterp/arm-vfp/fbinopWide.S new file mode 100644 index 0000000..2b9ad69 --- /dev/null +++ b/vm/mterp/arm-vfp/fbinopWide.S @@ -0,0 +1,23 @@ + /* + * 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 + 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/vm/mterp/arm-vfp/fbinopWide2addr.S b/vm/mterp/arm-vfp/fbinopWide2addr.S new file mode 100644 index 0000000..15d9424 --- /dev/null +++ b/vm/mterp/arm-vfp/fbinopWide2addr.S @@ -0,0 +1,22 @@ + /* + * 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 + mov r9, rINST, lsr #8 @ r9<- A+ + VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB + and r9, r9, #15 @ r9<- A + 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/vm/mterp/arm-vfp/funop.S b/vm/mterp/arm-vfp/funop.S new file mode 100644 index 0000000..a5846ce --- /dev/null +++ b/vm/mterp/arm-vfp/funop.S @@ -0,0 +1,18 @@ + /* + * 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 + mov r9, rINST, lsr #8 @ r9<- A+ + VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB + flds s0, [r3] @ s0<- vB + FETCH_ADVANCE_INST(1) @ advance rPC, load rINST + and r9, r9, #15 @ r9<- A + $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/vm/mterp/arm-vfp/funopNarrower.S b/vm/mterp/arm-vfp/funopNarrower.S new file mode 100644 index 0000000..7ae1676 --- /dev/null +++ b/vm/mterp/arm-vfp/funopNarrower.S @@ -0,0 +1,18 @@ + /* + * 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 + mov r9, rINST, lsr #8 @ r9<- A+ + VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB + fldd d0, [r3] @ d0<- vB + FETCH_ADVANCE_INST(1) @ advance rPC, load rINST + and r9, r9, #15 @ r9<- A + $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/vm/mterp/arm-vfp/funopWider.S b/vm/mterp/arm-vfp/funopWider.S new file mode 100644 index 0000000..055b851 --- /dev/null +++ b/vm/mterp/arm-vfp/funopWider.S @@ -0,0 +1,18 @@ + /* + * 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 + mov r9, rINST, lsr #8 @ r9<- A+ + VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB + flds s0, [r3] @ s0<- vB + FETCH_ADVANCE_INST(1) @ advance rPC, load rINST + and r9, r9, #15 @ r9<- A + $instr @ d0<- op + 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 |