• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1%default { "naninst":"mvn     r0, #0" }
2    /*
3     * For the JIT: incoming arguments in r0-r1, r2-r3
4     *              result in r0
5     *
6     * Compare two floating-point values.  Puts 0, 1, or -1 into the
7     * destination register based on the results of the comparison.
8     *
9     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
10     * on what value we'd like to return when one of the operands is NaN.
11     *
12     * The operation we're implementing is:
13     *   if (x == y)
14     *     return 0;
15     *   else if (x < y)
16     *     return -1;
17     *   else if (x > y)
18     *     return 1;
19     *   else
20     *     return {-1,1};  // one or both operands was NaN
21     *
22     * The straightforward implementation requires 3 calls to functions
23     * that return a result in r0.  We can do it with two calls if our
24     * EABI library supports __aeabi_cfcmple (only one if we want to check
25     * for NaN directly):
26     *   check x <= y
27     *     if <, return -1
28     *     if ==, return 0
29     *   check y <= x
30     *     if <, return 1
31     *   return {-1,1}
32     *
33     * for: cmpl-float, cmpg-float
34     */
35    /* op vAA, vBB, vCC */
36    mov     r9, r0                      @ Save copies - we may need to redo
37    mov     r10, r1
38    mov     r11, lr                     @ save return address
39    LDR_PC_LR ".L__aeabi_cfcmple"       @ cmp <=: C clear if <, Z set if eq
40    bhi     .L${opcode}_gt_or_nan       @ C set and Z clear, disambiguate
41    mvncc   r0, #0                      @ (less than) r0<- -1
42    moveq   r0, #0                      @ (equal) r0<- 0, trumps less than
43    bx      r11
44    @ Test for NaN with a second comparison.  EABI forbids testing bit
45    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
46    @ make the library call.
47.L${opcode}_gt_or_nan:
48    mov     r0, r10                     @ restore in reverse order
49    mov     r1, r9
50    LDR_PC_LR ".L__aeabi_cfcmple"       @ r0<- Z set if eq, C clear if <
51    movcc   r0, #1                      @ (greater than) r1<- 1
52    bxcc    r11
53    $naninst                            @ r1<- 1 or -1 for NaN
54    bx      r11
55