Home | History | Annotate | Download | only in mips
      1 %verify "executed"
      2 %include "mips/unopNarrower.S" {"instr":"b d2i_doconv", "instr_f":"b d2i_doconv"}
      3 /*
      4  * Convert the double in a0/a1 to an int in a0.
      5  *
      6  * We have to clip values to int min/max per the specification.  The
      7  * expected common case is a "reasonable" value that converts directly
      8  * to modest integer.  The EABI convert function isn't doing this for us.
      9  * Use rBIX / rTEMP as global to hold arguments (they are not bound to a global var)
     10  */
     11 %break
     12 
     13 
     14 d2i_doconv:
     15 #ifdef SOFT_FLOAT
     16     la        t0, .LDOUBLE_TO_INT_max
     17     LOAD64(rARG2, rARG3, t0)
     18     move      rBIX, rARG0                  #  save a0
     19     move      rTEMP, rARG1                 #  and a1
     20     JAL(__gedf2)                           #  is arg >= maxint?
     21 
     22     move      t0, v0
     23     li        v0, ~0x80000000              #  return maxint (7fffffff)
     24     bgez      t0, .L${opcode}_set_vreg     #  nonzero == yes
     25 
     26     move      rARG0, rBIX                  #  recover arg
     27     move      rARG1, rTEMP
     28     la        t0, .LDOUBLE_TO_INT_min
     29     LOAD64(rARG2, rARG3, t0)
     30     JAL(__ledf2)                           #  is arg <= minint?
     31 
     32     move      t0, v0
     33     li        v0, 0x80000000               #  return minint (80000000)
     34     blez      t0, .L${opcode}_set_vreg     #  nonzero == yes
     35 
     36     move      rARG0, rBIX                  #  recover arg
     37     move      rARG1, rTEMP
     38     move      rARG2, rBIX                  #  compare against self
     39     move      rARG3, rTEMP
     40     JAL(__nedf2)                           #  is arg == self?
     41 
     42     move      t0, v0                       #  zero == no
     43     li        v0, 0
     44     bnez      t0, .L${opcode}_set_vreg     #  return zero for NaN
     45 
     46     move      rARG0, rBIX                  #  recover arg
     47     move      rARG1, rTEMP
     48     JAL(__fixdfsi)                         #  convert double to int
     49     b         .L${opcode}_set_vreg
     50 #else
     51     la        t0, .LDOUBLE_TO_INT_max
     52     LOAD64_F(fa1, fa1f, t0)
     53     c.ole.d   fcc0, fa1, fa0
     54     l.s       fv0, .LDOUBLE_TO_INT_maxret
     55     bc1t      .L${opcode}_set_vreg_f
     56 
     57     la        t0, .LDOUBLE_TO_INT_min
     58     LOAD64_F(fa1, fa1f, t0)
     59     c.ole.d   fcc0, fa0, fa1
     60     l.s       fv0, .LDOUBLE_TO_INT_minret
     61     bc1t      .L${opcode}_set_vreg_f
     62 
     63     mov.d     fa1, fa0
     64     c.un.d    fcc0, fa0, fa1
     65     li.s      fv0, 0
     66     bc1t      .L${opcode}_set_vreg_f
     67 
     68     trunc.w.d  fv0, fa0
     69     b         .L${opcode}_set_vreg_f
     70 #endif
     71 
     72 
     73 .LDOUBLE_TO_INT_max:
     74     .dword 0x41dfffffffc00000
     75 .LDOUBLE_TO_INT_min:
     76     .dword 0xc1e0000000000000              #  minint, as a double (high word)
     77 .LDOUBLE_TO_INT_maxret:
     78     .word 0x7fffffff
     79 .LDOUBLE_TO_INT_minret:
     80     .word 0x80000000
     81