1%default {"preinstr":"", "result":"w0", "chkzero":"0"} 2 /* 3 * Generic 32-bit binary operation. Provide an "instr" line that 4 * specifies an instruction that performs "result = w0 op w1". 5 * This could be an ARM instruction or a function call. (If the result 6 * comes back in a register other than w0, 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. Note that we 10 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 11 * handles it correctly. 12 * 13 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 14 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 15 * mul-float, div-float, rem-float 16 */ 17 /* binop vAA, vBB, vCC */ 18 FETCH w0, 1 // w0<- CCBB 19 lsr w9, wINST, #8 // w9<- AA 20 lsr w3, w0, #8 // w3<- CC 21 and w2, w0, #255 // w2<- BB 22 GET_VREG w1, w3 // w1<- vCC 23 GET_VREG w0, w2 // w0<- vBB 24 .if $chkzero 25 cbz w1, common_errDivideByZero // is second operand zero? 26 .endif 27 FETCH_ADVANCE_INST 2 // advance rPC, load rINST 28 $preinstr // optional op; may set condition codes 29 $instr // $result<- op, w0-w3 changed 30 GET_INST_OPCODE ip // extract opcode from rINST 31 SET_VREG $result, w9 // vAA<- $result 32 GOTO_OPCODE ip // jump to next instruction 33 /* 11-14 instructions */ 34