1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%default { "naninst":"mvn     r1, #0" }
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "executed"
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "basic lt, gt, eq */
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "left arg NaN"
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "right arg NaN"
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compare two floating-point values.  Puts 0, 1, or -1 into the
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * destination register based on the results of the comparison.
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * on what value we'd like to return when one of the operands is NaN.
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The operation we're implementing is:
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   if (x == y)
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     return 0;
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   else if (x < y)
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     return -1;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   else if (x > y)
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     return 1;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   else
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     return {-1,1};  // one or both operands was NaN
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The straightforward implementation requires 3 calls to functions
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that return a result in r0.  We can do it with two calls if our
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * EABI library supports __aeabi_cfcmple (only one if we want to check
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for NaN directly):
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   check x <= y
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     if <, return -1
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     if ==, return 0
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   check y <= x
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     if <, return 1
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   return {-1,1}
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for: cmpl-float, cmpg-float
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* op vAA, vBB, vCC */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH(r0, 1)                        @ r0<- CCBB
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    and     r2, r0, #255                @ r2<- BB
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r3, r0, lsr #8              @ r3<- CC
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_VREG(r9, r2)                    @ r9<- vBB
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_VREG(r10, r3)                   @ r10<- vCC
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, r9                      @ copy to arg registers
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r10
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      __aeabi_cfcmple             @ cmp <=: C clear if <, Z set if eq
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bhi     .L${opcode}_gt_or_nan       @ C set and Z clear, disambiguate
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mvncc   r1, #0                      @ (less than) r1<- -1
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_finish:
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r3, rINST, lsr #8           @ r3<- AA
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    SET_VREG(r1, r3)                    @ vAA<- r1
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GOTO_OPCODE(ip)                     @ jump to next instruction
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%break
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @ Test for NaN with a second comparison.  EABI forbids testing bit
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @ make the library call.
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_gt_or_nan:
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r9                      @ reverse order
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, r10
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      __aeabi_cfcmple             @ r0<- Z set if eq, C clear if <
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @bleq    common_abort
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movcc   r1, #1                      @ (greater than) r1<- 1
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bcc     .L${opcode}_finish
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    $naninst                            @ r1<- 1 or -1 for NaN
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    b       .L${opcode}_finish
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0       /* "clasic" form */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH(r0, 1)                        @ r0<- CCBB
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    and     r2, r0, #255                @ r2<- BB
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r3, r0, lsr #8              @ r3<- CC
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_VREG(r9, r2)                    @ r9<- vBB
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_VREG(r10, r3)                   @ r10<- vCC
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, r9                      @ r0<- vBB
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r10                     @ r1<- vCC
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      __aeabi_fcmpeq              @ r0<- (vBB == vCC)
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ equal?
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movne   r1, #0                      @ yes, result is 0
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bne     ${opcode}_finish
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, r9                      @ r0<- vBB
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r10                     @ r1<- vCC
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      __aeabi_fcmplt              @ r0<- (vBB < vCC)
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ less than?
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    b       ${opcode}_continue
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project@%break
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project${opcode}_continue:
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mvnne   r1, #0                      @ yes, result is -1
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bne     ${opcode}_finish
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, r9                      @ r0<- vBB
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r10                     @ r1<- vCC
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      __aeabi_fcmpgt              @ r0<- (vBB > vCC)
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ greater than?
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    beq     ${opcode}_nan               @ no, must be NaN
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, #1                      @ yes, result is 1
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @ fall through to _finish
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project${opcode}_finish:
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r3, rINST, lsr #8           @ r3<- AA
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    SET_VREG(r1, r3)                    @ vAA<- r1
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GOTO_OPCODE(ip)                     @ jump to next instruction
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is expected to be uncommon, so we double-branch (once to here,
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * again back to _finish).
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project${opcode}_nan:
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    $naninst                            @ r1<- 1 or -1 for NaN
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    b       ${opcode}_finish
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
116