%default { "naninst":"li rTEMP, -1" }
%verify "executed"
%verify "basic lt, gt, eq */
%verify "left arg NaN"
%verify "right arg NaN"
    /*
     * Compare two floating-point values.  Puts 0, 1, or -1 into the
     * destination register based on the results of the comparison.
     *
     * Provide a "naninst" instruction that puts 1 or -1 into a1 depending
     * on what value we'd like to return when one of the operands is NaN.
     *
     * The operation we're implementing is:
     *   if (x == y)
     *     return 0;
     *   else if (x < y)
     *     return -1;
     *   else if (x > y)
     *     return 1;
     *   else
     *     return {-1,1};  // one or both operands was NaN
     *
     * for: cmpl-float, cmpg-float
     */
    /* op vAA, vBB, vCC */

    /* "clasic" form */
    FETCH(a0, 1)                           #  a0 <- CCBB
    and       a2, a0, 255                  #  a2 <- BB
    srl       a3, a0, 8
#ifdef SOFT_FLOAT
    GET_VREG(rOBJ, a2)                     #  rOBJ <- vBB
    GET_VREG(rBIX, a3)                     #  rBIX <- vCC
    move      a0, rOBJ                     #  a0 <- vBB
    move      a1, rBIX                     #  a1 <- vCC
    JAL(__eqsf2)                           #  a0 <- (vBB == vCC)
    li        rTEMP, 0                     # set rTEMP to 0
    beqz      v0, ${opcode}_finish
    move      a0, rOBJ                     #  a0 <- vBB
    move      a1, rBIX                     #  a1 <- vCC
    JAL(__ltsf2)                           #  a0 <- (vBB < vCC)
    li        rTEMP, -1
    bltz      v0, ${opcode}_finish
    move      a0, rOBJ                     #  a0 <- vBB
    move      a1, rBIX                     #  a1 <- vCC
    b         ${opcode}_continue
#else
    GET_VREG_F(ft0, a2)
    GET_VREG_F(ft1, a3)
    c.olt.s   fcc0, ft0, ft1               # Is ft0 < ft1
    li        rTEMP, -1
    bc1t      fcc0, ${opcode}_finish
    c.olt.s   fcc0, ft1, ft0
    li        rTEMP, 1
    bc1t      fcc0, ${opcode}_finish
    c.eq.s    fcc0, ft0, ft1
    li        rTEMP, 0
    bc1t      fcc0, ${opcode}_finish
    b         ${opcode}_nan

#endif

%break

${opcode}_nan:
    $naninst
    b         ${opcode}_finish

#ifdef SOFT_FLOAT
${opcode}_continue:
    JAL(__gtsf2)                           #  v0 <- (vBB > vCC)
    li        rTEMP, 1                     #  rTEMP = 1 if v0 != 0
    bgtz      v0, ${opcode}_finish
    b         ${opcode}_nan
#endif

${opcode}_finish:
    GET_OPA(t0)
    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
    SET_VREG(rTEMP, t0)                    #  vAA <- rTEMP
    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    GOTO_OPCODE(t0)