Home | History | Annotate | Download | only in x86
      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