1*795d594fSAndroid Build Coastguard Worker%def fbinop(instr=""): 2*795d594fSAndroid Build Coastguard Worker /* 3*795d594fSAndroid Build Coastguard Worker * Generic 32-bit floating-point operation. 4*795d594fSAndroid Build Coastguard Worker * 5*795d594fSAndroid Build Coastguard Worker * For: add-float, sub-float, mul-float, div-float 6*795d594fSAndroid Build Coastguard Worker * form: <op> s0, s0, s1 7*795d594fSAndroid Build Coastguard Worker */ 8*795d594fSAndroid Build Coastguard Worker /* floatop vAA, vBB, vCC */ 9*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // r0<- CCBB 10*795d594fSAndroid Build Coastguard Worker lsr w1, w0, #8 // r2<- CC 11*795d594fSAndroid Build Coastguard Worker and w0, w0, #255 // r1<- BB 12*795d594fSAndroid Build Coastguard Worker GET_VREG s1, w1 13*795d594fSAndroid Build Coastguard Worker GET_VREG s0, w0 14*795d594fSAndroid Build Coastguard Worker $instr // s0<- op 15*795d594fSAndroid Build Coastguard Worker lsr w1, wINST, #8 // r1<- AA 16*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance rPC, load rINST 17*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 18*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s0, w1 19*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Worker%def fbinopWide(instr="fadd d0, d1, d2", result="d0", r1="d1", r2="d2"): 22*795d594fSAndroid Build Coastguard Worker /* 23*795d594fSAndroid Build Coastguard Worker * Generic 64-bit floating-point operation. 24*795d594fSAndroid Build Coastguard Worker */ 25*795d594fSAndroid Build Coastguard Worker /* binop vAA, vBB, vCC */ 26*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // w0<- CCBB 27*795d594fSAndroid Build Coastguard Worker lsr w4, wINST, #8 // w4<- AA 28*795d594fSAndroid Build Coastguard Worker lsr w2, w0, #8 // w2<- CC 29*795d594fSAndroid Build Coastguard Worker and w1, w0, #255 // w1<- BB 30*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $r2, w2 // w2<- vCC 31*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $r1, w1 // w1<- vBB 32*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance rPC, load rINST 33*795d594fSAndroid Build Coastguard Worker $instr // $result<- op, w0-w4 changed 34*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 35*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE $result, w4 // vAA<- $result 36*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker%def fbinop2addr(instr=""): 39*795d594fSAndroid Build Coastguard Worker /* 40*795d594fSAndroid Build Coastguard Worker * Generic 32-bit floating point "/2addr" binary operation. Provide 41*795d594fSAndroid Build Coastguard Worker * an "instr" line that specifies an instruction that performs 42*795d594fSAndroid Build Coastguard Worker * "s2 = s0 op s1". 43*795d594fSAndroid Build Coastguard Worker * 44*795d594fSAndroid Build Coastguard Worker * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 45*795d594fSAndroid Build Coastguard Worker */ 46*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 47*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 48*795d594fSAndroid Build Coastguard Worker ubfx w9, wINST, #8, #4 // w9<- A 49*795d594fSAndroid Build Coastguard Worker GET_VREG s1, w3 50*795d594fSAndroid Build Coastguard Worker GET_VREG s0, w9 51*795d594fSAndroid Build Coastguard Worker $instr // s2<- op 52*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load rINST 53*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 54*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s2, w9 55*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker%def fbinopWide2addr(instr="fadd d0, d0, d1", r0="d0", r1="d1"): 58*795d594fSAndroid Build Coastguard Worker /* 59*795d594fSAndroid Build Coastguard Worker * Generic 64-bit floating point "/2addr" binary operation. 60*795d594fSAndroid Build Coastguard Worker */ 61*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 62*795d594fSAndroid Build Coastguard Worker lsr w1, wINST, #12 // w1<- B 63*795d594fSAndroid Build Coastguard Worker ubfx w2, wINST, #8, #4 // w2<- A 64*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $r1, w1 // x1<- vB 65*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $r0, w2 // x0<- vA 66*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load rINST 67*795d594fSAndroid Build Coastguard Worker $instr // result<- op 68*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 69*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE $r0, w2 // vAA<- result 70*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker%def fcmp(r1="s1", r2="s2", cond="lt"): 73*795d594fSAndroid Build Coastguard Worker /* 74*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values. Puts 0, 1, or -1 into the 75*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison. 76*795d594fSAndroid Build Coastguard Worker */ 77*795d594fSAndroid Build Coastguard Worker /* op vAA, vBB, vCC */ 78*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // w0<- CCBB 79*795d594fSAndroid Build Coastguard Worker% if r1.startswith("d"): 80*795d594fSAndroid Build Coastguard Worker LOAD_SCALED_VREG_MASK w5, 0xff // w4<- ff * sizeof(vreg) 81*795d594fSAndroid Build Coastguard Worker lsr w4, wINST, #8 // w4<- AA 82*795d594fSAndroid Build Coastguard Worker EXTRACT_SCALED_VREG w2, w5, w0, 0 // w2<- BB * sizeof(vreg) 83*795d594fSAndroid Build Coastguard Worker EXTRACT_SCALED_VREG w3, w5, w0, 8 // w3<- CC * sizeof(vreg) 84*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_PRESCALED $r1, w2 85*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_PRESCALED $r2, w3 86*795d594fSAndroid Build Coastguard Worker% else: 87*795d594fSAndroid Build Coastguard Worker lsr w4, wINST, #8 // w4<- AA 88*795d594fSAndroid Build Coastguard Worker and w2, w0, #255 // w2<- BB 89*795d594fSAndroid Build Coastguard Worker lsr w3, w0, #8 // w3<- CC 90*795d594fSAndroid Build Coastguard Worker GET_VREG $r1, w2 91*795d594fSAndroid Build Coastguard Worker GET_VREG $r2, w3 92*795d594fSAndroid Build Coastguard Worker% #endif 93*795d594fSAndroid Build Coastguard Worker fcmp $r1, $r2 94*795d594fSAndroid Build Coastguard Worker cset w0, ne 95*795d594fSAndroid Build Coastguard Worker cneg w0, w0, $cond 96*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance rPC, load rINST 97*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 98*795d594fSAndroid Build Coastguard Worker SET_VREG w0, w4 // vAA<- w0 99*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker%def funopNarrow(srcreg="s0", tgtreg="d0", instr=""): 102*795d594fSAndroid Build Coastguard Worker /* 103*795d594fSAndroid Build Coastguard Worker * Generic 32bit-to-32bit floating point unary operation. Provide an 104*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg". 105*795d594fSAndroid Build Coastguard Worker * 106*795d594fSAndroid Build Coastguard Worker * For: int-to-float, float-to-int 107*795d594fSAndroid Build Coastguard Worker * TODO: refactor all of the conversions - parameterize width and use same template. 108*795d594fSAndroid Build Coastguard Worker */ 109*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 110*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 111*795d594fSAndroid Build Coastguard Worker ubfx w4, wINST, #8, #4 // w4<- A 112*795d594fSAndroid Build Coastguard Worker GET_VREG $srcreg, w3 113*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load wINST 114*795d594fSAndroid Build Coastguard Worker $instr // d0<- op 115*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 116*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT $tgtreg, w4 // vA<- d0 117*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker%def funopNarrower(srcreg="s0", tgtreg="d0", instr=""): 120*795d594fSAndroid Build Coastguard Worker /* 121*795d594fSAndroid Build Coastguard Worker * Generic 64bit-to-32bit floating point unary operation. Provide an 122*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg". 123*795d594fSAndroid Build Coastguard Worker * 124*795d594fSAndroid Build Coastguard Worker * For: int-to-double, float-to-double, float-to-long 125*795d594fSAndroid Build Coastguard Worker */ 126*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 127*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 128*795d594fSAndroid Build Coastguard Worker ubfx w4, wINST, #8, #4 // w4<- A 129*795d594fSAndroid Build Coastguard Worker% if srcreg.startswith("d"): 130*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $srcreg, w3 131*795d594fSAndroid Build Coastguard Worker% else: 132*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE $srcreg, w3 133*795d594fSAndroid Build Coastguard Worker% #endif 134*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load wINST 135*795d594fSAndroid Build Coastguard Worker $instr // d0<- op 136*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 137*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT $tgtreg, w4 // vA<- d0 138*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker%def funopWide(srcreg="s0", tgtreg="d0", instr=""): 141*795d594fSAndroid Build Coastguard Worker /* 142*795d594fSAndroid Build Coastguard Worker * Generic 64bit-to-64bit floating point unary operation. Provide an 143*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg". 144*795d594fSAndroid Build Coastguard Worker * 145*795d594fSAndroid Build Coastguard Worker * For: long-to-double, double-to-long 146*795d594fSAndroid Build Coastguard Worker */ 147*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 148*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 149*795d594fSAndroid Build Coastguard Worker ubfx w4, wINST, #8, #4 // w4<- A 150*795d594fSAndroid Build Coastguard Worker% if srcreg.startswith("d"): 151*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE $srcreg, w3 152*795d594fSAndroid Build Coastguard Worker% else: 153*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE $srcreg, w3 154*795d594fSAndroid Build Coastguard Worker% #endif 155*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load wINST 156*795d594fSAndroid Build Coastguard Worker $instr // d0<- op 157*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 158*795d594fSAndroid Build Coastguard Worker% if tgtreg.startswith("d"): 159*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE $tgtreg, w4 // vA<- d0 160*795d594fSAndroid Build Coastguard Worker% else: 161*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE $tgtreg, w4 // vA<- d0 162*795d594fSAndroid Build Coastguard Worker% #endif 163*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker%def funopWider(srcreg="s0", tgtreg="d0", instr=""): 166*795d594fSAndroid Build Coastguard Worker /* 167*795d594fSAndroid Build Coastguard Worker * Generic 32bit-to-64bit floating point unary operation. Provide an 168*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "$tgtreg = op $srcreg". 169*795d594fSAndroid Build Coastguard Worker * 170*795d594fSAndroid Build Coastguard Worker * For: int-to-double, float-to-double, float-to-long 171*795d594fSAndroid Build Coastguard Worker */ 172*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 173*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 174*795d594fSAndroid Build Coastguard Worker ubfx w4, wINST, #8, #4 // w4<- A 175*795d594fSAndroid Build Coastguard Worker GET_VREG $srcreg, w3 176*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load wINST 177*795d594fSAndroid Build Coastguard Worker $instr // d0<- op 178*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 179*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE $tgtreg, w4 // vA<- d0 180*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 181*795d594fSAndroid Build Coastguard Worker 182*795d594fSAndroid Build Coastguard Worker%def op_add_double(): 183*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fadd d0, d1, d2", result="d0", r1="d1", r2="d2") 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker%def op_add_double_2addr(): 186*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fadd d0, d0, d1", r0="d0", r1="d1") 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker%def op_add_float(): 189*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fadd s0, s0, s1") 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker%def op_add_float_2addr(): 192*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fadd s2, s0, s1") 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker%def op_cmpg_double(): 195*795d594fSAndroid Build Coastguard Worker% fcmp(r1="d1", r2="d2", cond="cc") 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker%def op_cmpg_float(): 198*795d594fSAndroid Build Coastguard Worker% fcmp(r1="s1", r2="s2", cond="cc") 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker%def op_cmpl_double(): 201*795d594fSAndroid Build Coastguard Worker% fcmp(r1="d1", r2="d2", cond="lt") 202*795d594fSAndroid Build Coastguard Worker 203*795d594fSAndroid Build Coastguard Worker%def op_cmpl_float(): 204*795d594fSAndroid Build Coastguard Worker% fcmp(r1="s1", r2="s2", cond="lt") 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker%def op_div_double(): 207*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fdiv d0, d1, d2", result="d0", r1="d1", r2="d2") 208*795d594fSAndroid Build Coastguard Worker 209*795d594fSAndroid Build Coastguard Worker%def op_div_double_2addr(): 210*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fdiv d0, d0, d1", r0="d0", r1="d1") 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker%def op_div_float(): 213*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fdiv s0, s0, s1") 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker%def op_div_float_2addr(): 216*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fdiv s2, s0, s1") 217*795d594fSAndroid Build Coastguard Worker 218*795d594fSAndroid Build Coastguard Worker%def op_double_to_float(): 219*795d594fSAndroid Build Coastguard Worker% funopNarrower(instr="fcvt s0, d0", srcreg="d0", tgtreg="s0") 220*795d594fSAndroid Build Coastguard Worker 221*795d594fSAndroid Build Coastguard Worker%def op_double_to_int(): 222*795d594fSAndroid Build Coastguard Worker% funopNarrower(instr="fcvtzs w0, d0", srcreg="d0", tgtreg="w0") 223*795d594fSAndroid Build Coastguard Worker 224*795d594fSAndroid Build Coastguard Worker%def op_double_to_long(): 225*795d594fSAndroid Build Coastguard Worker% funopWide(instr="fcvtzs x0, d0", srcreg="d0", tgtreg="x0") 226*795d594fSAndroid Build Coastguard Worker 227*795d594fSAndroid Build Coastguard Worker%def op_float_to_double(): 228*795d594fSAndroid Build Coastguard Worker% funopWider(instr="fcvt d0, s0", srcreg="s0", tgtreg="d0") 229*795d594fSAndroid Build Coastguard Worker 230*795d594fSAndroid Build Coastguard Worker%def op_float_to_int(): 231*795d594fSAndroid Build Coastguard Worker% funopNarrow(instr="fcvtzs w0, s0", srcreg="s0", tgtreg="w0") 232*795d594fSAndroid Build Coastguard Worker 233*795d594fSAndroid Build Coastguard Worker%def op_float_to_long(): 234*795d594fSAndroid Build Coastguard Worker% funopWider(instr="fcvtzs x0, s0", srcreg="s0", tgtreg="x0") 235*795d594fSAndroid Build Coastguard Worker 236*795d594fSAndroid Build Coastguard Worker%def op_int_to_double(): 237*795d594fSAndroid Build Coastguard Worker% funopWider(instr="scvtf d0, w0", srcreg="w0", tgtreg="d0") 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker%def op_int_to_float(): 240*795d594fSAndroid Build Coastguard Worker% funopNarrow(instr="scvtf s0, w0", srcreg="w0", tgtreg="s0") 241*795d594fSAndroid Build Coastguard Worker 242*795d594fSAndroid Build Coastguard Worker%def op_long_to_double(): 243*795d594fSAndroid Build Coastguard Worker% funopWide(instr="scvtf d0, x0", srcreg="x0", tgtreg="d0") 244*795d594fSAndroid Build Coastguard Worker 245*795d594fSAndroid Build Coastguard Worker%def op_long_to_float(): 246*795d594fSAndroid Build Coastguard Worker% funopNarrower(instr="scvtf s0, x0", srcreg="x0", tgtreg="s0") 247*795d594fSAndroid Build Coastguard Worker 248*795d594fSAndroid Build Coastguard Worker%def op_mul_double(): 249*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fmul d0, d1, d2", result="d0", r1="d1", r2="d2") 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker%def op_mul_double_2addr(): 252*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fmul d0, d0, d1", r0="d0", r1="d1") 253*795d594fSAndroid Build Coastguard Worker 254*795d594fSAndroid Build Coastguard Worker%def op_mul_float(): 255*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fmul s0, s0, s1") 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker%def op_mul_float_2addr(): 258*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fmul s2, s0, s1") 259*795d594fSAndroid Build Coastguard Worker 260*795d594fSAndroid Build Coastguard Worker%def op_neg_double(): 261*795d594fSAndroid Build Coastguard Worker% unopWide(instr="eor x0, x0, #0x8000000000000000") 262*795d594fSAndroid Build Coastguard Worker 263*795d594fSAndroid Build Coastguard Worker%def op_neg_float(): 264*795d594fSAndroid Build Coastguard Worker% unop(instr="eor w0, w0, #0x80000000") 265*795d594fSAndroid Build Coastguard Worker 266*795d594fSAndroid Build Coastguard Worker%def op_rem_double(): 267*795d594fSAndroid Build Coastguard Worker /* rem vAA, vBB, vCC */ 268*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // w0<- CCBB 269*795d594fSAndroid Build Coastguard Worker lsr w2, w0, #8 // w2<- CC 270*795d594fSAndroid Build Coastguard Worker and w1, w0, #255 // w1<- BB 271*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE d1, w2 // d1<- vCC 272*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE d0, w1 // d0<- vBB 273*795d594fSAndroid Build Coastguard Worker bl fmod 274*795d594fSAndroid Build Coastguard Worker lsr w4, wINST, #8 // w4<- AA 275*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance rPC, load rINST 276*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 277*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE d0, w4 // vAA<- result 278*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 279*795d594fSAndroid Build Coastguard Worker /* 11-14 instructions */ 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker%def op_rem_double_2addr(): 282*795d594fSAndroid Build Coastguard Worker /* rem vA, vB */ 283*795d594fSAndroid Build Coastguard Worker lsr w1, wINST, #12 // w1<- B 284*795d594fSAndroid Build Coastguard Worker ubfx w2, wINST, #8, #4 // w2<- A 285*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE d1, w1 // d1<- vB 286*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE d0, w2 // d0<- vA 287*795d594fSAndroid Build Coastguard Worker bl fmod 288*795d594fSAndroid Build Coastguard Worker ubfx w2, wINST, #8, #4 // w2<- A (need to reload - killed across call) 289*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load rINST 290*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 291*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE d0, w2 // vAA<- result 292*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 293*795d594fSAndroid Build Coastguard Worker /* 10-13 instructions */ 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker%def op_rem_float(): 296*795d594fSAndroid Build Coastguard Worker/* EABI doesn't define a float remainder function, but libm does */ 297*795d594fSAndroid Build Coastguard Worker% fbinop(instr="bl fmodf") 298*795d594fSAndroid Build Coastguard Worker 299*795d594fSAndroid Build Coastguard Worker%def op_rem_float_2addr(): 300*795d594fSAndroid Build Coastguard Worker /* rem vA, vB */ 301*795d594fSAndroid Build Coastguard Worker lsr w3, wINST, #12 // w3<- B 302*795d594fSAndroid Build Coastguard Worker ubfx w9, wINST, #8, #4 // w9<- A 303*795d594fSAndroid Build Coastguard Worker GET_VREG s1, w3 304*795d594fSAndroid Build Coastguard Worker GET_VREG s0, w9 305*795d594fSAndroid Build Coastguard Worker bl fmodf 306*795d594fSAndroid Build Coastguard Worker ubfx w9, wINST, #8, #4 // w9<- A 307*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance rPC, load rINST 308*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from rINST 309*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s0, w9 310*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker%def op_sub_double(): 313*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fsub d0, d1, d2", result="d0", r1="d1", r2="d2") 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker%def op_sub_double_2addr(): 316*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fsub d0, d0, d1", r0="d0", r1="d1") 317*795d594fSAndroid Build Coastguard Worker 318*795d594fSAndroid Build Coastguard Worker%def op_sub_float(): 319*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fsub s0, s0, s1") 320*795d594fSAndroid Build Coastguard Worker 321*795d594fSAndroid Build Coastguard Worker%def op_sub_float_2addr(): 322*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fsub s2, s0, s1") 323