1%default {"srcdouble":"1","tgtlong":"1"} 2/* On fp to int conversions, Java requires that 3 * if the result > maxint, it should be clamped to maxint. If it is less 4 * than minint, it should be clamped to minint. If it is a nan, the result 5 * should be zero. Further, the rounding mode is to truncate. This model 6 * differs from what is delivered normally via the x86 fpu, so we have 7 * to play some games. 8 */ 9 /* float/double to int/long vA, vB */ 10 movzbl rINSTbl, %ecx # ecx <- A+ 11 sarl $$4, rINST # rINST <- B 12 .if $srcdouble 13 fldl VREG_ADDRESS(rINST) # %st0 <- vB 14 .else 15 flds VREG_ADDRESS(rINST) # %st0 <- vB 16 .endif 17 ftst 18 fnstcw LOCAL0(%esp) # remember original rounding mode 19 movzwl LOCAL0(%esp), %eax 20 movb $$0xc, %ah 21 movw %ax, LOCAL0+2(%esp) 22 fldcw LOCAL0+2(%esp) # set "to zero" rounding mode 23 andb $$0xf, %cl # ecx <- A 24 .if $tgtlong 25 fistpll VREG_ADDRESS(%ecx) # convert and store 26 .else 27 fistpl VREG_ADDRESS(%ecx) # convert and store 28 .endif 29 fldcw LOCAL0(%esp) # restore previous rounding mode 30 .if $tgtlong 31 movl $$0x80000000, %eax 32 xorl VREG_HIGH_ADDRESS(%ecx), %eax 33 orl VREG_ADDRESS(%ecx), %eax 34 .else 35 cmpl $$0x80000000, VREG_ADDRESS(%ecx) 36 .endif 37 je .L${opcode}_special_case # fix up result 38 39.L${opcode}_finish: 40 xor %eax, %eax 41 mov %eax, VREG_REF_ADDRESS(%ecx) 42 .if $tgtlong 43 mov %eax, VREG_REF_HIGH_ADDRESS(%ecx) 44 .endif 45 ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 46 47.L${opcode}_special_case: 48 fnstsw %ax 49 sahf 50 jp .L${opcode}_isNaN 51 adcl $$-1, VREG_ADDRESS(%ecx) 52 .if $tgtlong 53 adcl $$-1, VREG_HIGH_ADDRESS(%ecx) 54 .endif 55 jmp .L${opcode}_finish 56.L${opcode}_isNaN: 57 movl $$0, VREG_ADDRESS(%ecx) 58 .if $tgtlong 59 movl $$0, VREG_HIGH_ADDRESS(%ecx) 60 .endif 61 jmp .L${opcode}_finish 62