]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/hexagon/dfminmax.S
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / builtins / hexagon / dfminmax.S
1 //===----------------------Hexagon builtin routine ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #define A r1:0
11 #define B r3:2
12 #define ATMP r5:4
13
14
15 #define Q6_ALIAS(TAG) .global __qdsp_##TAG ; .set __qdsp_##TAG, __hexagon_##TAG
16 #define END(TAG) .size TAG,.-TAG
17
18 /*
19  * Min and Max return A if B is NaN, or B if A is NaN
20  * Otherwise, they return the smaller or bigger value
21  *
22  * If values are equal, we want to favor -0.0 for min and +0.0 for max.
23  */
24
25 /*
26  * Compares always return false for NaN
27  * if (isnan(A)) A = B; if (A > B) A = B will only trigger at most one of those options.
28  */
29         .text
30         .global __hexagon_mindf3
31         .global __hexagon_maxdf3
32         .global fmin
33         .type fmin,@function
34         .global fmax
35         .type fmax,@function
36         .type __hexagon_mindf3,@function
37         .type __hexagon_maxdf3,@function
38         Q6_ALIAS(mindf3)
39         Q6_ALIAS(maxdf3)
40         .p2align 5
41 __hexagon_mindf3:
42 fmin:
43         {
44                 p0 = dfclass(A,#0x10)           // If A is a number
45                 p1 = dfcmp.gt(A,B)              // AND B > A, don't swap
46                 ATMP = A
47         }
48         {
49                 if (p0) A = B                   // if A is NaN use B
50                 if (p1) A = B                   // gt is always false if either is NaN
51                 p2 = dfcmp.eq(A,B)              // if A == B
52                 if (!p2.new) jumpr:t r31
53         }
54         /* A == B, return A|B to select -0.0 over 0.0 */
55         {
56                 A = or(ATMP,B)
57                 jumpr r31
58         }
59 END(__hexagon_mindf3)
60         .falign
61 __hexagon_maxdf3:
62 fmax:
63         {
64                 p0 = dfclass(A,#0x10)
65                 p1 = dfcmp.gt(B,A)
66                 ATMP = A
67         }
68         {
69                 if (p0) A = B
70                 if (p1) A = B
71                 p2 = dfcmp.eq(A,B)
72                 if (!p2.new) jumpr:t r31
73         }
74         /* A == B, return A&B to select 0.0 over -0.0 */
75         {
76                 A = and(ATMP,B)
77                 jumpr r31
78         }
79 END(__hexagon_maxdf3)