1 | //===----------------------Hexagon builtin routine ------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #define A r1:0 |
10 | #define B r3:2 |
11 | #define ATMP r5:4 |
12 | |
13 | |
14 | #define Q6_ALIAS(TAG) .global __qdsp_##TAG ; .set __qdsp_##TAG, __hexagon_##TAG |
15 | #define END(TAG) .size TAG,.-TAG |
16 | |
17 | // Min and Max return A if B is NaN, or B if A is NaN |
18 | // Otherwise, they return the smaller or bigger value |
19 | // |
20 | // If values are equal, we want to favor -0.0 for min and +0.0 for max. |
21 | |
22 | // Compares always return false for NaN |
23 | // if (isnan(A)) A = B; if (A > B) A = B will only trigger at most one of those options. |
24 | |
25 | .text |
26 | .global __hexagon_mindf3 |
27 | .global __hexagon_maxdf3 |
28 | .global fmin |
29 | .type fmin,@function |
30 | .global fmax |
31 | .type fmax,@function |
32 | .type __hexagon_mindf3,@function |
33 | .type __hexagon_maxdf3,@function |
34 | Q6_ALIAS(mindf3) |
35 | Q6_ALIAS(maxdf3) |
36 | .p2align 5 |
37 | __hexagon_mindf3: |
38 | fmin: |
39 | { |
40 | p0 = dfclass(A,#0x10) // If A is a number |
41 | p1 = dfcmp.gt(A,B) // AND B > A, don't swap |
42 | ATMP = A |
43 | } |
44 | { |
45 | if (p0) A = B // if A is NaN use B |
46 | if (p1) A = B // gt is always false if either is NaN |
47 | p2 = dfcmp.eq(A,B) // if A == B |
48 | if (!p2.new) jumpr:t r31 |
49 | } |
50 | // A == B, return A|B to select -0.0 over 0.0 |
51 | { |
52 | A = or(ATMP,B) |
53 | jumpr r31 |
54 | } |
55 | END(__hexagon_mindf3) |
56 | .falign |
57 | __hexagon_maxdf3: |
58 | fmax: |
59 | { |
60 | p0 = dfclass(A,#0x10) |
61 | p1 = dfcmp.gt(B,A) |
62 | ATMP = A |
63 | } |
64 | { |
65 | if (p0) A = B |
66 | if (p1) A = B |
67 | p2 = dfcmp.eq(A,B) |
68 | if (!p2.new) jumpr:t r31 |
69 | } |
70 | // A == B, return A&B to select 0.0 over -0.0 |
71 | { |
72 | A = and(ATMP,B) |
73 | jumpr r31 |
74 | } |
75 | END(__hexagon_maxdf3) |
76 | |