1 /* Copyright 2022 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Authors: AMD
22 *
23 */
24 #include "conversion.h"
25
26 #define DIVIDER 10000
27
28 /* S2D13 value in [-3.99...3.9999] */
29 #define S2D13_MIN ((long long)(-3.999 * DIVIDER))
30 #define S2D13_MAX ((long long)(3.999 * DIVIDER))
31
32 #define FRACTIONAL_PART_MASK ((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1)
33
34 #define GET_INTEGER_PART(x) ((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART)
35
36 #define GET_FRACTIONAL_PART(x) (FRACTIONAL_PART_MASK & (x))
37
conv_fixed_point_to_int_frac(struct fixed31_32 arg,uint8_t integer_bits,uint8_t fractional_bits)38 uint16_t conv_fixed_point_to_int_frac(
39 struct fixed31_32 arg, uint8_t integer_bits, uint8_t fractional_bits)
40 {
41 int32_t numerator;
42 int32_t divisor = 1 << fractional_bits;
43
44 uint16_t result;
45
46 uint16_t d = (uint16_t)vpe_fixpt_floor(vpe_fixpt_abs(arg));
47
48 if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
49 numerator = (uint16_t)vpe_fixpt_round(vpe_fixpt_mul_int(arg, divisor));
50 else {
51 numerator = vpe_fixpt_floor(vpe_fixpt_sub(
52 vpe_fixpt_from_int(1LL << integer_bits), vpe_fixpt_recip(vpe_fixpt_from_int(divisor))));
53 }
54
55 if (numerator >= 0)
56 result = (uint16_t)numerator;
57 else
58 result = (uint16_t)((1 << (integer_bits + fractional_bits + 1)) + numerator);
59
60 if ((result != 0) && vpe_fixpt_lt(arg, vpe_fixpt_zero))
61 result |= 1 << (integer_bits + fractional_bits);
62
63 return result;
64 }
65
conv_convert_float_matrix(uint16_t * matrix,const struct fixed31_32 * flt,uint32_t buffer_size)66 void conv_convert_float_matrix(uint16_t *matrix, const struct fixed31_32 *flt, uint32_t buffer_size)
67 {
68 const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
69 const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
70 uint32_t i;
71
72 for (i = 0; i < buffer_size; ++i) {
73 uint32_t reg_value =
74 conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
75
76 matrix[i] = (uint16_t)reg_value;
77 }
78 }
79
vpe_convfix31_32(int16_t inval)80 struct fixed31_32 vpe_convfix31_32(int16_t inval)
81 {
82 const int integerBits = 2;
83 const int fractionalBits = 13;
84 struct fixed31_32 result;
85 long long outintegerPart;
86 long long outfractionalPart;
87 int sign = 1;
88 if (inval & (1 << (integerBits + fractionalBits + 1))) {
89 sign = -1;
90 inval = -inval;
91 }
92 outintegerPart = ((long long)inval >> fractionalBits) << 32;
93 outfractionalPart = ((long long)inval & (((long long)1 << fractionalBits) - 1));
94 ;
95 outfractionalPart <<= (32 - fractionalBits);
96 result.value = outintegerPart | outfractionalPart;
97 if (sign < 0)
98 result.value = -result.value;
99 return result;
100 }
101