blob: b8c0961e672bf1eb5ab2e52965c1a23a9be2c6bf [file] [log] [blame]
Douglas Leung200f0402016-02-25 20:05:47 -08001%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
Alexey Frunze28d06c12016-10-20 21:50:05 -070030 cmp.lt.s ft2, ft0, ft1 # Is ft0 < ft1
Douglas Leung200f0402016-02-25 20:05:47 -080031 li rTEMP, -1
32 bc1nez ft2, .L${opcode}_finish
Alexey Frunze28d06c12016-10-20 21:50:05 -070033 cmp.lt.s ft2, ft1, ft0
Douglas Leung200f0402016-02-25 20:05:47 -080034 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