| 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 | |