1*795d594fSAndroid Build Coastguard Worker%def fbinop(instr=""): 2*795d594fSAndroid Build Coastguard Worker /* 3*795d594fSAndroid Build Coastguard Worker * Generic 32-bit floating-point operation. Provide an "instr" line that 4*795d594fSAndroid Build Coastguard Worker * specifies an instruction that performs "s2 = s0 op s1". Because we 5*795d594fSAndroid Build Coastguard Worker * use the "softfp" ABI, this must be an instruction, not a function call. 6*795d594fSAndroid Build Coastguard Worker * 7*795d594fSAndroid Build Coastguard Worker * For: add-float, sub-float, mul-float, div-float 8*795d594fSAndroid Build Coastguard Worker */ 9*795d594fSAndroid Build Coastguard Worker /* floatop vAA, vBB, vCC */ 10*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 11*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 12*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 13*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 14*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 15*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 16*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s1, r3 @ s1<- vCC 17*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r2 @ s0<- vBB 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 20*795d594fSAndroid Build Coastguard Worker $instr @ s2<- op 21*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 22*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s2, r4, lr @ vAA<- s2 23*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker%def fbinop2addr(instr=""): 26*795d594fSAndroid Build Coastguard Worker /* 27*795d594fSAndroid Build Coastguard Worker * Generic 32-bit floating point "/2addr" binary operation. Provide 28*795d594fSAndroid Build Coastguard Worker * an "instr" line that specifies an instruction that performs 29*795d594fSAndroid Build Coastguard Worker * "s2 = s0 op s1". 30*795d594fSAndroid Build Coastguard Worker * 31*795d594fSAndroid Build Coastguard Worker * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 32*795d594fSAndroid Build Coastguard Worker */ 33*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 34*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 35*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 36*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB 37*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 @ r4<- &vA 38*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s1, r3 @ s1<- vB 39*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 40*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r4 @ s0<- vA 41*795d594fSAndroid Build Coastguard Worker $instr @ s2<- op 42*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 43*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT_BY_ADDR s2, r4 @ vAA<- s2 No need to clear as it's 2addr 44*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker%def fbinopWide(instr=""): 47*795d594fSAndroid Build Coastguard Worker /* 48*795d594fSAndroid Build Coastguard Worker * Generic 64-bit double-precision floating point binary operation. 49*795d594fSAndroid Build Coastguard Worker * Provide an "instr" line that specifies an instruction that performs 50*795d594fSAndroid Build Coastguard Worker * "d2 = d0 op d1". 51*795d594fSAndroid Build Coastguard Worker * 52*795d594fSAndroid Build Coastguard Worker * for: add-double, sub-double, mul-double, div-double 53*795d594fSAndroid Build Coastguard Worker */ 54*795d594fSAndroid Build Coastguard Worker /* doubleop vAA, vBB, vCC */ 55*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 56*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 57*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 58*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 59*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 60*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 61*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d1, r3 @ d1<- vCC 62*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r2 @ d0<- vBB 63*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 64*795d594fSAndroid Build Coastguard Worker $instr @ d2<- op 65*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r4, ip, lr @ Zero shadow regs 66*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 67*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 @ r4<- &vAA 68*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE_BY_ADDR d2, r4 @ vAA<- d2 69*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker%def fbinopWide2addr(instr=""): 72*795d594fSAndroid Build Coastguard Worker /* 73*795d594fSAndroid Build Coastguard Worker * Generic 64-bit floating point "/2addr" binary operation. Provide 74*795d594fSAndroid Build Coastguard Worker * an "instr" line that specifies an instruction that performs 75*795d594fSAndroid Build Coastguard Worker * "d2 = d0 op d1". 76*795d594fSAndroid Build Coastguard Worker * 77*795d594fSAndroid Build Coastguard Worker * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 78*795d594fSAndroid Build Coastguard Worker * div-double/2addr 79*795d594fSAndroid Build Coastguard Worker */ 80*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 81*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 82*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 83*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB 84*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r4, ip, r0 @ Zero out shadow regs 85*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d1, r3 @ d1<- vB 86*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 @ r4<- &vA 87*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 88*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r4 @ d0<- vA 89*795d594fSAndroid Build Coastguard Worker $instr @ d2<- op 90*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 91*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE_BY_ADDR d2, r4 @ vAA<- d2 92*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker%def funop(instr=""): 95*795d594fSAndroid Build Coastguard Worker /* 96*795d594fSAndroid Build Coastguard Worker * Generic 32-bit unary floating-point operation. Provide an "instr" 97*795d594fSAndroid Build Coastguard Worker * line that specifies an instruction that performs "s1 = op s0". 98*795d594fSAndroid Build Coastguard Worker * 99*795d594fSAndroid Build Coastguard Worker * for: int-to-float, float-to-int 100*795d594fSAndroid Build Coastguard Worker */ 101*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 102*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 103*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB 104*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r3 @ s0<- vB 105*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 106*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 107*795d594fSAndroid Build Coastguard Worker $instr @ s1<- op 108*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 109*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s1, r4, lr @ vA<- s1 110*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker%def funopNarrower(instr=""): 113*795d594fSAndroid Build Coastguard Worker /* 114*795d594fSAndroid Build Coastguard Worker * Generic 64bit-to-32bit unary floating point operation. Provide an 115*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "s0 = op d0". 116*795d594fSAndroid Build Coastguard Worker * 117*795d594fSAndroid Build Coastguard Worker * For: double-to-int, double-to-float 118*795d594fSAndroid Build Coastguard Worker */ 119*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 120*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 121*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB 122*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r3 @ d0<- vB 123*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 124*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 125*795d594fSAndroid Build Coastguard Worker $instr @ s0<- op 126*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 127*795d594fSAndroid Build Coastguard Worker SET_VREG_FLOAT s0, r4, lr @ vA<- s0 128*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker%def funopWider(instr=""): 131*795d594fSAndroid Build Coastguard Worker /* 132*795d594fSAndroid Build Coastguard Worker * Generic 32bit-to-64bit floating point unary operation. Provide an 133*795d594fSAndroid Build Coastguard Worker * "instr" line that specifies an instruction that performs "d0 = op s0". 134*795d594fSAndroid Build Coastguard Worker * 135*795d594fSAndroid Build Coastguard Worker * For: int-to-double, float-to-double 136*795d594fSAndroid Build Coastguard Worker */ 137*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 138*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 139*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vB 140*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r3 @ s0<- vB 141*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 142*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 143*795d594fSAndroid Build Coastguard Worker $instr @ d0<- op 144*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r4, ip, lr @ Zero shadow regs 145*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 146*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 @ r4<- &vA 147*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE_BY_ADDR d0, r4 @ vA<- d0 148*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker%def op_add_double(): 151*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="faddd d2, d0, d1") 152*795d594fSAndroid Build Coastguard Worker 153*795d594fSAndroid Build Coastguard Worker%def op_add_double_2addr(): 154*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="faddd d2, d0, d1") 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker%def op_add_float(): 157*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fadds s2, s0, s1") 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker%def op_add_float_2addr(): 160*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fadds s2, s0, s1") 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker%def op_cmpg_double(): 163*795d594fSAndroid Build Coastguard Worker /* 164*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values. Puts 0, 1, or -1 into the 165*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison. 166*795d594fSAndroid Build Coastguard Worker * 167*795d594fSAndroid Build Coastguard Worker * int compare(x, y) { 168*795d594fSAndroid Build Coastguard Worker * if (x == y) { 169*795d594fSAndroid Build Coastguard Worker * return 0; 170*795d594fSAndroid Build Coastguard Worker * } else if (x < y) { 171*795d594fSAndroid Build Coastguard Worker * return -1; 172*795d594fSAndroid Build Coastguard Worker * } else if (x > y) { 173*795d594fSAndroid Build Coastguard Worker * return 1; 174*795d594fSAndroid Build Coastguard Worker * } else { 175*795d594fSAndroid Build Coastguard Worker * return 1; 176*795d594fSAndroid Build Coastguard Worker * } 177*795d594fSAndroid Build Coastguard Worker * } 178*795d594fSAndroid Build Coastguard Worker */ 179*795d594fSAndroid Build Coastguard Worker /* op vAA, vBB, vCC */ 180*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 181*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 182*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 183*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 184*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 185*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 186*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r2 @ d0<- vBB 187*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d1, r3 @ d1<- vCC 188*795d594fSAndroid Build Coastguard Worker vcmpe.f64 d0, d1 @ compare (vBB, vCC) 189*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 190*795d594fSAndroid Build Coastguard Worker mvn r0, #0 @ r0<- -1 (default) 191*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 192*795d594fSAndroid Build Coastguard Worker fmstat 193*795d594fSAndroid Build Coastguard Worker it hi 194*795d594fSAndroid Build Coastguard Worker movhi r0, #1 @ (greater than, or unordered) r0<- 1 195*795d594fSAndroid Build Coastguard Worker moveq r0, #0 @ (equal) r0<- 0 196*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r4 @ vAA<- r0 197*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 198*795d594fSAndroid Build Coastguard Worker 199*795d594fSAndroid Build Coastguard Worker%def op_cmpg_float(): 200*795d594fSAndroid Build Coastguard Worker /* 201*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values. Puts 0, 1, or -1 into the 202*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison. 203*795d594fSAndroid Build Coastguard Worker * 204*795d594fSAndroid Build Coastguard Worker * int compare(x, y) { 205*795d594fSAndroid Build Coastguard Worker * if (x == y) { 206*795d594fSAndroid Build Coastguard Worker * return 0; 207*795d594fSAndroid Build Coastguard Worker * } else if (x < y) { 208*795d594fSAndroid Build Coastguard Worker * return -1; 209*795d594fSAndroid Build Coastguard Worker * } else if (x > y) { 210*795d594fSAndroid Build Coastguard Worker * return 1; 211*795d594fSAndroid Build Coastguard Worker * } else { 212*795d594fSAndroid Build Coastguard Worker * return 1; 213*795d594fSAndroid Build Coastguard Worker * } 214*795d594fSAndroid Build Coastguard Worker * } 215*795d594fSAndroid Build Coastguard Worker */ 216*795d594fSAndroid Build Coastguard Worker /* op vAA, vBB, vCC */ 217*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 218*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 219*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 220*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 221*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 222*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 223*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r2 @ s0<- vBB 224*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s1, r3 @ s1<- vCC 225*795d594fSAndroid Build Coastguard Worker vcmpe.f32 s0, s1 @ compare (vBB, vCC) 226*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 227*795d594fSAndroid Build Coastguard Worker mvn r0, #0 @ r0<- -1 (default) 228*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 229*795d594fSAndroid Build Coastguard Worker fmstat 230*795d594fSAndroid Build Coastguard Worker it hi 231*795d594fSAndroid Build Coastguard Worker movhi r0, #1 @ (greater than, or unordered) r0<- 1 232*795d594fSAndroid Build Coastguard Worker moveq r0, #0 @ (equal) r0<- 0 233*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r4 @ vAA<- r0 234*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 235*795d594fSAndroid Build Coastguard Worker 236*795d594fSAndroid Build Coastguard Worker%def op_cmpl_double(): 237*795d594fSAndroid Build Coastguard Worker /* 238*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values. Puts 0, 1, or -1 into the 239*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison. 240*795d594fSAndroid Build Coastguard Worker * 241*795d594fSAndroid Build Coastguard Worker * int compare(x, y) { 242*795d594fSAndroid Build Coastguard Worker * if (x == y) { 243*795d594fSAndroid Build Coastguard Worker * return 0; 244*795d594fSAndroid Build Coastguard Worker * } else if (x > y) { 245*795d594fSAndroid Build Coastguard Worker * return 1; 246*795d594fSAndroid Build Coastguard Worker * } else if (x < y) { 247*795d594fSAndroid Build Coastguard Worker * return -1; 248*795d594fSAndroid Build Coastguard Worker * } else { 249*795d594fSAndroid Build Coastguard Worker * return -1; 250*795d594fSAndroid Build Coastguard Worker * } 251*795d594fSAndroid Build Coastguard Worker * } 252*795d594fSAndroid Build Coastguard Worker */ 253*795d594fSAndroid Build Coastguard Worker /* op vAA, vBB, vCC */ 254*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 255*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 256*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 257*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 258*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 259*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 260*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r2 @ d0<- vBB 261*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d1, r3 @ d1<- vCC 262*795d594fSAndroid Build Coastguard Worker vcmpe.f64 d0, d1 @ compare (vBB, vCC) 263*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 264*795d594fSAndroid Build Coastguard Worker mvn r0, #0 @ r0<- -1 (default) 265*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 266*795d594fSAndroid Build Coastguard Worker fmstat @ export status flags 267*795d594fSAndroid Build Coastguard Worker it gt 268*795d594fSAndroid Build Coastguard Worker movgt r0, #1 @ (greater than) r1<- 1 269*795d594fSAndroid Build Coastguard Worker it eq 270*795d594fSAndroid Build Coastguard Worker moveq r0, #0 @ (equal) r1<- 0 271*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r4 @ vAA<- r0 272*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker%def op_cmpl_float(): 275*795d594fSAndroid Build Coastguard Worker /* 276*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values. Puts 0, 1, or -1 into the 277*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison. 278*795d594fSAndroid Build Coastguard Worker * 279*795d594fSAndroid Build Coastguard Worker * int compare(x, y) { 280*795d594fSAndroid Build Coastguard Worker * if (x == y) { 281*795d594fSAndroid Build Coastguard Worker * return 0; 282*795d594fSAndroid Build Coastguard Worker * } else if (x > y) { 283*795d594fSAndroid Build Coastguard Worker * return 1; 284*795d594fSAndroid Build Coastguard Worker * } else if (x < y) { 285*795d594fSAndroid Build Coastguard Worker * return -1; 286*795d594fSAndroid Build Coastguard Worker * } else { 287*795d594fSAndroid Build Coastguard Worker * return -1; 288*795d594fSAndroid Build Coastguard Worker * } 289*795d594fSAndroid Build Coastguard Worker * } 290*795d594fSAndroid Build Coastguard Worker */ 291*795d594fSAndroid Build Coastguard Worker /* op vAA, vBB, vCC */ 292*795d594fSAndroid Build Coastguard Worker FETCH r0, 1 @ r0<- CCBB 293*795d594fSAndroid Build Coastguard Worker mov r4, rINST, lsr #8 @ r4<- AA 294*795d594fSAndroid Build Coastguard Worker and r2, r0, #255 @ r2<- BB 295*795d594fSAndroid Build Coastguard Worker mov r3, r0, lsr #8 @ r3<- CC 296*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r2, r2 @ r2<- &vBB 297*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &vCC 298*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s0, r2 @ s0<- vBB 299*795d594fSAndroid Build Coastguard Worker GET_VREG_FLOAT_BY_ADDR s1, r3 @ s1<- vCC 300*795d594fSAndroid Build Coastguard Worker vcmpe.f32 s0, s1 @ compare (vBB, vCC) 301*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 @ advance rPC, load rINST 302*795d594fSAndroid Build Coastguard Worker mvn r0, #0 @ r0<- -1 (default) 303*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 304*795d594fSAndroid Build Coastguard Worker fmstat @ export status flags 305*795d594fSAndroid Build Coastguard Worker it gt 306*795d594fSAndroid Build Coastguard Worker movgt r0, #1 @ (greater than) r1<- 1 307*795d594fSAndroid Build Coastguard Worker it eq 308*795d594fSAndroid Build Coastguard Worker moveq r0, #0 @ (equal) r1<- 0 309*795d594fSAndroid Build Coastguard Worker SET_VREG r0, r4 @ vAA<- r0 310*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker%def op_div_double(): 313*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fdivd d2, d0, d1") 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker%def op_div_double_2addr(): 316*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fdivd d2, d0, d1") 317*795d594fSAndroid Build Coastguard Worker 318*795d594fSAndroid Build Coastguard Worker%def op_div_float(): 319*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fdivs s2, s0, s1") 320*795d594fSAndroid Build Coastguard Worker 321*795d594fSAndroid Build Coastguard Worker%def op_div_float_2addr(): 322*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fdivs s2, s0, s1") 323*795d594fSAndroid Build Coastguard Worker 324*795d594fSAndroid Build Coastguard Worker%def op_double_to_float(): 325*795d594fSAndroid Build Coastguard Worker% funopNarrower(instr="vcvt.f32.f64 s0, d0") 326*795d594fSAndroid Build Coastguard Worker 327*795d594fSAndroid Build Coastguard Worker%def op_double_to_int(): 328*795d594fSAndroid Build Coastguard Worker% funopNarrower(instr="vcvt.s32.f64 s0, d0") 329*795d594fSAndroid Build Coastguard Worker 330*795d594fSAndroid Build Coastguard Worker%def op_double_to_long(): 331*795d594fSAndroid Build Coastguard Worker% unopWide(instr="bl nterp_d2l_doconv") 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker%def op_float_to_double(): 334*795d594fSAndroid Build Coastguard Worker% funopWider(instr="vcvt.f64.f32 d0, s0") 335*795d594fSAndroid Build Coastguard Worker 336*795d594fSAndroid Build Coastguard Worker%def op_float_to_int(): 337*795d594fSAndroid Build Coastguard Worker% funop(instr="vcvt.s32.f32 s1, s0") 338*795d594fSAndroid Build Coastguard Worker 339*795d594fSAndroid Build Coastguard Worker%def op_float_to_long(): 340*795d594fSAndroid Build Coastguard Worker% unopWider(instr="bl nterp_f2l_doconv") 341*795d594fSAndroid Build Coastguard Worker 342*795d594fSAndroid Build Coastguard Worker%def op_int_to_double(): 343*795d594fSAndroid Build Coastguard Worker% funopWider(instr="vcvt.f64.s32 d0, s0") 344*795d594fSAndroid Build Coastguard Worker 345*795d594fSAndroid Build Coastguard Worker%def op_int_to_float(): 346*795d594fSAndroid Build Coastguard Worker% funop(instr="vcvt.f32.s32 s1, s0") 347*795d594fSAndroid Build Coastguard Worker 348*795d594fSAndroid Build Coastguard Worker%def op_long_to_double(): 349*795d594fSAndroid Build Coastguard Worker /* 350*795d594fSAndroid Build Coastguard Worker * Specialised 64-bit floating point operation. 351*795d594fSAndroid Build Coastguard Worker * 352*795d594fSAndroid Build Coastguard Worker * Note: The result will be returned in d2. 353*795d594fSAndroid Build Coastguard Worker * 354*795d594fSAndroid Build Coastguard Worker * For: long-to-double 355*795d594fSAndroid Build Coastguard Worker */ 356*795d594fSAndroid Build Coastguard Worker mov r3, rINST, lsr #12 @ r3<- B 357*795d594fSAndroid Build Coastguard Worker ubfx r4, rINST, #8, #4 @ r4<- A 358*795d594fSAndroid Build Coastguard Worker CLEAR_SHADOW_PAIR r4, ip, lr @ Zero shadow regs 359*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r3, r3 @ r3<- &fp[B] 360*795d594fSAndroid Build Coastguard Worker VREG_INDEX_TO_ADDR r4, r4 @ r4<- &fp[A] 361*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE_BY_ADDR d0, r3 @ d0<- vBB 362*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 @ advance rPC, load rINST 363*795d594fSAndroid Build Coastguard Worker 364*795d594fSAndroid Build Coastguard Worker vcvt.f64.s32 d1, s1 @ d1<- (double)(vAAh) 365*795d594fSAndroid Build Coastguard Worker vcvt.f64.u32 d2, s0 @ d2<- (double)(vAAl) 366*795d594fSAndroid Build Coastguard Worker vldr d3, constval$opcode 367*795d594fSAndroid Build Coastguard Worker vmla.f64 d2, d1, d3 @ d2<- vAAh*2^32 + vAAl 368*795d594fSAndroid Build Coastguard Worker 369*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip @ extract opcode from rINST 370*795d594fSAndroid Build Coastguard Worker SET_VREG_DOUBLE_BY_ADDR d2, r4 @ vAA<- d2 371*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip @ jump to next instruction 372*795d594fSAndroid Build Coastguard Worker 373*795d594fSAndroid Build Coastguard Worker /* literal pool helper */ 374*795d594fSAndroid Build Coastguard Workerconstval${opcode}: 375*795d594fSAndroid Build Coastguard Worker .8byte 0x41f0000000000000 376*795d594fSAndroid Build Coastguard Worker 377*795d594fSAndroid Build Coastguard Worker%def op_long_to_float(): 378*795d594fSAndroid Build Coastguard Worker% unopNarrower(instr="bl __aeabi_l2f") 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker%def op_mul_double(): 381*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fmuld d2, d0, d1") 382*795d594fSAndroid Build Coastguard Worker 383*795d594fSAndroid Build Coastguard Worker%def op_mul_double_2addr(): 384*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fmuld d2, d0, d1") 385*795d594fSAndroid Build Coastguard Worker 386*795d594fSAndroid Build Coastguard Worker%def op_mul_float(): 387*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fmuls s2, s0, s1") 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker%def op_mul_float_2addr(): 390*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fmuls s2, s0, s1") 391*795d594fSAndroid Build Coastguard Worker 392*795d594fSAndroid Build Coastguard Worker%def op_neg_double(): 393*795d594fSAndroid Build Coastguard Worker% unopWide(instr="add r1, r1, #0x80000000") 394*795d594fSAndroid Build Coastguard Worker 395*795d594fSAndroid Build Coastguard Worker%def op_neg_float(): 396*795d594fSAndroid Build Coastguard Worker% unop(instr="add r0, r0, #0x80000000") 397*795d594fSAndroid Build Coastguard Worker 398*795d594fSAndroid Build Coastguard Worker%def op_rem_double(): 399*795d594fSAndroid Build Coastguard Worker/* EABI doesn't define a double remainder function, but libm does */ 400*795d594fSAndroid Build Coastguard Worker% binopWide(instr="bl fmod") 401*795d594fSAndroid Build Coastguard Worker 402*795d594fSAndroid Build Coastguard Worker%def op_rem_double_2addr(): 403*795d594fSAndroid Build Coastguard Worker/* EABI doesn't define a double remainder function, but libm does */ 404*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr="bl fmod") 405*795d594fSAndroid Build Coastguard Worker 406*795d594fSAndroid Build Coastguard Worker%def op_rem_float(): 407*795d594fSAndroid Build Coastguard Worker/* EABI doesn't define a float remainder function, but libm does */ 408*795d594fSAndroid Build Coastguard Worker% binop(instr="bl fmodf") 409*795d594fSAndroid Build Coastguard Worker 410*795d594fSAndroid Build Coastguard Worker%def op_rem_float_2addr(): 411*795d594fSAndroid Build Coastguard Worker/* EABI doesn't define a float remainder function, but libm does */ 412*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="bl fmodf") 413*795d594fSAndroid Build Coastguard Worker 414*795d594fSAndroid Build Coastguard Worker%def op_sub_double(): 415*795d594fSAndroid Build Coastguard Worker% fbinopWide(instr="fsubd d2, d0, d1") 416*795d594fSAndroid Build Coastguard Worker 417*795d594fSAndroid Build Coastguard Worker%def op_sub_double_2addr(): 418*795d594fSAndroid Build Coastguard Worker% fbinopWide2addr(instr="fsubd d2, d0, d1") 419*795d594fSAndroid Build Coastguard Worker 420*795d594fSAndroid Build Coastguard Worker%def op_sub_float(): 421*795d594fSAndroid Build Coastguard Worker% fbinop(instr="fsubs s2, s0, s1") 422*795d594fSAndroid Build Coastguard Worker 423*795d594fSAndroid Build Coastguard Worker%def op_sub_float_2addr(): 424*795d594fSAndroid Build Coastguard Worker% fbinop2addr(instr="fsubs s2, s0, s1") 425