%default {"srcdouble":"1","tgtlong":"1"} /* On fp to int conversions, Java requires that * if the result > maxint, it should be clamped to maxint. If it is less * than minint, it should be clamped to minint. If it is a nan, the result * should be zero. Further, the rounding mode is to truncate. This model * differs from what is delivered normally via the x86 fpu, so we have * to play some games. */ /* float/double to int/long vA, vB */ movzbl rINSTbl,%ecx # ecx<- A+ sarl $$4,rINST # rINST<- B .if $srcdouble fldl (rFP,rINST,4) # %st0<- vB .else flds (rFP,rINST,4) # %st0<- vB .endif ftst fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode movzwl LOCAL0_OFFSET(%ebp),%eax movb $$0xc,%ah movw %ax,LOCAL0_OFFSET+2(%ebp) fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode andb $$0xf,%cl # ecx<- A .if $tgtlong fistpll (rFP,%ecx,4) # convert and store .else fistpl (rFP,%ecx,4) # convert and store .endif fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode .if $tgtlong movl $$0x80000000,%eax xorl 4(rFP,%ecx,4),%eax orl (rFP,%ecx,4),%eax .else cmpl $$0x80000000,(rFP,%ecx,4) .endif je .L${opcode}_special_case # fix up result .L${opcode}_finish: FETCH_INST_OPCODE 1 %ecx ADVANCE_PC 1 GOTO_NEXT_R %ecx .L${opcode}_special_case: fnstsw %ax sahf jp .L${opcode}_isNaN adcl $$-1,(rFP,%ecx,4) .if $tgtlong adcl $$-1,4(rFP,%ecx,4) .endif jmp .L${opcode}_finish .L${opcode}_isNaN: movl $$0,(rFP,%ecx,4) .if $tgtlong movl $$0,4(rFP,%ecx,4) .endif jmp .L${opcode}_finish