blob: 78d4a8f5c7a9f99838a573083c1aa52c414cd5a5 [file] [log] [blame]
Alexey Frunze84603bf2016-10-21 19:54:43 -07001 /*
2 * double-to-long
3 *
4 * We have to clip values to long min/max per the specification. The
5 * expected common case is a "reasonable" value that converts directly
6 * to modest integer. The EABI convert function isn't doing this for us.
7 */
8 /* unop vA, vB */
9 GET_OPA4(rOBJ) # rOBJ <- A+
10 GET_OPB(a3) # a3 <- B
11 EAS2(a3, rFP, a3) # a3 <- &fp[B]
12 LOAD64_F(fa0, fa0f, a3)
13 FETCH_ADVANCE_INST(1) # advance rPC, load rINST
14
15#ifdef MIPS32REVGE6
16 /*
17 * TODO: simplify this when the MIPS64R6 emulator
18 * supports NAN2008=1.
19 */
20 li t0, LONG_MIN_AS_DOUBLE_HIGH
21 mtc1 zero, fa1
22 mthc1 t0, fa1
23 cmp.le.d ft0, fa1, fa0
24 GET_INST_OPCODE(t1) # extract opcode from rINST
25 bc1nez ft0, 1f # if LONG_MIN <= vB, proceed to truncation
26 cmp.eq.d ft0, fa0, fa0
27 selnez.d fa0, fa1, ft0 # fa0 = ordered(vB) ? LONG_MIN_AS_DOUBLE : 0
281:
29 trunc.l.d fa0, fa0
30 SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
31#else
32 c.eq.d fcc0, fa0, fa0
33 li rRESULT0, 0
34 li rRESULT1, 0
35 bc1f fcc0, .L${opcode}_get_opcode
36
37 li t0, LONG_MIN_AS_DOUBLE_HIGH
38 mtc1 zero, fa1
39 MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
40 c.ole.d fcc0, fa0, fa1
41 li rRESULT1, LONG_MIN_HIGH
42 bc1t fcc0, .L${opcode}_get_opcode
43
44 neg.d fa1, fa1
45 c.ole.d fcc0, fa1, fa0
46 nor rRESULT0, rRESULT0, zero
47 nor rRESULT1, rRESULT1, zero
48 bc1t fcc0, .L${opcode}_get_opcode
49
50 JAL(__fixdfdi)
51 GET_INST_OPCODE(t1) # extract opcode from rINST
52 b .L${opcode}_set_vreg
53#endif
Douglas Leung200f0402016-02-25 20:05:47 -080054%break
55
Alexey Frunze84603bf2016-10-21 19:54:43 -070056#ifndef MIPS32REVGE6
57.L${opcode}_get_opcode:
58 GET_INST_OPCODE(t1) # extract opcode from rINST
59.L${opcode}_set_vreg:
60 SET_VREG64_GOTO(rRESULT0, rRESULT1, rOBJ, t1) # vA/vA+1 <- v0/v1
Douglas Leung200f0402016-02-25 20:05:47 -080061#endif