OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / dalvik / vm / mterp / x86 / cvtfp_int.S
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