Home | History | Annotate | Download | only in mips
      1 %default { "naninst":"li rTEMP, -1" }
      2     /*
      3      * Compare two floating-point values.  Puts 0, 1, or -1 into the
      4      * destination register rTEMP based on the results of the comparison.
      5      *
      6      * Provide a "naninst" instruction that puts 1 or -1 into rTEMP depending
      7      * on what value we'd like to return when one of the operands is NaN.
      8      *
      9      * The operation we're implementing is:
     10      *   if (x == y)
     11      *     return 0;
     12      *   else if (x < y)
     13      *     return -1;
     14      *   else if (x > y)
     15      *     return 1;
     16      *   else
     17      *     return {-1 or 1};  // one or both operands was NaN
     18      *
     19      * for: cmpl-float, cmpg-float
     20      */
     21     /* op vAA, vBB, vCC */
     22 
     23     /* "clasic" form */
     24     FETCH(a0, 1)                           #  a0 <- CCBB
     25     and       a2, a0, 255                  #  a2 <- BB
     26     srl       a3, a0, 8
     27     GET_VREG_F(ft0, a2)
     28     GET_VREG_F(ft1, a3)
     29 #ifdef MIPS32REVGE6
     30     cmp.ult.s ft2, ft0, ft1               # Is ft0 < ft1
     31     li        rTEMP, -1
     32     bc1nez    ft2, .L${opcode}_finish
     33     cmp.ult.s ft2, ft1, ft0
     34     li        rTEMP, 1
     35     bc1nez    ft2, .L${opcode}_finish
     36     cmp.eq.s  ft2, ft0, ft1
     37     li        rTEMP, 0
     38     bc1nez    ft2, .L${opcode}_finish
     39     b         .L${opcode}_nan
     40 #else
     41     c.olt.s   fcc0, ft0, ft1               # Is ft0 < ft1
     42     li        rTEMP, -1
     43     bc1t      fcc0, .L${opcode}_finish
     44     c.olt.s   fcc0, ft1, ft0
     45     li        rTEMP, 1
     46     bc1t      fcc0, .L${opcode}_finish
     47     c.eq.s    fcc0, ft0, ft1
     48     li        rTEMP, 0
     49     bc1t      fcc0, .L${opcode}_finish
     50     b         .L${opcode}_nan
     51 #endif
     52 %break
     53 
     54 .L${opcode}_nan:
     55     $naninst
     56 
     57 .L${opcode}_finish:
     58     GET_OPA(rOBJ)
     59     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
     60     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     61     SET_VREG_GOTO(rTEMP, rOBJ, t0)         #  vAA <- rTEMP
     62