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