blob: 759094376cba7a11033d94544c21a1c06e5c2c97 [file] [log] [blame]
%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