• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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