Home | History | Annotate | Download | only in mips
      1 %default { "naninst":"li rTEMP, -1" }
      2 %verify "executed"
      3 %verify "basic lt, gt, eq */
      4 %verify "left arg NaN"
      5 %verify "right arg NaN"
      6     /*
      7      * Compare two floating-point values.  Puts 0, 1, or -1 into the
      8      * destination register based on the results of the comparison.
      9      *
     10      * Provide a "naninst" instruction that puts 1 or -1 into a1 depending
     11      * on what value we'd like to return when one of the operands is NaN.
     12      *
     13      * The operation we're implementing is:
     14      *   if (x == y)
     15      *     return 0;
     16      *   else if (x < y)
     17      *     return -1;
     18      *   else if (x > y)
     19      *     return 1;
     20      *   else
     21      *     return {-1,1};  // one or both operands was NaN
     22      *
     23      * for: cmpl-float, cmpg-float
     24      */
     25     /* op vAA, vBB, vCC */
     26 
     27     /* "clasic" form */
     28     FETCH(a0, 1)                           #  a0 <- CCBB
     29     and       a2, a0, 255                  #  a2 <- BB
     30     srl       a3, a0, 8
     31 #ifdef SOFT_FLOAT
     32     GET_VREG(rOBJ, a2)                     #  rOBJ <- vBB
     33     GET_VREG(rBIX, a3)                     #  rBIX <- vCC
     34     move      a0, rOBJ                     #  a0 <- vBB
     35     move      a1, rBIX                     #  a1 <- vCC
     36     JAL(__eqsf2)                           #  a0 <- (vBB == vCC)
     37     li        rTEMP, 0                     # set rTEMP to 0
     38     beqz      v0, ${opcode}_finish
     39     move      a0, rOBJ                     #  a0 <- vBB
     40     move      a1, rBIX                     #  a1 <- vCC
     41     JAL(__ltsf2)                           #  a0 <- (vBB < vCC)
     42     li        rTEMP, -1
     43     bltz      v0, ${opcode}_finish
     44     move      a0, rOBJ                     #  a0 <- vBB
     45     move      a1, rBIX                     #  a1 <- vCC
     46     b         ${opcode}_continue
     47 #else
     48     GET_VREG_F(ft0, a2)
     49     GET_VREG_F(ft1, a3)
     50     c.olt.s   fcc0, ft0, ft1               # Is ft0 < ft1
     51     li        rTEMP, -1
     52     bc1t      fcc0, ${opcode}_finish
     53     c.olt.s   fcc0, ft1, ft0
     54     li        rTEMP, 1
     55     bc1t      fcc0, ${opcode}_finish
     56     c.eq.s    fcc0, ft0, ft1
     57     li        rTEMP, 0
     58     bc1t      fcc0, ${opcode}_finish
     59     b         ${opcode}_nan
     60 
     61 #endif
     62 
     63 %break
     64 
     65 ${opcode}_nan:
     66     $naninst
     67     b         ${opcode}_finish
     68 
     69 #ifdef SOFT_FLOAT
     70 ${opcode}_continue:
     71     JAL(__gtsf2)                           #  v0 <- (vBB > vCC)
     72     li        rTEMP, 1                     #  rTEMP = 1 if v0 != 0
     73     bgtz      v0, ${opcode}_finish
     74     b         ${opcode}_nan
     75 #endif
     76 
     77 ${opcode}_finish:
     78     GET_OPA(t0)
     79     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
     80     SET_VREG(rTEMP, t0)                    #  vAA <- rTEMP
     81     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     82     GOTO_OPCODE(t0)
     83