master
h 69 lines 2.38 KB
Raw
1 /*
2 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #ifndef HEXAGON_HVX_IEEE_H
8 #define HEXAGON_HVX_IEEE_H
9
10 #include "fpu/softfloat.h"
11
12 #define FP32_DEF_NAN 0x7FFFFFFF
13
14 #define f16_to_f32(A) float16_to_float32((A), true, &env->hvx_fp_status)
15 #define f32_to_f16(A) float32_to_float16((A), true, &env->hvx_fp_status)
16 #define bf16_to_f32(A) bfloat16_to_float32(A, &env->hvx_fp_status)
17
18 float32 fp_mult_sf_hf(float16 a1, float16 a2, float_status *fp_status);
19 float32 fp_vdmpy(float16 a1, float16 a2, float16 a3, float16 a4,
20 float_status *fp_status);
21
22 /* Qfloat min/max treat +NaN as greater than +INF and -NaN as smaller than -INF */
23 float32 qf_max_sf(float32 a1, float32 a2, float_status *fp_status);
24 float32 qf_min_sf(float32 a1, float32 a2, float_status *fp_status);
25 float16 qf_max_hf(float16 a1, float16 a2, float_status *fp_status);
26 float16 qf_min_hf(float16 a1, float16 a2, float_status *fp_status);
27
28 int32_t conv_w_sf(float32 a, float_status *fp_status);
29 int16_t conv_h_hf(float16 a, float_status *fp_status);
30
31 /* IEEE - FP compare instructions */
32 uint32_t cmpgt_sf(float32 a1, float32 a2, float_status *fp_status);
33 uint16_t cmpgt_hf(float16 a1, float16 a2, float_status *fp_status);
34
35 /* IEEE BFloat instructions */
36
37 #define fp_mult_sf_bf(A, B) \
38 float32_mul(bf16_to_f32(A), bf16_to_f32(B), &env->hvx_fp_status)
39
40 #define fp_add_sf_bf(A, B) \
41 float32_add(bf16_to_f32(A), bf16_to_f32(B), &env->hvx_fp_status)
42
43 #define fp_sub_sf_bf(A, B) \
44 float32_sub(bf16_to_f32(A), bf16_to_f32(B), &env->hvx_fp_status)
45
46 #define fp_mult_sf_bf_acc(f1, f2, f3) \
47 float32_muladd(bf16_to_f32(f1), bf16_to_f32(f2), f3, 0, &env->hvx_fp_status)
48
49 static inline bfloat16 f32_to_bf16(float32 A, float_status *fp_status)
50 {
51 uint32_t rslt = A;
52 if ((rslt & 0x1FFFF) == 0x08000) {
53 /* do not round up if exactly .5 and even already */
54 } else if ((rslt & 0x8000) == 0x8000) {
55 rslt += 0x8000; /* rounding to nearest number */
56 }
57 rslt = float32_is_any_nan(A) ? FP32_DEF_NAN : rslt;
58 return float32_to_bfloat16(rslt, fp_status);
59 }
60
61 #define fp_min_bf(A, B) \
62 f32_to_bf16(float32_min(bf16_to_f32(A), bf16_to_f32(B), &env->hvx_fp_status), \
63 &env->hvx_fp_status);
64
65 #define fp_max_bf(A, B) \
66 f32_to_bf16(float32_max(bf16_to_f32(A), bf16_to_f32(B), &env->hvx_fp_status), \
67 &env->hvx_fp_status);
68
69 #endif