1*795d594fSAndroid Build Coastguard Worker// 2*795d594fSAndroid Build Coastguard Worker// unop vA, vB 3*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|op 4*795d594fSAndroid Build Coastguard Worker// (see floating_point.S for float/double ops) 5*795d594fSAndroid Build Coastguard Worker// 6*795d594fSAndroid Build Coastguard Worker 7*795d594fSAndroid Build Coastguard Worker// neg-int vA, vB 8*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|7b 9*795d594fSAndroid Build Coastguard Worker%def op_neg_int(): 10*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="negw t1, t1") 11*795d594fSAndroid Build Coastguard Worker 12*795d594fSAndroid Build Coastguard Worker// not-int vA, vB 13*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|7c 14*795d594fSAndroid Build Coastguard Worker%def op_not_int(): 15*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="not t1, t1") 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker// neg-long vA, vB 18*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|7d 19*795d594fSAndroid Build Coastguard Worker%def op_neg_long(): 20*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="neg t1, t1", is_wide=True) 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker// not-long vA, vB 23*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|7e 24*795d594fSAndroid Build Coastguard Worker%def op_not_long(): 25*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="not t1, t1", is_wide=True) 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker// int-to-long vA, vB 28*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|81 29*795d594fSAndroid Build Coastguard Worker// Note: Sign extension of int32 into int64. 30*795d594fSAndroid Build Coastguard Worker// Read from 32-bit vreg and write to 64-bit vreg, hence a custom impl. 31*795d594fSAndroid Build Coastguard Worker%def op_int_to_long(): 32*795d594fSAndroid Build Coastguard Worker srliw t1, xINST, 12 // t1 := B 33*795d594fSAndroid Build Coastguard Worker srliw t2, xINST, 8 // t2 := B|A 34*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t1") # t1 := fp[B] with sign extension to 64 bits 35*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance xPC, load xINST 36*795d594fSAndroid Build Coastguard Worker and t2, t2, 0xF // t2 := A 37*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t3 // t3 holds next opcode 38*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE t1, t2, z0=t0 39*795d594fSAndroid Build Coastguard Worker // fp[A:A+1] := t1 40*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t3 // continue to next 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker// long-to-int vA, vB 43*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|84 44*795d594fSAndroid Build Coastguard Worker// Note: Truncation of int64 into int32. 45*795d594fSAndroid Build Coastguard Worker// Implemented as a read from the low bits from vB, write them to vA. 46*795d594fSAndroid Build Coastguard Worker// Note: instr is intentionally empty. 47*795d594fSAndroid Build Coastguard Worker%def op_long_to_int(): 48*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="") 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker// int-to-byte vA, vB 51*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|8d 52*795d594fSAndroid Build Coastguard Worker// Note: Truncation of int32 to int8, sign extending the result. 53*795d594fSAndroid Build Coastguard Worker%def op_int_to_byte(): 54*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="sext.b t1, t1") 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker// int-to-byte vA, vB 57*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|8e 58*795d594fSAndroid Build Coastguard Worker// Note: Truncation of int32 to uint16, without sign extension. 59*795d594fSAndroid Build Coastguard Worker%def op_int_to_char(): 60*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="zext.h t1, t1") 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker// int-to-byte vA, vB 63*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|8f 64*795d594fSAndroid Build Coastguard Worker// Note: Truncation of int32 to int16, sign extending the result. 65*795d594fSAndroid Build Coastguard Worker%def op_int_to_short(): 66*795d594fSAndroid Build Coastguard Worker% generic_unop(instr="sext.h t1, t1") 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker// unop boilerplate 69*795d594fSAndroid Build Coastguard Worker// instr: operand held in t1, result written to t1. 70*795d594fSAndroid Build Coastguard Worker// instr must not clobber t2. 71*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2 72*795d594fSAndroid Build Coastguard Worker%def generic_unop(instr, is_wide=False): 73*795d594fSAndroid Build Coastguard Worker srliw t1, xINST, 12 // t1 := B 74*795d594fSAndroid Build Coastguard Worker srliw t2, xINST, 8 // t2 := B|A 75*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t1", is_wide=is_wide) 76*795d594fSAndroid Build Coastguard Worker // t1 := fp[B] 77*795d594fSAndroid Build Coastguard Worker and t2, t2, 0xF // t2 := A 78*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance xPC, load xINST 79*795d594fSAndroid Build Coastguard Worker $instr // read t1, write result to t1. 80*795d594fSAndroid Build Coastguard Worker // do not clobber t2! 81*795d594fSAndroid Build Coastguard Worker% set_vreg("t1", "t2", z0="t0", is_wide=is_wide) 82*795d594fSAndroid Build Coastguard Worker // fp[A] := t1 83*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t0 // t0 holds next opcode 84*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t0 // continue to next 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker// 87*795d594fSAndroid Build Coastguard Worker// binop vAA, vBB, vCC 88*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|op CC|BB 89*795d594fSAndroid Build Coastguard Worker// (see floating_point.S for float/double ops) 90*795d594fSAndroid Build Coastguard Worker// 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker// add-int vAA, vBB, vCC 93*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|90 CC|BB 94*795d594fSAndroid Build Coastguard Worker%def op_add_int(): 95*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="addw t1, t1, t2") 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker// sub-int vAA, vBB, vCC 98*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|91 CC|BB 99*795d594fSAndroid Build Coastguard Worker%def op_sub_int(): 100*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="subw t1, t1, t2") 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker// mul-int vAA, vBB, vCC 103*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|92 CC|BB 104*795d594fSAndroid Build Coastguard Worker%def op_mul_int(): 105*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="mulw t1, t1, t2") 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker// div-int vAA, vBB, vCC 108*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|93 CC|BB 109*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement division, rounded towards zero (that is, truncated to integer). This throws 110*795d594fSAndroid Build Coastguard Worker// ArithmeticException if b == 0. 111*795d594fSAndroid Build Coastguard Worker%def op_div_int(): 112*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="divw t1, t1, t2", divz_throw=True) 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker// rem-int vAA, vBB, vCC 115*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|94 CC|BB 116*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement remainder after division. The sign of the result is the same as that of a, 117*795d594fSAndroid Build Coastguard Worker// and it is more precisely defined as result == a - (a / b) * b. This throws ArithmeticException if 118*795d594fSAndroid Build Coastguard Worker// b == 0. 119*795d594fSAndroid Build Coastguard Worker%def op_rem_int(): 120*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="remw t1, t1, t2", divz_throw=True) 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker// and-int vAA, vBB, vCC 123*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|95 CC|BB 124*795d594fSAndroid Build Coastguard Worker%def op_and_int(): 125*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="and t1, t1, t2") 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker// or-int vAA, vBB, vCC 128*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|96 CC|BB 129*795d594fSAndroid Build Coastguard Worker%def op_or_int(): 130*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="or t1, t1, t2") 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker// xor-int vAA, vBB, vCC 133*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|97 CC|BB 134*795d594fSAndroid Build Coastguard Worker%def op_xor_int(): 135*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="xor t1, t1, t2") 136*795d594fSAndroid Build Coastguard Worker 137*795d594fSAndroid Build Coastguard Worker// shl-int vAA, vBB, vCC 138*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|98 CC|BB 139*795d594fSAndroid Build Coastguard Worker// Note: SLLW uses t2[4:0] for the shift amount. 140*795d594fSAndroid Build Coastguard Worker%def op_shl_int(): 141*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="sllw t1, t1, t2") 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker// shr-int vAA, vBB, vCC 144*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|99 CC|BB 145*795d594fSAndroid Build Coastguard Worker// Note: SRAW uses t2[4:0] for the shift amount. 146*795d594fSAndroid Build Coastguard Worker%def op_shr_int(): 147*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="sraw t1, t1, t2") 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker// ushr-int vAA, vBB, vCC 150*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9a CC|BB 151*795d594fSAndroid Build Coastguard Worker// Note: SRLW uses t2[4:0] for the shift amount. 152*795d594fSAndroid Build Coastguard Worker%def op_ushr_int(): 153*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="srlw t1, t1, t2") 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker// add-long vAA, vBB, vCC 156*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9b CC|BB 157*795d594fSAndroid Build Coastguard Worker%def op_add_long(): 158*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="add t1, t1, t2", is_wide=True) 159*795d594fSAndroid Build Coastguard Worker 160*795d594fSAndroid Build Coastguard Worker// sub-long vAA, vBB, vCC 161*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9c CC|BB 162*795d594fSAndroid Build Coastguard Worker%def op_sub_long(): 163*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="sub t1, t1, t2", is_wide=True) 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker// mul-long vAA, vBB, vCC 166*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9d CC|BB 167*795d594fSAndroid Build Coastguard Worker%def op_mul_long(): 168*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="mul t1, t1, t2", is_wide=True) 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker// div-long vAA, vBB, vCC 171*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9e CC|BB 172*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement division, rounded towards zero (that is, truncated to integer). This throws 173*795d594fSAndroid Build Coastguard Worker// ArithmeticException if b == 0. 174*795d594fSAndroid Build Coastguard Worker%def op_div_long(): 175*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="div t1, t1, t2", divz_throw=True, is_wide=True) 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker// rem-long vAA, vBB, vCC 178*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|9f CC|BB 179*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement remainder after division. The sign of the result is the same as that of a, 180*795d594fSAndroid Build Coastguard Worker// and it is more precisely defined as result == a - (a / b) * b. This throws ArithmeticException if 181*795d594fSAndroid Build Coastguard Worker// b == 0. 182*795d594fSAndroid Build Coastguard Worker%def op_rem_long(): 183*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="rem t1, t1, t2", divz_throw=True, is_wide=True) 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker// and-long vAA, vBB, vCC 186*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a0 CC|BB 187*795d594fSAndroid Build Coastguard Worker%def op_and_long(): 188*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="and t1, t1, t2", is_wide=True) 189*795d594fSAndroid Build Coastguard Worker 190*795d594fSAndroid Build Coastguard Worker// or-long vAA, vBB, vCC 191*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a1 CC|BB 192*795d594fSAndroid Build Coastguard Worker%def op_or_long(): 193*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="or t1, t1, t2", is_wide=True) 194*795d594fSAndroid Build Coastguard Worker 195*795d594fSAndroid Build Coastguard Worker// xor-long vAA, vBB, vCC 196*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a2 CC|BB 197*795d594fSAndroid Build Coastguard Worker%def op_xor_long(): 198*795d594fSAndroid Build Coastguard Worker% generic_binop(instr="xor t1, t1, t2", is_wide=True) 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker// shl-long vAA, vBB, vCC 201*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a3 CC|BB 202*795d594fSAndroid Build Coastguard Worker// Note: SLL uses t2[5:0] for the shift amount. 203*795d594fSAndroid Build Coastguard Worker%def op_shl_long(): 204*795d594fSAndroid Build Coastguard Worker% generic_shift_wide(instr="sll t1, t1, t2") 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker// shr-long vAA, vBB, vCC 207*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a4 CC|BB 208*795d594fSAndroid Build Coastguard Worker// Note: SRA uses t2[5:0] for the shift amount. 209*795d594fSAndroid Build Coastguard Worker%def op_shr_long(): 210*795d594fSAndroid Build Coastguard Worker% generic_shift_wide(instr="sra t1, t1, t2") 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker// ushr-long vAA, vBB, vCC 213*795d594fSAndroid Build Coastguard Worker// Format 23x: AA|a5 CC|BB 214*795d594fSAndroid Build Coastguard Worker// Note: SRL uses t2[5:0] for the shift amount. 215*795d594fSAndroid Build Coastguard Worker%def op_ushr_long(): 216*795d594fSAndroid Build Coastguard Worker% generic_shift_wide(instr="srl t1, t1, t2") 217*795d594fSAndroid Build Coastguard Worker 218*795d594fSAndroid Build Coastguard Worker// binop boilerplate 219*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 and t2, result written to t1. 220*795d594fSAndroid Build Coastguard Worker// instr must not throw. Exceptions to be thrown prior to instr. 221*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 222*795d594fSAndroid Build Coastguard Worker// 223*795d594fSAndroid Build Coastguard Worker// The divz_throw flag generates check-and-throw code for div/0. 224*795d594fSAndroid Build Coastguard Worker// The is_wide flag ensures vregs are read and written in 64-bit widths. 225*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3 226*795d594fSAndroid Build Coastguard Worker%def generic_binop(instr, divz_throw=False, is_wide=False): 227*795d594fSAndroid Build Coastguard Worker FETCH t1, count=1 // t1 := CC|BB 228*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := AA 229*795d594fSAndroid Build Coastguard Worker srliw t2, t1, 8 // t2 := CC 230*795d594fSAndroid Build Coastguard Worker and t1, t1, 0xFF // t1 := BB 231*795d594fSAndroid Build Coastguard Worker% get_vreg("t2", "t2", is_wide=is_wide) # t2 := fp[CC] 232*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t1", is_wide=is_wide) # t1 := fp[BB] 233*795d594fSAndroid Build Coastguard Worker% if divz_throw: 234*795d594fSAndroid Build Coastguard Worker beqz t2, 1f // Must throw before FETCH_ADVANCE_INST. 235*795d594fSAndroid Build Coastguard Worker%#: 236*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance xPC, load xINST 237*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 238*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 239*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 240*795d594fSAndroid Build Coastguard Worker% set_vreg("t1", "t3", z0="t0", is_wide=is_wide) 241*795d594fSAndroid Build Coastguard Worker // fp[AA] := t1 242*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 243*795d594fSAndroid Build Coastguard Worker1: 244*795d594fSAndroid Build Coastguard Worker% if divz_throw: 245*795d594fSAndroid Build Coastguard Worker tail common_errDivideByZero 246*795d594fSAndroid Build Coastguard Worker%#: 247*795d594fSAndroid Build Coastguard Worker 248*795d594fSAndroid Build Coastguard Worker// binop wide shift boilerplate 249*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 (64-bit) and t2 (32-bit), result written to t1. 250*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 251*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3 252*795d594fSAndroid Build Coastguard Worker// 253*795d594fSAndroid Build Coastguard Worker// Note: Contrary to other -long mathematical operations (which take register pairs for both their 254*795d594fSAndroid Build Coastguard Worker// first and their second source), shl-long, shr-long, and ushr-long take a register pair for their 255*795d594fSAndroid Build Coastguard Worker// first source (the value to be shifted), but a single register for their second source (the 256*795d594fSAndroid Build Coastguard Worker// shifting distance). 257*795d594fSAndroid Build Coastguard Worker%def generic_shift_wide(instr): 258*795d594fSAndroid Build Coastguard Worker FETCH t1, count=1 // t1 := CC|BB 259*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := AA 260*795d594fSAndroid Build Coastguard Worker srliw t2, t1, 8 // t2 := CC 261*795d594fSAndroid Build Coastguard Worker and t1, t1, 0xFF // t1 := BB 262*795d594fSAndroid Build Coastguard Worker% get_vreg("t2", "t2") # t2 := fp[CC] 263*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE t1, t1 // t1 := fp[BB] 264*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance xPC, load xINST 265*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 266*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 267*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 268*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE t1, t3, z0=t0 269*795d594fSAndroid Build Coastguard Worker // fp[AA] := t1 270*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 271*795d594fSAndroid Build Coastguard Worker 272*795d594fSAndroid Build Coastguard Worker// 273*795d594fSAndroid Build Coastguard Worker// binop/2addr vA, vB 274*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|op 275*795d594fSAndroid Build Coastguard Worker// (see floating_point.S for float/double ops) 276*795d594fSAndroid Build Coastguard Worker// 277*795d594fSAndroid Build Coastguard Worker 278*795d594fSAndroid Build Coastguard Worker// add-int/2addr vA, vB 279*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b0 280*795d594fSAndroid Build Coastguard Worker%def op_add_int_2addr(): 281*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="addw t1, t1, t2") 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker// sub-int/2addr vA, vB 284*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b1 285*795d594fSAndroid Build Coastguard Worker%def op_sub_int_2addr(): 286*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="subw t1, t1, t2") 287*795d594fSAndroid Build Coastguard Worker 288*795d594fSAndroid Build Coastguard Worker// mul-int/2addr vA, vB 289*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b2 290*795d594fSAndroid Build Coastguard Worker%def op_mul_int_2addr(): 291*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="mulw t1, t1, t2") 292*795d594fSAndroid Build Coastguard Worker 293*795d594fSAndroid Build Coastguard Worker// div-int/2addr vA, vB 294*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b3 295*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement division, rounded towards zero (that is, truncated to integer). This throws 296*795d594fSAndroid Build Coastguard Worker// ArithmeticException if b == 0. 297*795d594fSAndroid Build Coastguard Worker%def op_div_int_2addr(): 298*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="divw t1, t1, t2", divz_throw=True) 299*795d594fSAndroid Build Coastguard Worker 300*795d594fSAndroid Build Coastguard Worker// rem-int/2addr vA, vB 301*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b4 302*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement remainder after division. The sign of the result is the same as that of a, 303*795d594fSAndroid Build Coastguard Worker// and it is more precisely defined as result == a - (a / b) * b. This throws ArithmeticException if 304*795d594fSAndroid Build Coastguard Worker// b == 0. 305*795d594fSAndroid Build Coastguard Worker%def op_rem_int_2addr(): 306*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="remw t1, t1, t2", divz_throw=True) 307*795d594fSAndroid Build Coastguard Worker 308*795d594fSAndroid Build Coastguard Worker// and-int/2addr vA, vB 309*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b5 310*795d594fSAndroid Build Coastguard Worker%def op_and_int_2addr(): 311*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="and t1, t1, t2") 312*795d594fSAndroid Build Coastguard Worker 313*795d594fSAndroid Build Coastguard Worker// or-int/2addr vA, vB 314*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b6 315*795d594fSAndroid Build Coastguard Worker%def op_or_int_2addr(): 316*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="or t1, t1, t2") 317*795d594fSAndroid Build Coastguard Worker 318*795d594fSAndroid Build Coastguard Worker// xor-int/2addr vA, vB 319*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b7 320*795d594fSAndroid Build Coastguard Worker%def op_xor_int_2addr(): 321*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="xor t1, t1, t2") 322*795d594fSAndroid Build Coastguard Worker 323*795d594fSAndroid Build Coastguard Worker// shl-int/2addr vA, vB 324*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b8 325*795d594fSAndroid Build Coastguard Worker%def op_shl_int_2addr(): 326*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="sllw t1, t1, t2") 327*795d594fSAndroid Build Coastguard Worker 328*795d594fSAndroid Build Coastguard Worker// shr-int/2addr vA, vB 329*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|b9 330*795d594fSAndroid Build Coastguard Worker%def op_shr_int_2addr(): 331*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="sraw t1, t1, t2") 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker// ushr-int/2addr vA, vB 334*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|ba 335*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_2addr(): 336*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="srlw t1, t1, t2") 337*795d594fSAndroid Build Coastguard Worker 338*795d594fSAndroid Build Coastguard Worker// add-long/2addr vA, vB 339*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|bb 340*795d594fSAndroid Build Coastguard Worker%def op_add_long_2addr(): 341*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="add t1, t1, t2", is_wide=True) 342*795d594fSAndroid Build Coastguard Worker 343*795d594fSAndroid Build Coastguard Worker// sub-long/2addr vA, vB 344*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|bc 345*795d594fSAndroid Build Coastguard Worker%def op_sub_long_2addr(): 346*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="sub t1, t1, t2", is_wide=True) 347*795d594fSAndroid Build Coastguard Worker 348*795d594fSAndroid Build Coastguard Worker// mul-long/2addr vA, vB 349*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|bd 350*795d594fSAndroid Build Coastguard Worker%def op_mul_long_2addr(): 351*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="mul t1, t1, t2", is_wide=True) 352*795d594fSAndroid Build Coastguard Worker 353*795d594fSAndroid Build Coastguard Worker// div-long/2addr vA, vB 354*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|be 355*795d594fSAndroid Build Coastguard Worker%def op_div_long_2addr(): 356*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="div t1, t1, t2", divz_throw=True, is_wide=True) 357*795d594fSAndroid Build Coastguard Worker 358*795d594fSAndroid Build Coastguard Worker// rem-long/2addr vA, vB 359*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|bf 360*795d594fSAndroid Build Coastguard Worker%def op_rem_long_2addr(): 361*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="rem t1, t1, t2", divz_throw=True, is_wide=True) 362*795d594fSAndroid Build Coastguard Worker 363*795d594fSAndroid Build Coastguard Worker// and-long/2addr vA, vB 364*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c0 365*795d594fSAndroid Build Coastguard Worker%def op_and_long_2addr(): 366*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="and t1, t1, t2", is_wide=True) 367*795d594fSAndroid Build Coastguard Worker 368*795d594fSAndroid Build Coastguard Worker// or-long/2addr vA, vB 369*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c1 370*795d594fSAndroid Build Coastguard Worker%def op_or_long_2addr(): 371*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="or t1, t1, t2", is_wide=True) 372*795d594fSAndroid Build Coastguard Worker 373*795d594fSAndroid Build Coastguard Worker// xor-long/2addr vA, vB 374*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c2 375*795d594fSAndroid Build Coastguard Worker%def op_xor_long_2addr(): 376*795d594fSAndroid Build Coastguard Worker% generic_binop_2addr(instr="xor t1, t1, t2", is_wide=True) 377*795d594fSAndroid Build Coastguard Worker 378*795d594fSAndroid Build Coastguard Worker// shl-long/2addr vA, vB 379*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c3 380*795d594fSAndroid Build Coastguard Worker// Note: SLL uses t2[5:0] for the shift amount. 381*795d594fSAndroid Build Coastguard Worker%def op_shl_long_2addr(): 382*795d594fSAndroid Build Coastguard Worker% generic_shift_wide_2addr(instr="sll t1, t1, t2") 383*795d594fSAndroid Build Coastguard Worker 384*795d594fSAndroid Build Coastguard Worker// shr-long/2addr vA, vB 385*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c4 386*795d594fSAndroid Build Coastguard Worker// Note: SRA uses t2[5:0] for the shift amount. 387*795d594fSAndroid Build Coastguard Worker%def op_shr_long_2addr(): 388*795d594fSAndroid Build Coastguard Worker% generic_shift_wide_2addr(instr="sra t1, t1, t2") 389*795d594fSAndroid Build Coastguard Worker 390*795d594fSAndroid Build Coastguard Worker// ushr-long/2addr vA, vB 391*795d594fSAndroid Build Coastguard Worker// Format 12x: B|A|c5 392*795d594fSAndroid Build Coastguard Worker// Note: SRL uses t2[5:0] for the shift amount. 393*795d594fSAndroid Build Coastguard Worker%def op_ushr_long_2addr(): 394*795d594fSAndroid Build Coastguard Worker% generic_shift_wide_2addr(instr="srl t1, t1, t2") 395*795d594fSAndroid Build Coastguard Worker 396*795d594fSAndroid Build Coastguard Worker// binop 2addr boilerplate 397*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 and t2, result written to t1. 398*795d594fSAndroid Build Coastguard Worker// instr must not throw. Exceptions to be thrown prior to instr. 399*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 400*795d594fSAndroid Build Coastguard Worker// 401*795d594fSAndroid Build Coastguard Worker// The divz_throw flag generates check-and-throw code for div/0. 402*795d594fSAndroid Build Coastguard Worker// The is_wide flag ensures vregs are read and written in 64-bit widths. 403*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3, t4 404*795d594fSAndroid Build Coastguard Worker%def generic_binop_2addr(instr, divz_throw=False, is_wide=False): 405*795d594fSAndroid Build Coastguard Worker srliw t2, xINST, 12 // t2 := B 406*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := B|A 407*795d594fSAndroid Build Coastguard Worker% get_vreg("t2", "t2", is_wide=is_wide) 408*795d594fSAndroid Build Coastguard Worker // t2 := fp[B] 409*795d594fSAndroid Build Coastguard Worker and t3, t3, 0xF // t3 := A (cached for SET_VREG) 410*795d594fSAndroid Build Coastguard Worker mv t4, t3 // t4 := A 411*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t4", is_wide=is_wide) 412*795d594fSAndroid Build Coastguard Worker // t1 := fp[A] 413*795d594fSAndroid Build Coastguard Worker% if divz_throw: 414*795d594fSAndroid Build Coastguard Worker beqz t2, 1f // Must throw before FETCH_ADVANCE_INST. 415*795d594fSAndroid Build Coastguard Worker%#: 416*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance xPC, load xINST 417*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 418*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 419*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 420*795d594fSAndroid Build Coastguard Worker% set_vreg("t1", "t3", z0="t0", is_wide=is_wide) 421*795d594fSAndroid Build Coastguard Worker // fp[A] := t1 422*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 423*795d594fSAndroid Build Coastguard Worker1: 424*795d594fSAndroid Build Coastguard Worker% if divz_throw: 425*795d594fSAndroid Build Coastguard Worker tail common_errDivideByZero 426*795d594fSAndroid Build Coastguard Worker%#: 427*795d594fSAndroid Build Coastguard Worker 428*795d594fSAndroid Build Coastguard Worker// binop wide shift 2addr boilerplate 429*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 (64-bit) and t2 (32-bit), result written to t1. 430*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 431*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3, t4 432*795d594fSAndroid Build Coastguard Worker// 433*795d594fSAndroid Build Coastguard Worker// Note: Contrary to other -long/2addr mathematical operations (which take register pairs for both 434*795d594fSAndroid Build Coastguard Worker// their destination/first source and their second source), shl-long/2addr, shr-long/2addr, and 435*795d594fSAndroid Build Coastguard Worker// ushr-long/2addr take a register pair for their destination/first source (the value to be 436*795d594fSAndroid Build Coastguard Worker// shifted), but a single register for their second source (the shifting distance). 437*795d594fSAndroid Build Coastguard Worker%def generic_shift_wide_2addr(instr): 438*795d594fSAndroid Build Coastguard Worker srliw t2, xINST, 12 // t2 := B 439*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := B|A 440*795d594fSAndroid Build Coastguard Worker% get_vreg("t2", "t2") # t2 := fp[B] 441*795d594fSAndroid Build Coastguard Worker and t3, t3, 0xF // t3 := A (cached for SET_VREG_WIDE) 442*795d594fSAndroid Build Coastguard Worker mv t4, t3 // t4 := A 443*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 1 // advance xPC, load xINST 444*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE t1, t4 // t1 := fp[A] 445*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 446*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 447*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 448*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE t1, t3, z0=t0 449*795d594fSAndroid Build Coastguard Worker // fp[A] := t1 450*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 451*795d594fSAndroid Build Coastguard Worker 452*795d594fSAndroid Build Coastguard Worker// 453*795d594fSAndroid Build Coastguard Worker// binop/lit16 vA, vB, #+CCCC 454*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|op CCCC 455*795d594fSAndroid Build Coastguard Worker// 456*795d594fSAndroid Build Coastguard Worker 457*795d594fSAndroid Build Coastguard Worker// add-int/lit16 vA, vB, #+CCCC 458*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d0 CCCC 459*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit16(): 460*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="addw t1, t1, t2") 461*795d594fSAndroid Build Coastguard Worker 462*795d594fSAndroid Build Coastguard Worker// rsub-int vA, vB, #+CCCC 463*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d1 CCCC 464*795d594fSAndroid Build Coastguard Worker// Note: rsub-int does not have a suffix since this version is the main opcode of its family. 465*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement reverse subtraction. 466*795d594fSAndroid Build Coastguard Worker%def op_rsub_int(): 467*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="subw t1, t2, t1") 468*795d594fSAndroid Build Coastguard Worker 469*795d594fSAndroid Build Coastguard Worker// mul-int/lit16 vA, vB, #+CCCC 470*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d2 CCCC 471*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit16(): 472*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="mulw t1, t1, t2") 473*795d594fSAndroid Build Coastguard Worker 474*795d594fSAndroid Build Coastguard Worker// div-int/lit16 vA, vB, #+CCCC 475*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d3 CCCC 476*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement division, rounded towards zero (that is, truncated to integer). This throws 477*795d594fSAndroid Build Coastguard Worker// ArithmeticException if b == 0. 478*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit16(): 479*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="divw t1, t1, t2", divz_throw=True) 480*795d594fSAndroid Build Coastguard Worker 481*795d594fSAndroid Build Coastguard Worker// rem-int/lit16 vA, vB, #+CCCC 482*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d4 CCCC 483*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement remainder after division. The sign of the result is the same as that of a, 484*795d594fSAndroid Build Coastguard Worker// and it is more precisely defined as result == a - (a / b) * b. This throws ArithmeticException if 485*795d594fSAndroid Build Coastguard Worker// b == 0. 486*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit16(): 487*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="remw t1, t1, t2", divz_throw=True) 488*795d594fSAndroid Build Coastguard Worker 489*795d594fSAndroid Build Coastguard Worker// and-int/lit16 vA, vB, #+CCCC 490*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d5 CCCC 491*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit16(): 492*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="and t1, t1, t2") 493*795d594fSAndroid Build Coastguard Worker 494*795d594fSAndroid Build Coastguard Worker// or-int/lit16 vA, vB, #+CCCC 495*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d6 CCCC 496*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit16(): 497*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="or t1, t1, t2") 498*795d594fSAndroid Build Coastguard Worker 499*795d594fSAndroid Build Coastguard Worker// xor-int/lit16 vA, vB, #+CCCC 500*795d594fSAndroid Build Coastguard Worker// Format 22s: B|A|d7 CCCC 501*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit16(): 502*795d594fSAndroid Build Coastguard Worker% generic_binop_lit16(instr="xor t1, t1, t2") 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker// binop lit16 boilerplate 505*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 and t2, result written to t1. 506*795d594fSAndroid Build Coastguard Worker// instr must not throw. Exceptions to be thrown prior to instr. 507*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 508*795d594fSAndroid Build Coastguard Worker// 509*795d594fSAndroid Build Coastguard Worker// The divz_throw flag generates check-and-throw code for div/0. 510*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3 511*795d594fSAndroid Build Coastguard Worker%def generic_binop_lit16(instr, divz_throw=False): 512*795d594fSAndroid Build Coastguard Worker FETCH t2, count=1, signed=1 // t2 := ssssCCCC 513*795d594fSAndroid Build Coastguard Worker srliw t1, xINST, 12 // t1 := B 514*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := B|A 515*795d594fSAndroid Build Coastguard Worker% if divz_throw: 516*795d594fSAndroid Build Coastguard Worker beqz t2, 1f // Must throw before FETCH_ADVANCE_INST. 517*795d594fSAndroid Build Coastguard Worker%#: 518*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t1") # t1 := fp[B] 519*795d594fSAndroid Build Coastguard Worker and t3, t3, 0xF // t3 := A 520*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance xPC, load xINST 521*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 522*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 523*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 524*795d594fSAndroid Build Coastguard Worker% set_vreg("t1", "t3", z0="t0") # fp[A] := t1 525*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 526*795d594fSAndroid Build Coastguard Worker1: 527*795d594fSAndroid Build Coastguard Worker% if divz_throw: 528*795d594fSAndroid Build Coastguard Worker tail common_errDivideByZero 529*795d594fSAndroid Build Coastguard Worker%#: 530*795d594fSAndroid Build Coastguard Worker 531*795d594fSAndroid Build Coastguard Worker// 532*795d594fSAndroid Build Coastguard Worker// binop/lit8 vAA, vBB, #+CC 533*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|op CC|BB 534*795d594fSAndroid Build Coastguard Worker// 535*795d594fSAndroid Build Coastguard Worker 536*795d594fSAndroid Build Coastguard Worker// add-int/lit8, vAA, vBB, #+CC 537*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|d8, CC|BB 538*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit8(): 539*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="addw t1, t1, t2") 540*795d594fSAndroid Build Coastguard Worker 541*795d594fSAndroid Build Coastguard Worker// rsub-int/lit8, vAA, vBB, #+CC 542*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|d9, CC|BB 543*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement reverse subtraction. 544*795d594fSAndroid Build Coastguard Worker%def op_rsub_int_lit8(): 545*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="subw t1, t2, t1") 546*795d594fSAndroid Build Coastguard Worker 547*795d594fSAndroid Build Coastguard Worker// mul-int/lit8, vAA, vBB, #+CC 548*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|da, CC|BB 549*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit8(): 550*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="mulw t1, t1, t2") 551*795d594fSAndroid Build Coastguard Worker 552*795d594fSAndroid Build Coastguard Worker// div-int/lit8, vAA, vBB, #+CC 553*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|db, CC|BB 554*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement division, rounded towards zero (that is, truncated to integer). This throws 555*795d594fSAndroid Build Coastguard Worker// ArithmeticException if b == 0. 556*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit8(): 557*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="divw t1, t1, t2", divz_throw=True) 558*795d594fSAndroid Build Coastguard Worker 559*795d594fSAndroid Build Coastguard Worker// rem-int/lit8, vAA, vBB, #+CC 560*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|dc, CC|BB 561*795d594fSAndroid Build Coastguard Worker// Note: Twos-complement remainder after division. The sign of the result is the same as that of a, 562*795d594fSAndroid Build Coastguard Worker// and it is more precisely defined as result == a - (a / b) * b. This throws ArithmeticException if 563*795d594fSAndroid Build Coastguard Worker// b == 0. 564*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit8(): 565*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="remw t1, t1, t2", divz_throw=True) 566*795d594fSAndroid Build Coastguard Worker 567*795d594fSAndroid Build Coastguard Worker// and-int/lit8, vAA, vBB, #+CC 568*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|dd, CC|BB 569*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit8(): 570*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="and t1, t1, t2") 571*795d594fSAndroid Build Coastguard Worker 572*795d594fSAndroid Build Coastguard Worker// or-int/lit8, vAA, vBB, #+CC 573*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|de, CC|BB 574*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit8(): 575*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="or t1, t1, t2") 576*795d594fSAndroid Build Coastguard Worker 577*795d594fSAndroid Build Coastguard Worker// xor-int/lit8, vAA, vBB, #+CC 578*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|df, CC|BB 579*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit8(): 580*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="xor t1, t1, t2") 581*795d594fSAndroid Build Coastguard Worker 582*795d594fSAndroid Build Coastguard Worker// shl-int/lit8, vAA, vBB, #+CC 583*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|e0, CC|BB 584*795d594fSAndroid Build Coastguard Worker// Note: SLLW uses t2[4:0] for the shift amount. 585*795d594fSAndroid Build Coastguard Worker%def op_shl_int_lit8(): 586*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="sllw t1, t1, t2") 587*795d594fSAndroid Build Coastguard Worker 588*795d594fSAndroid Build Coastguard Worker// shr-int/lit8, vAA, vBB, #+CC 589*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|e1, CC|BB 590*795d594fSAndroid Build Coastguard Worker// Note: SRAW uses t2[4:0] for the shift amount. 591*795d594fSAndroid Build Coastguard Worker%def op_shr_int_lit8(): 592*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="sraw t1, t1, t2") 593*795d594fSAndroid Build Coastguard Worker 594*795d594fSAndroid Build Coastguard Worker// ushr-int/lit8, vAA, vBB, #+CC 595*795d594fSAndroid Build Coastguard Worker// Format 22b: AA|e2, CC|BB 596*795d594fSAndroid Build Coastguard Worker// Note: SRLW uses t2[4:0] for the shift amount. 597*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_lit8(): 598*795d594fSAndroid Build Coastguard Worker% generic_binop_lit8(instr="srlw t1, t1, t2") 599*795d594fSAndroid Build Coastguard Worker 600*795d594fSAndroid Build Coastguard Worker// binop lit8 boilerplate 601*795d594fSAndroid Build Coastguard Worker// instr: operands held in t1 and t2, result written to t1. 602*795d594fSAndroid Build Coastguard Worker// instr must not throw. Exceptions to be thrown prior to instr. 603*795d594fSAndroid Build Coastguard Worker// instr must not clobber t3. 604*795d594fSAndroid Build Coastguard Worker// 605*795d594fSAndroid Build Coastguard Worker// The divz_throw flag generates check-and-throw code for div/0. 606*795d594fSAndroid Build Coastguard Worker// Clobbers: t0, t1, t2, t3 607*795d594fSAndroid Build Coastguard Worker%def generic_binop_lit8(instr, divz_throw=False): 608*795d594fSAndroid Build Coastguard Worker FETCH t1, count=1, signed=1 // t1 := ssssCC|BB 609*795d594fSAndroid Build Coastguard Worker srliw t3, xINST, 8 // t3 := AA 610*795d594fSAndroid Build Coastguard Worker sraiw t2, t1, 8 // t2 := ssssssCC 611*795d594fSAndroid Build Coastguard Worker andi t1, t1, 0xFF // t1 := BB 612*795d594fSAndroid Build Coastguard Worker% if divz_throw: 613*795d594fSAndroid Build Coastguard Worker beqz t2, 1f // Must throw before FETCH_ADVANCE_INST. 614*795d594fSAndroid Build Coastguard Worker%#: 615*795d594fSAndroid Build Coastguard Worker% get_vreg("t1", "t1") # t1 := fp[BB] 616*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 2 // advance xPC, load xINST 617*795d594fSAndroid Build Coastguard Worker $instr // read t1 and t2, write result to t1. 618*795d594fSAndroid Build Coastguard Worker // do not clobber t3! 619*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE t2 // t2 holds next opcode 620*795d594fSAndroid Build Coastguard Worker% set_vreg("t1", "t3", z0="t0") # fp[AA] := t1 621*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE t2 // continue to next 622*795d594fSAndroid Build Coastguard Worker1: 623*795d594fSAndroid Build Coastguard Worker% if divz_throw: 624*795d594fSAndroid Build Coastguard Worker tail common_errDivideByZero 625*795d594fSAndroid Build Coastguard Worker%#: 626