1%default {"preinstr":"", "instr":"add x0, x1, x2", "result":"x0", "r1":"x1", "r2":"x2", "chkzero":"0"} 2 /* 3 * Generic 64-bit binary operation. Provide an "instr" line that 4 * specifies an instruction that performs "result = x1 op x2". 5 * This could be an ARM instruction or a function call. (If the result 6 * comes back in a register other than x0, you can override "result".) 7 * 8 * If "chkzero" is set to 1, we perform a divide-by-zero check on 9 * vCC (w1). Useful for integer division and modulus. 10 * 11 * For: add-long, sub-long, mul-long, div-long, rem-long, and-long, or-long, 12 * xor-long, add-double, sub-double, mul-double, div-double, rem-double 13 */ 14 /* binop vAA, vBB, vCC */ 15 FETCH w0, 1 // w0<- CCBB 16 lsr w4, wINST, #8 // w4<- AA 17 lsr w2, w0, #8 // w2<- CC 18 and w1, w0, #255 // w1<- BB 19 GET_VREG_WIDE $r2, w2 // w2<- vCC 20 GET_VREG_WIDE $r1, w1 // w1<- vBB 21 .if $chkzero 22 cbz $r2, common_errDivideByZero // is second operand zero? 23 .endif 24 FETCH_ADVANCE_INST 2 // advance rPC, load rINST 25 $preinstr 26 $instr // $result<- op, w0-w4 changed 27 GET_INST_OPCODE ip // extract opcode from rINST 28 SET_VREG_WIDE $result, w4 // vAA<- $result 29 GOTO_OPCODE ip // jump to next instruction 30 /* 11-14 instructions */ 31