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 rINST_HI,%ecx # ecx<- A+ 11 sarl $$12,rINST_FULL # rINST_FULL<- B 12 .if $srcdouble 13 fldl (rFP,rINST_FULL,4) # %st0<- vB 14 .else 15 flds (rFP,rINST_FULL,4) # %st0<- vB 16 .endif 17 ftst 18 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 19 movzwl LOCAL0_OFFSET(%ebp),%eax 20 movb $$0xc,%ah 21 movw %ax,LOCAL0_OFFSET+2(%ebp) 22 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 23 FETCH_INST_WORD(1) 24 andb $$0xf,%cl # ecx<- A 25 .if $tgtlong 26 fistpll (rFP,%ecx,4) # convert and store 27 .else 28 fistpl (rFP,%ecx,4) # convert and store 29 .endif 30 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 31 jmp .L${opcode}_continue 32 %break 33 34 35 .L${opcode}_continue: 36 .if $tgtlong 37 movl $$0x80000000,%eax 38 xorl 4(rFP,%ecx,4),%eax 39 orl (rFP,%ecx,4),%eax 40 .else 41 cmpl $$0x80000000,(rFP,%ecx,4) 42 .endif 43 je .L${opcode}_special_case # fix up result 44 45 .L${opcode}_finish: 46 ADVANCE_PC(1) 47 GOTO_NEXT 48 49 .L${opcode}_special_case: 50 fnstsw %ax 51 sahf 52 jp .L${opcode}_isNaN 53 adcl $$-1,(rFP,%ecx,4) 54 .if $tgtlong 55 adcl $$-1,4(rFP,%ecx,4) 56 .endif 57 jmp .L${opcode}_finish 58 .L${opcode}_isNaN: 59 movl $$0,(rFP,%ecx,4) 60 .if $tgtlong 61 movl $$0,4(rFP,%ecx,4) 62 .endif 63 jmp .L${opcode}_finish 64