1%default { "naninst":"li rTEMP, -1" }
2    /*
3     * Compare two floating-point values. Puts 0(==), 1(>), or -1(<)
4     * into the destination register (rTEMP) based on the comparison results.
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     * See op_cmpl_float for more details.
10     *
11     * For: cmpl-double, cmpg-double
12     */
13    /* op vAA, vBB, vCC */
14
15    FETCH(a0, 1)                           #  a0 <- CCBB
16    and       rOBJ, a0, 255                #  s5 <- BB
17    srl       t0, a0, 8                    #  t0 <- CC
18    EAS2(rOBJ, rFP, rOBJ)                  #  s5 <- &fp[BB]
19    EAS2(t0, rFP, t0)                      #  t0 <- &fp[CC]
20    LOAD64_F(ft0, ft0f, rOBJ)
21    LOAD64_F(ft1, ft1f, t0)
22#ifdef MIPS32REVGE6
23    cmp.ult.d ft2, ft0, ft1
24    li        rTEMP, -1
25    bc1nez    ft2, .L${opcode}_finish
26    cmp.ult.d ft2, ft1, ft0
27    li        rTEMP, 1
28    bc1nez    ft2, .L${opcode}_finish
29    cmp.eq.d  ft2, ft0, ft1
30    li        rTEMP, 0
31    bc1nez    ft2, .L${opcode}_finish
32    b         .L${opcode}_nan
33#else
34    c.olt.d   fcc0, ft0, ft1
35    li        rTEMP, -1
36    bc1t      fcc0, .L${opcode}_finish
37    c.olt.d   fcc0, ft1, ft0
38    li        rTEMP, 1
39    bc1t      fcc0, .L${opcode}_finish
40    c.eq.d    fcc0, ft0, ft1
41    li        rTEMP, 0
42    bc1t      fcc0, .L${opcode}_finish
43    b         .L${opcode}_nan
44#endif
45%break
46
47.L${opcode}_nan:
48    $naninst
49
50.L${opcode}_finish:
51    GET_OPA(rOBJ)
52    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
53    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
54    SET_VREG_GOTO(rTEMP, rOBJ, t0)         #  vAA <- rTEMP
55