1*795d594fSAndroid Build Coastguard Worker%def bindiv(result="", special="", rem=""): 2*795d594fSAndroid Build Coastguard Worker/* 3*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation. Handles special case of op0=minint and 4*795d594fSAndroid Build Coastguard Worker * op1=-1. 5*795d594fSAndroid Build Coastguard Worker */ 6*795d594fSAndroid Build Coastguard Worker /* div/rem vAA, vBB, vCC */ 7*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 8*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 9*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vBB 10*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vCC 11*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) 12*795d594fSAndroid Build Coastguard Worker testl %ecx, %ecx 13*795d594fSAndroid Build Coastguard Worker je common_errDivideByZero 14*795d594fSAndroid Build Coastguard Worker movl %eax, %edx 15*795d594fSAndroid Build Coastguard Worker orl %ecx, %edx 16*795d594fSAndroid Build Coastguard Worker testl $$0xFFFFFF00, %edx # If both arguments are less 17*795d594fSAndroid Build Coastguard Worker # than 8-bit and +ve 18*795d594fSAndroid Build Coastguard Worker jz .L${opcode}_8 # Do 8-bit divide 19*795d594fSAndroid Build Coastguard Worker testl $$0xFFFF0000, %edx # If both arguments are less 20*795d594fSAndroid Build Coastguard Worker # than 16-bit and +ve 21*795d594fSAndroid Build Coastguard Worker jz .L${opcode}_16 # Do 16-bit divide 22*795d594fSAndroid Build Coastguard Worker cmpl $$-1, %ecx 23*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_32 24*795d594fSAndroid Build Coastguard Worker cmpl $$0x80000000, %eax 25*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_32 26*795d594fSAndroid Build Coastguard Worker movl $special, $result 27*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 28*795d594fSAndroid Build Coastguard Worker% add_slow_path(bindiv_helper, result, rem) 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker%def bindiv_helper(result, rem): 31*795d594fSAndroid Build Coastguard Worker.L${opcode}_32: 32*795d594fSAndroid Build Coastguard Worker cltd 33*795d594fSAndroid Build Coastguard Worker idivl %ecx 34*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 35*795d594fSAndroid Build Coastguard Worker.L${opcode}_8: 36*795d594fSAndroid Build Coastguard Worker div %cl # 8-bit divide otherwise. 37*795d594fSAndroid Build Coastguard Worker # Remainder in %ah, quotient in %al 38*795d594fSAndroid Build Coastguard Worker .if $rem 39*795d594fSAndroid Build Coastguard Worker movl %eax, %edx 40*795d594fSAndroid Build Coastguard Worker shr $$8, %edx 41*795d594fSAndroid Build Coastguard Worker .else 42*795d594fSAndroid Build Coastguard Worker andl $$0x000000FF, %eax 43*795d594fSAndroid Build Coastguard Worker .endif 44*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 45*795d594fSAndroid Build Coastguard Worker.L${opcode}_16: 46*795d594fSAndroid Build Coastguard Worker xorl %edx, %edx # Clear %edx before divide 47*795d594fSAndroid Build Coastguard Worker div %cx 48*795d594fSAndroid Build Coastguard Worker.L${opcode}_finish: 49*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 50*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 51*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker%def bindiv2addr(result="", special=""): 54*795d594fSAndroid Build Coastguard Worker/* 55*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation. Handles special case of op0=minint and 56*795d594fSAndroid Build Coastguard Worker * op1=-1. 57*795d594fSAndroid Build Coastguard Worker */ 58*795d594fSAndroid Build Coastguard Worker /* div/rem/2addr vA, vB */ 59*795d594fSAndroid Build Coastguard Worker movzx rINSTbl, %ecx # eax <- BA 60*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) 61*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 62*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # eax <- vBB 63*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 64*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- vBB 65*795d594fSAndroid Build Coastguard Worker testl %ecx, %ecx 66*795d594fSAndroid Build Coastguard Worker je common_errDivideByZero 67*795d594fSAndroid Build Coastguard Worker cmpl $$-1, %ecx 68*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div2addr 69*795d594fSAndroid Build Coastguard Worker cmpl $$0x80000000, %eax 70*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div2addr 71*795d594fSAndroid Build Coastguard Worker movl $special, $result 72*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 73*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 74*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 75*795d594fSAndroid Build Coastguard Worker% add_slow_path(bindiv2addr_helper, result) 76*795d594fSAndroid Build Coastguard Worker 77*795d594fSAndroid Build Coastguard Worker%def bindiv2addr_helper(result): 78*795d594fSAndroid Build Coastguard Worker.L${opcode}_continue_div2addr: 79*795d594fSAndroid Build Coastguard Worker cltd 80*795d594fSAndroid Build Coastguard Worker idivl %ecx 81*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 82*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 83*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker%def bindivLit16(result="", special=""): 86*795d594fSAndroid Build Coastguard Worker/* 87*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation. Handles special case of op0=minint and 88*795d594fSAndroid Build Coastguard Worker * op1=-1. 89*795d594fSAndroid Build Coastguard Worker */ 90*795d594fSAndroid Build Coastguard Worker /* div/rem/lit16 vA, vB, #+CCCC */ 91*795d594fSAndroid Build Coastguard Worker /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 92*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax # eax <- 000000BA 93*795d594fSAndroid Build Coastguard Worker sarl $$4, %eax # eax <- B 94*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vB 95*795d594fSAndroid Build Coastguard Worker movswl 2(rPC), %ecx # ecx <- ssssCCCC 96*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 97*795d594fSAndroid Build Coastguard Worker testl %ecx, %ecx 98*795d594fSAndroid Build Coastguard Worker je common_errDivideByZero 99*795d594fSAndroid Build Coastguard Worker cmpl $$-1, %ecx 100*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div 101*795d594fSAndroid Build Coastguard Worker cmpl $$0x80000000, %eax 102*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div 103*795d594fSAndroid Build Coastguard Worker movl $special, %eax 104*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 105*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker.L${opcode}_continue_div: 108*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) 109*795d594fSAndroid Build Coastguard Worker cltd 110*795d594fSAndroid Build Coastguard Worker idivl %ecx 111*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 112*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 113*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker%def bindivLit8(result="", special=""): 116*795d594fSAndroid Build Coastguard Worker/* 117*795d594fSAndroid Build Coastguard Worker * 32-bit div/rem "lit8" binary operation. Handles special case of 118*795d594fSAndroid Build Coastguard Worker * op0=minint & op1=-1 119*795d594fSAndroid Build Coastguard Worker */ 120*795d594fSAndroid Build Coastguard Worker /* div/rem/lit8 vAA, vBB, #+CC */ 121*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 122*795d594fSAndroid Build Coastguard Worker movsbl 3(rPC), %ecx # ecx <- ssssssCC 123*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- rBB 124*795d594fSAndroid Build Coastguard Worker testl %ecx, %ecx 125*795d594fSAndroid Build Coastguard Worker je common_errDivideByZero 126*795d594fSAndroid Build Coastguard Worker cmpl $$0x80000000, %eax 127*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div 128*795d594fSAndroid Build Coastguard Worker cmpl $$-1, %ecx 129*795d594fSAndroid Build Coastguard Worker jne .L${opcode}_continue_div 130*795d594fSAndroid Build Coastguard Worker movl $special, %eax 131*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 132*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker.L${opcode}_continue_div: 135*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) 136*795d594fSAndroid Build Coastguard Worker cltd 137*795d594fSAndroid Build Coastguard Worker idivl %ecx 138*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 139*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 140*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker%def binop(result="%eax", instr=""): 143*795d594fSAndroid Build Coastguard Worker/* 144*795d594fSAndroid Build Coastguard Worker * Generic 32-bit binary operation. Provide an "instr" line that 145*795d594fSAndroid Build Coastguard Worker * specifies an instruction that performs "result = eax op VREG_ADDRESS(%ecx)". 146*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call. (If the result 147*795d594fSAndroid Build Coastguard Worker * comes back in a register other than eax, you can override "result".) 148*795d594fSAndroid Build Coastguard Worker * 149*795d594fSAndroid Build Coastguard Worker * For: add-int, sub-int, and-int, or-int, 150*795d594fSAndroid Build Coastguard Worker * xor-int, shl-int, shr-int, ushr-int 151*795d594fSAndroid Build Coastguard Worker */ 152*795d594fSAndroid Build Coastguard Worker /* binop vAA, vBB, vCC */ 153*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 154*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 155*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vBB 156*795d594fSAndroid Build Coastguard Worker $instr VREG_ADDRESS(%ecx), %eax 157*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 158*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 159*795d594fSAndroid Build Coastguard Worker 160*795d594fSAndroid Build Coastguard Worker%def binop1(result="%eax", tmp="%ecx", instr=""): 161*795d594fSAndroid Build Coastguard Worker/* 162*795d594fSAndroid Build Coastguard Worker * Generic 32-bit binary operation in which both operands loaded to 163*795d594fSAndroid Build Coastguard Worker * registers (op0 in eax, op1 in ecx). 164*795d594fSAndroid Build Coastguard Worker */ 165*795d594fSAndroid Build Coastguard Worker /* binop vAA, vBB, vCC */ 166*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC),%eax # eax <- BB 167*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC),%ecx # ecx <- CC 168*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vBB 169*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # eax <- vBB 170*795d594fSAndroid Build Coastguard Worker $instr # ex: addl %ecx,%eax 171*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 172*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 173*795d594fSAndroid Build Coastguard Worker 174*795d594fSAndroid Build Coastguard Worker%def binop2addr(result="%eax", instr=""): 175*795d594fSAndroid Build Coastguard Worker/* 176*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 177*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = r0 op r1". 178*795d594fSAndroid Build Coastguard Worker * This could be an instruction or a function call. 179*795d594fSAndroid Build Coastguard Worker * 180*795d594fSAndroid Build Coastguard Worker * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 181*795d594fSAndroid Build Coastguard Worker * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 182*795d594fSAndroid Build Coastguard Worker * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 183*795d594fSAndroid Build Coastguard Worker * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 184*795d594fSAndroid Build Coastguard Worker */ 185*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 186*795d594fSAndroid Build Coastguard Worker movzx rINSTbl, %ecx # ecx <- A+ 187*795d594fSAndroid Build Coastguard Worker sarl $$4, rINST # rINST <- B 188*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- vB 189*795d594fSAndroid Build Coastguard Worker andb $$0xf, %cl # ecx <- A 190*795d594fSAndroid Build Coastguard Worker $instr %eax, VREG_ADDRESS(%ecx) 191*795d594fSAndroid Build Coastguard Worker CLEAR_REF %ecx 192*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker%def binopLit16(result="%eax", instr=""): 195*795d594fSAndroid Build Coastguard Worker/* 196*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "lit16" binary operation. Provide an "instr" line 197*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = eax op ecx". 198*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call. (If the result 199*795d594fSAndroid Build Coastguard Worker * comes back in a register other than eax, you can override "result".) 200*795d594fSAndroid Build Coastguard Worker * 201*795d594fSAndroid Build Coastguard Worker * For: add-int/lit16, rsub-int, 202*795d594fSAndroid Build Coastguard Worker * and-int/lit16, or-int/lit16, xor-int/lit16 203*795d594fSAndroid Build Coastguard Worker */ 204*795d594fSAndroid Build Coastguard Worker /* binop/lit16 vA, vB, #+CCCC */ 205*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax # eax <- 000000BA 206*795d594fSAndroid Build Coastguard Worker sarl $$4, %eax # eax <- B 207*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vB 208*795d594fSAndroid Build Coastguard Worker movswl 2(rPC), %ecx # ecx <- ssssCCCC 209*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 210*795d594fSAndroid Build Coastguard Worker $instr # for example: addl %ecx, %eax 211*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 212*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 213*795d594fSAndroid Build Coastguard Worker 214*795d594fSAndroid Build Coastguard Worker%def binopLit8(result="%eax", instr=""): 215*795d594fSAndroid Build Coastguard Worker/* 216*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "lit8" binary operation. Provide an "instr" line 217*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = eax op ecx". 218*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call. (If the result 219*795d594fSAndroid Build Coastguard Worker * comes back in a register other than r0, you can override "result".) 220*795d594fSAndroid Build Coastguard Worker * 221*795d594fSAndroid Build Coastguard Worker * For: add-int/lit8, rsub-int/lit8 222*795d594fSAndroid Build Coastguard Worker * and-int/lit8, or-int/lit8, xor-int/lit8, 223*795d594fSAndroid Build Coastguard Worker * shl-int/lit8, shr-int/lit8, ushr-int/lit8 224*795d594fSAndroid Build Coastguard Worker */ 225*795d594fSAndroid Build Coastguard Worker /* binop/lit8 vAA, vBB, #+CC */ 226*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 227*795d594fSAndroid Build Coastguard Worker movsbl 3(rPC), %ecx # ecx <- ssssssCC 228*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- rBB 229*795d594fSAndroid Build Coastguard Worker $instr # ex: addl %ecx,%eax 230*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 231*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 232*795d594fSAndroid Build Coastguard Worker 233*795d594fSAndroid Build Coastguard Worker%def binopWide(instr1="", instr2=""): 234*795d594fSAndroid Build Coastguard Worker/* 235*795d594fSAndroid Build Coastguard Worker * Generic 64-bit binary operation. 236*795d594fSAndroid Build Coastguard Worker */ 237*795d594fSAndroid Build Coastguard Worker /* binop vAA, vBB, vCC */ 238*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 239*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 240*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) # save rIBASE 241*795d594fSAndroid Build Coastguard Worker GET_VREG rIBASE, %eax # rIBASE <- v[BB+0] 242*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %eax, %eax # eax <- v[BB+1] 243*795d594fSAndroid Build Coastguard Worker $instr1 VREG_ADDRESS(%ecx), rIBASE 244*795d594fSAndroid Build Coastguard Worker $instr2 VREG_HIGH_ADDRESS(%ecx), %eax 245*795d594fSAndroid Build Coastguard Worker SET_VREG rIBASE, rINST # v[AA+0] <- rIBASE 246*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE # restore rIBASE 247*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax 248*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 249*795d594fSAndroid Build Coastguard Worker 250*795d594fSAndroid Build Coastguard Worker%def binopWide2addr(instr1="", instr2=""): 251*795d594fSAndroid Build Coastguard Worker/* 252*795d594fSAndroid Build Coastguard Worker * Generic 64-bit binary operation. 253*795d594fSAndroid Build Coastguard Worker */ 254*795d594fSAndroid Build Coastguard Worker /* binop/2addr vA, vB */ 255*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx<- BA 256*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx<- B 257*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %ecx # eax<- v[B+0] 258*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ecx, %ecx # eax<- v[B+1] 259*795d594fSAndroid Build Coastguard Worker andb $$0xF, rINSTbl # rINST<- A 260*795d594fSAndroid Build Coastguard Worker $instr1 %eax, VREG_ADDRESS(rINST) 261*795d594fSAndroid Build Coastguard Worker $instr2 %ecx, VREG_HIGH_ADDRESS(rINST) 262*795d594fSAndroid Build Coastguard Worker CLEAR_WIDE_REF rINST 263*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 264*795d594fSAndroid Build Coastguard Worker 265*795d594fSAndroid Build Coastguard Worker%def cvtfp_int(srcdouble="1", tgtlong="1"): 266*795d594fSAndroid Build Coastguard Worker/* On fp to int conversions, Java requires that 267*795d594fSAndroid Build Coastguard Worker * if the result > maxint, it should be clamped to maxint. If it is less 268*795d594fSAndroid Build Coastguard Worker * than minint, it should be clamped to minint. If it is a nan, the result 269*795d594fSAndroid Build Coastguard Worker * should be zero. Further, the rounding mode is to truncate. This model 270*795d594fSAndroid Build Coastguard Worker * differs from what is delivered normally via the x86 fpu, so we have 271*795d594fSAndroid Build Coastguard Worker * to play some games. 272*795d594fSAndroid Build Coastguard Worker */ 273*795d594fSAndroid Build Coastguard Worker /* float/double to int/long vA, vB */ 274*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- A+ 275*795d594fSAndroid Build Coastguard Worker sarl $$4, rINST # rINST <- B 276*795d594fSAndroid Build Coastguard Worker .if $srcdouble 277*795d594fSAndroid Build Coastguard Worker fldl VREG_ADDRESS(rINST) # %st0 <- vB 278*795d594fSAndroid Build Coastguard Worker .else 279*795d594fSAndroid Build Coastguard Worker flds VREG_ADDRESS(rINST) # %st0 <- vB 280*795d594fSAndroid Build Coastguard Worker .endif 281*795d594fSAndroid Build Coastguard Worker ftst 282*795d594fSAndroid Build Coastguard Worker fnstcw LOCAL0(%esp) # remember original rounding mode 283*795d594fSAndroid Build Coastguard Worker movzwl LOCAL0(%esp), %eax 284*795d594fSAndroid Build Coastguard Worker movb $$0xc, %ah 285*795d594fSAndroid Build Coastguard Worker movw %ax, LOCAL0+2(%esp) 286*795d594fSAndroid Build Coastguard Worker fldcw LOCAL0+2(%esp) # set "to zero" rounding mode 287*795d594fSAndroid Build Coastguard Worker andb $$0xf, %cl # ecx <- A 288*795d594fSAndroid Build Coastguard Worker .if $tgtlong 289*795d594fSAndroid Build Coastguard Worker fistpll VREG_ADDRESS(%ecx) # convert and store 290*795d594fSAndroid Build Coastguard Worker .else 291*795d594fSAndroid Build Coastguard Worker fistpl VREG_ADDRESS(%ecx) # convert and store 292*795d594fSAndroid Build Coastguard Worker .endif 293*795d594fSAndroid Build Coastguard Worker fldcw LOCAL0(%esp) # restore previous rounding mode 294*795d594fSAndroid Build Coastguard Worker .if $tgtlong 295*795d594fSAndroid Build Coastguard Worker movl $$0x80000000, %eax 296*795d594fSAndroid Build Coastguard Worker xorl VREG_HIGH_ADDRESS(%ecx), %eax 297*795d594fSAndroid Build Coastguard Worker orl VREG_ADDRESS(%ecx), %eax 298*795d594fSAndroid Build Coastguard Worker .else 299*795d594fSAndroid Build Coastguard Worker cmpl $$0x80000000, VREG_ADDRESS(%ecx) 300*795d594fSAndroid Build Coastguard Worker .endif 301*795d594fSAndroid Build Coastguard Worker je .L${opcode}_special_case # fix up result 302*795d594fSAndroid Build Coastguard Worker 303*795d594fSAndroid Build Coastguard Worker.L${opcode}_finish: 304*795d594fSAndroid Build Coastguard Worker xor %eax, %eax 305*795d594fSAndroid Build Coastguard Worker mov %eax, VREG_REF_ADDRESS(%ecx) 306*795d594fSAndroid Build Coastguard Worker .if $tgtlong 307*795d594fSAndroid Build Coastguard Worker mov %eax, VREG_REF_HIGH_ADDRESS(%ecx) 308*795d594fSAndroid Build Coastguard Worker .endif 309*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 310*795d594fSAndroid Build Coastguard Worker% add_slow_path(cvtfp_int_helper, tgtlong) 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker%def cvtfp_int_helper(tgtlong): 313*795d594fSAndroid Build Coastguard Worker.L${opcode}_special_case: 314*795d594fSAndroid Build Coastguard Worker fnstsw %ax 315*795d594fSAndroid Build Coastguard Worker sahf 316*795d594fSAndroid Build Coastguard Worker jp .L${opcode}_isNaN 317*795d594fSAndroid Build Coastguard Worker adcl $$-1, VREG_ADDRESS(%ecx) 318*795d594fSAndroid Build Coastguard Worker .if $tgtlong 319*795d594fSAndroid Build Coastguard Worker adcl $$-1, VREG_HIGH_ADDRESS(%ecx) 320*795d594fSAndroid Build Coastguard Worker .endif 321*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 322*795d594fSAndroid Build Coastguard Worker.L${opcode}_isNaN: 323*795d594fSAndroid Build Coastguard Worker movl $$0, VREG_ADDRESS(%ecx) 324*795d594fSAndroid Build Coastguard Worker .if $tgtlong 325*795d594fSAndroid Build Coastguard Worker movl $$0, VREG_HIGH_ADDRESS(%ecx) 326*795d594fSAndroid Build Coastguard Worker .endif 327*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 328*795d594fSAndroid Build Coastguard Worker 329*795d594fSAndroid Build Coastguard Worker%def shop2addr(result="%eax", instr=""): 330*795d594fSAndroid Build Coastguard Worker/* 331*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "shift/2addr" operation. 332*795d594fSAndroid Build Coastguard Worker */ 333*795d594fSAndroid Build Coastguard Worker /* shift/2addr vA, vB */ 334*795d594fSAndroid Build Coastguard Worker movzx rINSTbl, %ecx # eax <- BA 335*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 336*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # eax <- vBB 337*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 338*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- vAA 339*795d594fSAndroid Build Coastguard Worker $instr # ex: sarl %cl, %eax 340*795d594fSAndroid Build Coastguard Worker SET_VREG $result, rINST 341*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 342*795d594fSAndroid Build Coastguard Worker 343*795d594fSAndroid Build Coastguard Worker%def unop(instr=""): 344*795d594fSAndroid Build Coastguard Worker/* 345*795d594fSAndroid Build Coastguard Worker * Generic 32-bit unary operation. Provide an "instr" line that 346*795d594fSAndroid Build Coastguard Worker * specifies an instruction that performs "result = op eax". 347*795d594fSAndroid Build Coastguard Worker */ 348*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 349*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl,%ecx # ecx <- A+ 350*795d594fSAndroid Build Coastguard Worker sarl $$4,rINST # rINST <- B 351*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- vB 352*795d594fSAndroid Build Coastguard Worker andb $$0xf,%cl # ecx <- A 353*795d594fSAndroid Build Coastguard Worker $instr 354*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, %ecx 355*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 356*795d594fSAndroid Build Coastguard Worker 357*795d594fSAndroid Build Coastguard Worker%def op_add_int(): 358*795d594fSAndroid Build Coastguard Worker% binop(instr="addl") 359*795d594fSAndroid Build Coastguard Worker 360*795d594fSAndroid Build Coastguard Worker%def op_add_int_2addr(): 361*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="addl") 362*795d594fSAndroid Build Coastguard Worker 363*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit16(): 364*795d594fSAndroid Build Coastguard Worker% binopLit16(instr="addl %ecx, %eax") 365*795d594fSAndroid Build Coastguard Worker 366*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit8(): 367*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="addl %ecx, %eax") 368*795d594fSAndroid Build Coastguard Worker 369*795d594fSAndroid Build Coastguard Worker%def op_add_long(): 370*795d594fSAndroid Build Coastguard Worker% binopWide(instr1="addl", instr2="adcl") 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker%def op_add_long_2addr(): 373*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr1="addl", instr2="adcl") 374*795d594fSAndroid Build Coastguard Worker 375*795d594fSAndroid Build Coastguard Worker%def op_and_int(): 376*795d594fSAndroid Build Coastguard Worker% binop(instr="andl") 377*795d594fSAndroid Build Coastguard Worker 378*795d594fSAndroid Build Coastguard Worker%def op_and_int_2addr(): 379*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="andl") 380*795d594fSAndroid Build Coastguard Worker 381*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit16(): 382*795d594fSAndroid Build Coastguard Worker% binopLit16(instr="andl %ecx, %eax") 383*795d594fSAndroid Build Coastguard Worker 384*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit8(): 385*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="andl %ecx, %eax") 386*795d594fSAndroid Build Coastguard Worker 387*795d594fSAndroid Build Coastguard Worker%def op_and_long(): 388*795d594fSAndroid Build Coastguard Worker% binopWide(instr1="andl", instr2="andl") 389*795d594fSAndroid Build Coastguard Worker 390*795d594fSAndroid Build Coastguard Worker%def op_and_long_2addr(): 391*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr1="andl", instr2="andl") 392*795d594fSAndroid Build Coastguard Worker 393*795d594fSAndroid Build Coastguard Worker%def op_cmp_long(): 394*795d594fSAndroid Build Coastguard Worker/* 395*795d594fSAndroid Build Coastguard Worker * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 396*795d594fSAndroid Build Coastguard Worker * register based on the results of the comparison. 397*795d594fSAndroid Build Coastguard Worker */ 398*795d594fSAndroid Build Coastguard Worker /* cmp-long vAA, vBB, vCC */ 399*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 400*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 401*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %eax, %eax # eax <- v[BB+1], BB is clobbered 402*795d594fSAndroid Build Coastguard Worker cmpl VREG_HIGH_ADDRESS(%ecx), %eax 403*795d594fSAndroid Build Coastguard Worker jl .L${opcode}_smaller 404*795d594fSAndroid Build Coastguard Worker jg .L${opcode}_bigger 405*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB, restore BB 406*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- v[BB] 407*795d594fSAndroid Build Coastguard Worker sub VREG_ADDRESS(%ecx), %eax 408*795d594fSAndroid Build Coastguard Worker ja .L${opcode}_bigger 409*795d594fSAndroid Build Coastguard Worker jb .L${opcode}_smaller 410*795d594fSAndroid Build Coastguard Worker.L${opcode}_finish: 411*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 412*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 413*795d594fSAndroid Build Coastguard Worker 414*795d594fSAndroid Build Coastguard Worker.L${opcode}_bigger: 415*795d594fSAndroid Build Coastguard Worker movl $$1, %eax 416*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 417*795d594fSAndroid Build Coastguard Worker 418*795d594fSAndroid Build Coastguard Worker.L${opcode}_smaller: 419*795d594fSAndroid Build Coastguard Worker movl $$-1, %eax 420*795d594fSAndroid Build Coastguard Worker jmp .L${opcode}_finish 421*795d594fSAndroid Build Coastguard Worker 422*795d594fSAndroid Build Coastguard Worker%def op_div_int(): 423*795d594fSAndroid Build Coastguard Worker% bindiv(result="%eax", special="$0x80000000", rem="0") 424*795d594fSAndroid Build Coastguard Worker 425*795d594fSAndroid Build Coastguard Worker%def op_div_int_2addr(): 426*795d594fSAndroid Build Coastguard Worker% bindiv2addr(result="%eax", special="$0x80000000") 427*795d594fSAndroid Build Coastguard Worker 428*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit16(): 429*795d594fSAndroid Build Coastguard Worker% bindivLit16(result="%eax", special="$0x80000000") 430*795d594fSAndroid Build Coastguard Worker 431*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit8(): 432*795d594fSAndroid Build Coastguard Worker% bindivLit8(result="%eax", special="$0x80000000") 433*795d594fSAndroid Build Coastguard Worker 434*795d594fSAndroid Build Coastguard Worker%def op_div_long(routine="art_quick_ldiv"): 435*795d594fSAndroid Build Coastguard Worker/* art_quick_* methods has quick abi, 436*795d594fSAndroid Build Coastguard Worker * so use eax, ecx, edx, ebx for args 437*795d594fSAndroid Build Coastguard Worker */ 438*795d594fSAndroid Build Coastguard Worker /* div vAA, vBB, vCC */ 439*795d594fSAndroid Build Coastguard Worker .extern $routine 440*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx 441*795d594fSAndroid Build Coastguard Worker mov rINST, LOCAL1(%esp) # save rINST/%ebx 442*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %eax # eax <- CC 443*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %eax 444*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ebx, %eax 445*795d594fSAndroid Build Coastguard Worker movl %ecx, %edx 446*795d594fSAndroid Build Coastguard Worker orl %ebx, %ecx 447*795d594fSAndroid Build Coastguard Worker jz common_errDivideByZero 448*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 449*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ecx, %eax 450*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax 451*795d594fSAndroid Build Coastguard Worker call SYMBOL($routine) 452*795d594fSAndroid Build Coastguard Worker mov LOCAL1(%esp), rINST # restore rINST/%ebx 453*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST 454*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 455*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx 456*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 457*795d594fSAndroid Build Coastguard Worker 458*795d594fSAndroid Build Coastguard Worker%def op_div_long_2addr(routine="art_quick_ldiv"): 459*795d594fSAndroid Build Coastguard Worker/* art_quick_* methods has quick abi, 460*795d594fSAndroid Build Coastguard Worker * so use eax, ecx, edx, ebx for args 461*795d594fSAndroid Build Coastguard Worker */ 462*795d594fSAndroid Build Coastguard Worker /* div/2addr vA, vB */ 463*795d594fSAndroid Build Coastguard Worker .extern $routine 464*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) # save rIBASE/%edx 465*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax 466*795d594fSAndroid Build Coastguard Worker shrl $$4, %eax # eax <- B 467*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 468*795d594fSAndroid Build Coastguard Worker mov rINST, LOCAL1(%esp) # save rINST/%ebx 469*795d594fSAndroid Build Coastguard Worker movl %ebx, %ecx 470*795d594fSAndroid Build Coastguard Worker GET_VREG %edx, %eax 471*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ebx, %eax 472*795d594fSAndroid Build Coastguard Worker movl %edx, %eax 473*795d594fSAndroid Build Coastguard Worker orl %ebx, %eax 474*795d594fSAndroid Build Coastguard Worker jz common_errDivideByZero 475*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %ecx 476*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ecx, %ecx 477*795d594fSAndroid Build Coastguard Worker call SYMBOL($routine) 478*795d594fSAndroid Build Coastguard Worker mov LOCAL1(%esp), rINST # restore rINST/%ebx 479*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST 480*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 481*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE # restore rIBASE/%edx 482*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 483*795d594fSAndroid Build Coastguard Worker 484*795d594fSAndroid Build Coastguard Worker%def op_int_to_byte(): 485*795d594fSAndroid Build Coastguard Worker% unop(instr="movsbl %al, %eax") 486*795d594fSAndroid Build Coastguard Worker 487*795d594fSAndroid Build Coastguard Worker%def op_int_to_char(): 488*795d594fSAndroid Build Coastguard Worker% unop(instr="movzwl %ax,%eax") 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker%def op_int_to_long(): 491*795d594fSAndroid Build Coastguard Worker /* int to long vA, vB */ 492*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax # eax <- +A 493*795d594fSAndroid Build Coastguard Worker sarl $$4, %eax # eax <- B 494*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vB 495*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 496*795d594fSAndroid Build Coastguard Worker movl rIBASE, %ecx # cltd trashes rIBASE/edx 497*795d594fSAndroid Build Coastguard Worker cltd # rINST:eax<- sssssssBBBBBBBB 498*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[A+1] <- rIBASE 499*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[A+0] <- %eax 500*795d594fSAndroid Build Coastguard Worker movl %ecx, rIBASE 501*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 502*795d594fSAndroid Build Coastguard Worker 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker%def op_int_to_short(): 505*795d594fSAndroid Build Coastguard Worker% unop(instr="movswl %ax, %eax") 506*795d594fSAndroid Build Coastguard Worker 507*795d594fSAndroid Build Coastguard Worker%def op_long_to_int(): 508*795d594fSAndroid Build Coastguard Worker/* we ignore the high word, making this equivalent to a 32-bit reg move */ 509*795d594fSAndroid Build Coastguard Worker% op_move() 510*795d594fSAndroid Build Coastguard Worker 511*795d594fSAndroid Build Coastguard Worker%def op_mul_int(): 512*795d594fSAndroid Build Coastguard Worker /* 513*795d594fSAndroid Build Coastguard Worker * 32-bit binary multiplication. 514*795d594fSAndroid Build Coastguard Worker */ 515*795d594fSAndroid Build Coastguard Worker /* mul vAA, vBB, vCC */ 516*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 517*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 518*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vBB 519*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL0(%esp) 520*795d594fSAndroid Build Coastguard Worker imull VREG_ADDRESS(%ecx), %eax # trashes rIBASE/edx 521*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rIBASE 522*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 523*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 524*795d594fSAndroid Build Coastguard Worker 525*795d594fSAndroid Build Coastguard Worker%def op_mul_int_2addr(): 526*795d594fSAndroid Build Coastguard Worker /* mul vA, vB */ 527*795d594fSAndroid Build Coastguard Worker movzx rINSTbl, %ecx # ecx <- A+ 528*795d594fSAndroid Build Coastguard Worker sarl $$4, rINST # rINST <- B 529*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- vB 530*795d594fSAndroid Build Coastguard Worker andb $$0xf, %cl # ecx <- A 531*795d594fSAndroid Build Coastguard Worker movl rIBASE, rINST 532*795d594fSAndroid Build Coastguard Worker imull VREG_ADDRESS(%ecx), %eax # trashes rIBASE/edx 533*795d594fSAndroid Build Coastguard Worker movl rINST, rIBASE 534*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, %ecx 535*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 536*795d594fSAndroid Build Coastguard Worker 537*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit16(): 538*795d594fSAndroid Build Coastguard Worker /* mul/lit16 vA, vB, #+CCCC */ 539*795d594fSAndroid Build Coastguard Worker /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 540*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax # eax <- 000000BA 541*795d594fSAndroid Build Coastguard Worker sarl $$4, %eax # eax <- B 542*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- vB 543*795d594fSAndroid Build Coastguard Worker movl rIBASE, %ecx 544*795d594fSAndroid Build Coastguard Worker movswl 2(rPC), rIBASE # rIBASE <- ssssCCCC 545*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 546*795d594fSAndroid Build Coastguard Worker imull rIBASE, %eax # trashes rIBASE/edx 547*795d594fSAndroid Build Coastguard Worker movl %ecx, rIBASE 548*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 549*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 550*795d594fSAndroid Build Coastguard Worker 551*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit8(): 552*795d594fSAndroid Build Coastguard Worker /* mul/lit8 vAA, vBB, #+CC */ 553*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 554*795d594fSAndroid Build Coastguard Worker movl rIBASE, %ecx 555*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- rBB 556*795d594fSAndroid Build Coastguard Worker movsbl 3(rPC), rIBASE # rIBASE <- ssssssCC 557*795d594fSAndroid Build Coastguard Worker imull rIBASE, %eax # trashes rIBASE/edx 558*795d594fSAndroid Build Coastguard Worker movl %ecx, rIBASE 559*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST 560*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 561*795d594fSAndroid Build Coastguard Worker 562*795d594fSAndroid Build Coastguard Worker%def op_mul_long(): 563*795d594fSAndroid Build Coastguard Worker/* 564*795d594fSAndroid Build Coastguard Worker * Signed 64-bit integer multiply. 565*795d594fSAndroid Build Coastguard Worker * 566*795d594fSAndroid Build Coastguard Worker * We could definately use more free registers for 567*795d594fSAndroid Build Coastguard Worker * this code. We spill rINSTw (ebx), 568*795d594fSAndroid Build Coastguard Worker * giving us eax, ebc, ecx and edx as computational 569*795d594fSAndroid Build Coastguard Worker * temps. On top of that, we'll spill edi (rFP) 570*795d594fSAndroid Build Coastguard Worker * for use as the vB pointer and esi (rPC) for use 571*795d594fSAndroid Build Coastguard Worker * as the vC pointer. Yuck. 572*795d594fSAndroid Build Coastguard Worker * 573*795d594fSAndroid Build Coastguard Worker */ 574*795d594fSAndroid Build Coastguard Worker /* mul-long vAA, vBB, vCC */ 575*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- B 576*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- C 577*795d594fSAndroid Build Coastguard Worker mov rPC, LOCAL0(%esp) # save Interpreter PC 578*795d594fSAndroid Build Coastguard Worker mov rFP, LOCAL1(%esp) # save FP 579*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL2(%esp) # save rIBASE 580*795d594fSAndroid Build Coastguard Worker leal (rFP,%eax,4), %esi # esi <- &v[B] 581*795d594fSAndroid Build Coastguard Worker leal VREG_ADDRESS(%ecx), rFP # rFP <- &v[C] 582*795d594fSAndroid Build Coastguard Worker movl 4(%esi), %ecx # ecx <- Bmsw 583*795d594fSAndroid Build Coastguard Worker imull (rFP), %ecx # ecx <- (Bmsw*Clsw) 584*795d594fSAndroid Build Coastguard Worker movl 4(rFP), %eax # eax <- Cmsw 585*795d594fSAndroid Build Coastguard Worker imull (%esi), %eax # eax <- (Cmsw*Blsw) 586*795d594fSAndroid Build Coastguard Worker addl %eax, %ecx # ecx <- (Bmsw*Clsw)+(Cmsw*Blsw) 587*795d594fSAndroid Build Coastguard Worker movl (rFP), %eax # eax <- Clsw 588*795d594fSAndroid Build Coastguard Worker mull (%esi) # eax <- (Clsw*Alsw) 589*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rPC # restore Interpreter PC 590*795d594fSAndroid Build Coastguard Worker mov LOCAL1(%esp), rFP # restore FP 591*795d594fSAndroid Build Coastguard Worker leal (%ecx,rIBASE), rIBASE # full result now in rIBASE:%eax 592*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[B+1] <- rIBASE 593*795d594fSAndroid Build Coastguard Worker mov LOCAL2(%esp), rIBASE # restore IBASE 594*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[B] <- eax 595*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 596*795d594fSAndroid Build Coastguard Worker 597*795d594fSAndroid Build Coastguard Worker%def op_mul_long_2addr(): 598*795d594fSAndroid Build Coastguard Worker/* 599*795d594fSAndroid Build Coastguard Worker * Signed 64-bit integer multiply, 2-addr version 600*795d594fSAndroid Build Coastguard Worker * 601*795d594fSAndroid Build Coastguard Worker * We could definately use more free registers for 602*795d594fSAndroid Build Coastguard Worker * this code. We must spill %edx (rIBASE) because it 603*795d594fSAndroid Build Coastguard Worker * is used by imul. We'll also spill rINST (ebx), 604*795d594fSAndroid Build Coastguard Worker * giving us eax, ebc, ecx and rIBASE as computational 605*795d594fSAndroid Build Coastguard Worker * temps. On top of that, we'll spill %esi (edi) 606*795d594fSAndroid Build Coastguard Worker * for use as the vA pointer and rFP (esi) for use 607*795d594fSAndroid Build Coastguard Worker * as the vB pointer. Yuck. 608*795d594fSAndroid Build Coastguard Worker */ 609*795d594fSAndroid Build Coastguard Worker /* mul-long/2addr vA, vB */ 610*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %eax # eax <- BA 611*795d594fSAndroid Build Coastguard Worker andb $$0xf, %al # eax <- A 612*795d594fSAndroid Build Coastguard Worker CLEAR_WIDE_REF %eax # clear refs in advance 613*795d594fSAndroid Build Coastguard Worker sarl $$4, rINST # rINST <- B 614*795d594fSAndroid Build Coastguard Worker mov rPC, LOCAL0(%esp) # save Interpreter PC 615*795d594fSAndroid Build Coastguard Worker mov rFP, LOCAL1(%esp) # save FP 616*795d594fSAndroid Build Coastguard Worker mov rIBASE, LOCAL2(%esp) # save rIBASE 617*795d594fSAndroid Build Coastguard Worker leal (rFP,%eax,4), %esi # esi <- &v[A] 618*795d594fSAndroid Build Coastguard Worker leal (rFP,rINST,4), rFP # rFP <- &v[B] 619*795d594fSAndroid Build Coastguard Worker movl 4(%esi), %ecx # ecx <- Amsw 620*795d594fSAndroid Build Coastguard Worker imull (rFP), %ecx # ecx <- (Amsw*Blsw) 621*795d594fSAndroid Build Coastguard Worker movl 4(rFP), %eax # eax <- Bmsw 622*795d594fSAndroid Build Coastguard Worker imull (%esi), %eax # eax <- (Bmsw*Alsw) 623*795d594fSAndroid Build Coastguard Worker addl %eax, %ecx # ecx <- (Amsw*Blsw)+(Bmsw*Alsw) 624*795d594fSAndroid Build Coastguard Worker movl (rFP), %eax # eax <- Blsw 625*795d594fSAndroid Build Coastguard Worker mull (%esi) # eax <- (Blsw*Alsw) 626*795d594fSAndroid Build Coastguard Worker leal (%ecx,rIBASE), rIBASE # full result now in %edx:%eax 627*795d594fSAndroid Build Coastguard Worker movl rIBASE, 4(%esi) # v[A+1] <- rIBASE 628*795d594fSAndroid Build Coastguard Worker movl %eax, (%esi) # v[A] <- %eax 629*795d594fSAndroid Build Coastguard Worker mov LOCAL0(%esp), rPC # restore Interpreter PC 630*795d594fSAndroid Build Coastguard Worker mov LOCAL2(%esp), rIBASE # restore IBASE 631*795d594fSAndroid Build Coastguard Worker mov LOCAL1(%esp), rFP # restore FP 632*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 633*795d594fSAndroid Build Coastguard Worker 634*795d594fSAndroid Build Coastguard Worker%def op_neg_int(): 635*795d594fSAndroid Build Coastguard Worker% unop(instr="negl %eax") 636*795d594fSAndroid Build Coastguard Worker 637*795d594fSAndroid Build Coastguard Worker%def op_neg_long(): 638*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 639*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- BA 640*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 641*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 642*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %ecx # eax <- v[B+0] 643*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1] 644*795d594fSAndroid Build Coastguard Worker negl %eax 645*795d594fSAndroid Build Coastguard Worker adcl $$0, %ecx 646*795d594fSAndroid Build Coastguard Worker negl %ecx 647*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[A+0] <- eax 648*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx 649*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 650*795d594fSAndroid Build Coastguard Worker 651*795d594fSAndroid Build Coastguard Worker 652*795d594fSAndroid Build Coastguard Worker%def op_not_int(): 653*795d594fSAndroid Build Coastguard Worker% unop(instr="notl %eax") 654*795d594fSAndroid Build Coastguard Worker 655*795d594fSAndroid Build Coastguard Worker%def op_not_long(): 656*795d594fSAndroid Build Coastguard Worker /* unop vA, vB */ 657*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- BA 658*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 659*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 660*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %ecx # eax <- v[B+0] 661*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH %ecx, %ecx # ecx <- v[B+1] 662*795d594fSAndroid Build Coastguard Worker notl %eax 663*795d594fSAndroid Build Coastguard Worker notl %ecx 664*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[A+0] <- eax 665*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH %ecx, rINST # v[A+1] <- ecx 666*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 667*795d594fSAndroid Build Coastguard Worker 668*795d594fSAndroid Build Coastguard Worker%def op_or_int(): 669*795d594fSAndroid Build Coastguard Worker% binop(instr="orl") 670*795d594fSAndroid Build Coastguard Worker 671*795d594fSAndroid Build Coastguard Worker%def op_or_int_2addr(): 672*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="orl") 673*795d594fSAndroid Build Coastguard Worker 674*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit16(): 675*795d594fSAndroid Build Coastguard Worker% binopLit16(instr="orl %ecx, %eax") 676*795d594fSAndroid Build Coastguard Worker 677*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit8(): 678*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="orl %ecx, %eax") 679*795d594fSAndroid Build Coastguard Worker 680*795d594fSAndroid Build Coastguard Worker%def op_or_long(): 681*795d594fSAndroid Build Coastguard Worker% binopWide(instr1="orl", instr2="orl") 682*795d594fSAndroid Build Coastguard Worker 683*795d594fSAndroid Build Coastguard Worker%def op_or_long_2addr(): 684*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr1="orl", instr2="orl") 685*795d594fSAndroid Build Coastguard Worker 686*795d594fSAndroid Build Coastguard Worker%def op_rem_int(): 687*795d594fSAndroid Build Coastguard Worker% bindiv(result="rIBASE", special="$0", rem="1") 688*795d594fSAndroid Build Coastguard Worker 689*795d594fSAndroid Build Coastguard Worker%def op_rem_int_2addr(): 690*795d594fSAndroid Build Coastguard Worker% bindiv2addr(result="rIBASE", special="$0") 691*795d594fSAndroid Build Coastguard Worker 692*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit16(): 693*795d594fSAndroid Build Coastguard Worker% bindivLit16(result="rIBASE", special="$0") 694*795d594fSAndroid Build Coastguard Worker 695*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit8(): 696*795d594fSAndroid Build Coastguard Worker% bindivLit8(result="rIBASE", special="$0") 697*795d594fSAndroid Build Coastguard Worker 698*795d594fSAndroid Build Coastguard Worker%def op_rem_long(): 699*795d594fSAndroid Build Coastguard Worker% op_div_long(routine="art_quick_lmod") 700*795d594fSAndroid Build Coastguard Worker 701*795d594fSAndroid Build Coastguard Worker%def op_rem_long_2addr(): 702*795d594fSAndroid Build Coastguard Worker% op_div_long_2addr(routine="art_quick_lmod") 703*795d594fSAndroid Build Coastguard Worker 704*795d594fSAndroid Build Coastguard Worker%def op_rsub_int(): 705*795d594fSAndroid Build Coastguard Worker/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 706*795d594fSAndroid Build Coastguard Worker% binopLit16(instr="subl %eax, %ecx", result="%ecx") 707*795d594fSAndroid Build Coastguard Worker 708*795d594fSAndroid Build Coastguard Worker%def op_rsub_int_lit8(): 709*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="subl %eax, %ecx", result="%ecx") 710*795d594fSAndroid Build Coastguard Worker 711*795d594fSAndroid Build Coastguard Worker%def op_shl_int(): 712*795d594fSAndroid Build Coastguard Worker% binop1(instr="sall %cl, %eax") 713*795d594fSAndroid Build Coastguard Worker 714*795d594fSAndroid Build Coastguard Worker%def op_shl_int_2addr(): 715*795d594fSAndroid Build Coastguard Worker% shop2addr(instr="sall %cl, %eax") 716*795d594fSAndroid Build Coastguard Worker 717*795d594fSAndroid Build Coastguard Worker%def op_shl_int_lit8(): 718*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="sall %cl, %eax") 719*795d594fSAndroid Build Coastguard Worker 720*795d594fSAndroid Build Coastguard Worker%def op_shl_long(): 721*795d594fSAndroid Build Coastguard Worker/* 722*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 723*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 724*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to mask off the low 725*795d594fSAndroid Build Coastguard Worker * 6 bits of the shift distance. x86 shifts automatically mask off 726*795d594fSAndroid Build Coastguard Worker * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 727*795d594fSAndroid Build Coastguard Worker * case specially. 728*795d594fSAndroid Build Coastguard Worker */ 729*795d594fSAndroid Build Coastguard Worker /* shl-long vAA, vBB, vCC */ 730*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 731*795d594fSAndroid Build Coastguard Worker /* Need to spill rINST */ 732*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 733*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 734*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 735*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 736*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, %eax # ecx <- v[BB+1] 737*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vCC 738*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- v[BB+0] 739*795d594fSAndroid Build Coastguard Worker shldl %eax,rIBASE 740*795d594fSAndroid Build Coastguard Worker sall %cl, %eax 741*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 742*795d594fSAndroid Build Coastguard Worker je 2f 743*795d594fSAndroid Build Coastguard Worker movl %eax, rIBASE 744*795d594fSAndroid Build Coastguard Worker xorl %eax, %eax 745*795d594fSAndroid Build Coastguard Worker2: 746*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 747*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 748*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[AA+0] <- %eax 749*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 750*795d594fSAndroid Build Coastguard Worker 751*795d594fSAndroid Build Coastguard Worker%def op_shl_long_2addr(): 752*795d594fSAndroid Build Coastguard Worker/* 753*795d594fSAndroid Build Coastguard Worker * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 754*795d594fSAndroid Build Coastguard Worker * 32-bit shift distance. 755*795d594fSAndroid Build Coastguard Worker */ 756*795d594fSAndroid Build Coastguard Worker /* shl-long/2addr vA, vB */ 757*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 758*795d594fSAndroid Build Coastguard Worker /* Need to spill rIBASE */ 759*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 760*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- BA 761*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 762*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- v[AA+0] 763*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 764*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 765*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1] 766*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vBB 767*795d594fSAndroid Build Coastguard Worker shldl %eax, rIBASE 768*795d594fSAndroid Build Coastguard Worker sall %cl, %eax 769*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 770*795d594fSAndroid Build Coastguard Worker je 2f 771*795d594fSAndroid Build Coastguard Worker movl %eax, rIBASE 772*795d594fSAndroid Build Coastguard Worker xorl %eax, %eax 773*795d594fSAndroid Build Coastguard Worker2: 774*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 775*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 776*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[AA+0] <- eax 777*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 778*795d594fSAndroid Build Coastguard Worker 779*795d594fSAndroid Build Coastguard Worker%def op_shr_int(): 780*795d594fSAndroid Build Coastguard Worker% binop1(instr="sarl %cl, %eax") 781*795d594fSAndroid Build Coastguard Worker 782*795d594fSAndroid Build Coastguard Worker%def op_shr_int_2addr(): 783*795d594fSAndroid Build Coastguard Worker% shop2addr(instr="sarl %cl, %eax") 784*795d594fSAndroid Build Coastguard Worker 785*795d594fSAndroid Build Coastguard Worker%def op_shr_int_lit8(): 786*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="sarl %cl, %eax") 787*795d594fSAndroid Build Coastguard Worker 788*795d594fSAndroid Build Coastguard Worker%def op_shr_long(): 789*795d594fSAndroid Build Coastguard Worker/* 790*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 791*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 792*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to mask off the low 793*795d594fSAndroid Build Coastguard Worker * 6 bits of the shift distance. x86 shifts automatically mask off 794*795d594fSAndroid Build Coastguard Worker * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 795*795d594fSAndroid Build Coastguard Worker * case specially. 796*795d594fSAndroid Build Coastguard Worker */ 797*795d594fSAndroid Build Coastguard Worker /* shr-long vAA, vBB, vCC */ 798*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 799*795d594fSAndroid Build Coastguard Worker /* Need to spill rIBASE */ 800*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 801*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 802*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 803*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 804*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, %eax # rIBASE<- v[BB+1] 805*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vCC 806*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- v[BB+0] 807*795d594fSAndroid Build Coastguard Worker shrdl rIBASE, %eax 808*795d594fSAndroid Build Coastguard Worker sarl %cl, rIBASE 809*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 810*795d594fSAndroid Build Coastguard Worker je 2f 811*795d594fSAndroid Build Coastguard Worker movl rIBASE, %eax 812*795d594fSAndroid Build Coastguard Worker sarl $$31, rIBASE 813*795d594fSAndroid Build Coastguard Worker2: 814*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 815*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 816*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[AA+0] <- eax 817*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 818*795d594fSAndroid Build Coastguard Worker 819*795d594fSAndroid Build Coastguard Worker%def op_shr_long_2addr(): 820*795d594fSAndroid Build Coastguard Worker/* 821*795d594fSAndroid Build Coastguard Worker * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 822*795d594fSAndroid Build Coastguard Worker * 32-bit shift distance. 823*795d594fSAndroid Build Coastguard Worker */ 824*795d594fSAndroid Build Coastguard Worker /* shl-long/2addr vA, vB */ 825*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 826*795d594fSAndroid Build Coastguard Worker /* Need to spill rIBASE */ 827*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 828*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- BA 829*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 830*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- v[AA+0] 831*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 832*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 833*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1] 834*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vBB 835*795d594fSAndroid Build Coastguard Worker shrdl rIBASE, %eax 836*795d594fSAndroid Build Coastguard Worker sarl %cl, rIBASE 837*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 838*795d594fSAndroid Build Coastguard Worker je 2f 839*795d594fSAndroid Build Coastguard Worker movl rIBASE, %eax 840*795d594fSAndroid Build Coastguard Worker sarl $$31, rIBASE 841*795d594fSAndroid Build Coastguard Worker2: 842*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 843*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 844*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[AA+0] <- eax 845*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 846*795d594fSAndroid Build Coastguard Worker 847*795d594fSAndroid Build Coastguard Worker%def op_sub_int(): 848*795d594fSAndroid Build Coastguard Worker% binop(instr="subl") 849*795d594fSAndroid Build Coastguard Worker 850*795d594fSAndroid Build Coastguard Worker%def op_sub_int_2addr(): 851*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="subl") 852*795d594fSAndroid Build Coastguard Worker 853*795d594fSAndroid Build Coastguard Worker%def op_sub_long(): 854*795d594fSAndroid Build Coastguard Worker% binopWide(instr1="subl", instr2="sbbl") 855*795d594fSAndroid Build Coastguard Worker 856*795d594fSAndroid Build Coastguard Worker%def op_sub_long_2addr(): 857*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr1="subl", instr2="sbbl") 858*795d594fSAndroid Build Coastguard Worker 859*795d594fSAndroid Build Coastguard Worker%def op_ushr_int(): 860*795d594fSAndroid Build Coastguard Worker% binop1(instr="shrl %cl, %eax") 861*795d594fSAndroid Build Coastguard Worker 862*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_2addr(): 863*795d594fSAndroid Build Coastguard Worker% shop2addr(instr="shrl %cl, %eax") 864*795d594fSAndroid Build Coastguard Worker 865*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_lit8(): 866*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="shrl %cl, %eax") 867*795d594fSAndroid Build Coastguard Worker 868*795d594fSAndroid Build Coastguard Worker%def op_ushr_long(): 869*795d594fSAndroid Build Coastguard Worker/* 870*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 871*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 872*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to mask off the low 873*795d594fSAndroid Build Coastguard Worker * 6 bits of the shift distance. x86 shifts automatically mask off 874*795d594fSAndroid Build Coastguard Worker * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 875*795d594fSAndroid Build Coastguard Worker * case specially. 876*795d594fSAndroid Build Coastguard Worker */ 877*795d594fSAndroid Build Coastguard Worker /* shr-long vAA, vBB, vCC */ 878*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 879*795d594fSAndroid Build Coastguard Worker /* Need to spill rIBASE */ 880*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 881*795d594fSAndroid Build Coastguard Worker movzbl 2(rPC), %eax # eax <- BB 882*795d594fSAndroid Build Coastguard Worker movzbl 3(rPC), %ecx # ecx <- CC 883*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 884*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, %eax # rIBASE <- v[BB+1] 885*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vCC 886*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, %eax # eax <- v[BB+0] 887*795d594fSAndroid Build Coastguard Worker shrdl rIBASE, %eax 888*795d594fSAndroid Build Coastguard Worker shrl %cl, rIBASE 889*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 890*795d594fSAndroid Build Coastguard Worker je 2f 891*795d594fSAndroid Build Coastguard Worker movl rIBASE, %eax 892*795d594fSAndroid Build Coastguard Worker xorl rIBASE, rIBASE 893*795d594fSAndroid Build Coastguard Worker2: 894*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 895*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 896*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[BB+0] <- eax 897*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 898*795d594fSAndroid Build Coastguard Worker 899*795d594fSAndroid Build Coastguard Worker%def op_ushr_long_2addr(): 900*795d594fSAndroid Build Coastguard Worker/* 901*795d594fSAndroid Build Coastguard Worker * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 902*795d594fSAndroid Build Coastguard Worker * 32-bit shift distance. 903*795d594fSAndroid Build Coastguard Worker */ 904*795d594fSAndroid Build Coastguard Worker /* shl-long/2addr vA, vB */ 905*795d594fSAndroid Build Coastguard Worker /* ecx gets shift count */ 906*795d594fSAndroid Build Coastguard Worker /* Need to spill rIBASE */ 907*795d594fSAndroid Build Coastguard Worker /* rINSTw gets AA */ 908*795d594fSAndroid Build Coastguard Worker movzbl rINSTbl, %ecx # ecx <- BA 909*795d594fSAndroid Build Coastguard Worker andb $$0xf, rINSTbl # rINST <- A 910*795d594fSAndroid Build Coastguard Worker GET_VREG %eax, rINST # eax <- v[AA+0] 911*795d594fSAndroid Build Coastguard Worker sarl $$4, %ecx # ecx <- B 912*795d594fSAndroid Build Coastguard Worker movl rIBASE, LOCAL0(%esp) 913*795d594fSAndroid Build Coastguard Worker GET_VREG_HIGH rIBASE, rINST # rIBASE <- v[AA+1] 914*795d594fSAndroid Build Coastguard Worker GET_VREG %ecx, %ecx # ecx <- vBB 915*795d594fSAndroid Build Coastguard Worker shrdl rIBASE, %eax 916*795d594fSAndroid Build Coastguard Worker shrl %cl, rIBASE 917*795d594fSAndroid Build Coastguard Worker testb $$32, %cl 918*795d594fSAndroid Build Coastguard Worker je 2f 919*795d594fSAndroid Build Coastguard Worker movl rIBASE, %eax 920*795d594fSAndroid Build Coastguard Worker xorl rIBASE, rIBASE 921*795d594fSAndroid Build Coastguard Worker2: 922*795d594fSAndroid Build Coastguard Worker SET_VREG_HIGH rIBASE, rINST # v[AA+1] <- rIBASE 923*795d594fSAndroid Build Coastguard Worker movl LOCAL0(%esp), rIBASE 924*795d594fSAndroid Build Coastguard Worker SET_VREG %eax, rINST # v[AA+0] <- eax 925*795d594fSAndroid Build Coastguard Worker ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 926*795d594fSAndroid Build Coastguard Worker 927*795d594fSAndroid Build Coastguard Worker%def op_xor_int(): 928*795d594fSAndroid Build Coastguard Worker% binop(instr="xorl") 929*795d594fSAndroid Build Coastguard Worker 930*795d594fSAndroid Build Coastguard Worker%def op_xor_int_2addr(): 931*795d594fSAndroid Build Coastguard Worker% binop2addr(instr="xorl") 932*795d594fSAndroid Build Coastguard Worker 933*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit16(): 934*795d594fSAndroid Build Coastguard Worker% binopLit16(instr="xorl %ecx, %eax") 935*795d594fSAndroid Build Coastguard Worker 936*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit8(): 937*795d594fSAndroid Build Coastguard Worker% binopLit8(instr="xorl %ecx, %eax") 938*795d594fSAndroid Build Coastguard Worker 939*795d594fSAndroid Build Coastguard Worker%def op_xor_long(): 940*795d594fSAndroid Build Coastguard Worker% binopWide(instr1="xorl", instr2="xorl") 941*795d594fSAndroid Build Coastguard Worker 942*795d594fSAndroid Build Coastguard Worker%def op_xor_long_2addr(): 943*795d594fSAndroid Build Coastguard Worker% binopWide2addr(instr1="xorl", instr2="xorl") 944