1 /*
2 * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdint.h>
21
22 int err;
23
24 #include "hex_test.h"
25
26 #define NBITS 8
27 #define SIZE (1 << NBITS)
28
29 int64_t dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
30 int32_t wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
31 int16_t hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
32 uint8_t bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
33
34 /*
35 * We use the C preporcessor to deal with the combinations of types
36 */
37
38 #define BREV_LOAD(SZ, RES, ADDR, INC) \
39 __asm__( \
40 "m0 = %2\n\t" \
41 "%0 = mem" #SZ "(%1++m0:brev)\n\t" \
42 : "=r"(RES), "+r"(ADDR) \
43 : "r"(INC) \
44 : "m0")
45
46 #define BREV_LOAD_b(RES, ADDR, INC) \
47 BREV_LOAD(b, RES, ADDR, INC)
48 #define BREV_LOAD_ub(RES, ADDR, INC) \
49 BREV_LOAD(ub, RES, ADDR, INC)
50 #define BREV_LOAD_h(RES, ADDR, INC) \
51 BREV_LOAD(h, RES, ADDR, INC)
52 #define BREV_LOAD_uh(RES, ADDR, INC) \
53 BREV_LOAD(uh, RES, ADDR, INC)
54 #define BREV_LOAD_w(RES, ADDR, INC) \
55 BREV_LOAD(w, RES, ADDR, INC)
56 #define BREV_LOAD_d(RES, ADDR, INC) \
57 BREV_LOAD(d, RES, ADDR, INC)
58
59 #define BREV_STORE(SZ, PART, ADDR, VAL, INC) \
60 __asm__( \
61 "m0 = %2\n\t" \
62 "mem" #SZ "(%0++m0:brev) = %1" PART "\n\t" \
63 : "+r"(ADDR) \
64 : "r"(VAL), "r"(INC) \
65 : "m0", "memory")
66
67 #define BREV_STORE_b(ADDR, VAL, INC) \
68 BREV_STORE(b, "", ADDR, VAL, INC)
69 #define BREV_STORE_h(ADDR, VAL, INC) \
70 BREV_STORE(h, "", ADDR, VAL, INC)
71 #define BREV_STORE_f(ADDR, VAL, INC) \
72 BREV_STORE(h, ".H", ADDR, VAL, INC)
73 #define BREV_STORE_w(ADDR, VAL, INC) \
74 BREV_STORE(w, "", ADDR, VAL, INC)
75 #define BREV_STORE_d(ADDR, VAL, INC) \
76 BREV_STORE(d, "", ADDR, VAL, INC)
77
78 #define BREV_STORE_NEW(SZ, ADDR, VAL, INC) \
79 __asm__( \
80 "m0 = %2\n\t" \
81 "{\n\t" \
82 " r5 = %1\n\t" \
83 " mem" #SZ "(%0++m0:brev) = r5.new\n\t" \
84 "}\n\t" \
85 : "+r"(ADDR) \
86 : "r"(VAL), "r"(INC) \
87 : "r5", "m0", "memory")
88
89 #define BREV_STORE_bnew(ADDR, VAL, INC) \
90 BREV_STORE_NEW(b, ADDR, VAL, INC)
91 #define BREV_STORE_hnew(ADDR, VAL, INC) \
92 BREV_STORE_NEW(h, ADDR, VAL, INC)
93 #define BREV_STORE_wnew(ADDR, VAL, INC) \
94 BREV_STORE_NEW(w, ADDR, VAL, INC)
95
bitreverse(uint32_t x)96 uint32_t bitreverse(uint32_t x)
97 {
98 uint32_t result = 0;
99 for (int i = 0; i < NBITS; i++) {
100 result <<= 1;
101 result |= x & 1;
102 x >>= 1;
103 }
104 return result;
105 }
106
sext8(int32_t x)107 int32_t sext8(int32_t x)
108 {
109 return (x << 24) >> 24;
110 }
111
112 #define TEST_BREV_LOAD(SZ, TYPE, BUF, SHIFT, EXP) \
113 do { \
114 p = BUF; \
115 for (int i = 0; i < SIZE; i++) { \
116 TYPE result; \
117 BREV_LOAD_##SZ(result, p, 1 << (SHIFT - NBITS)); \
118 check32(result, EXP); \
119 } \
120 } while (0)
121
122 #define TEST_BREV_STORE(SZ, TYPE, BUF, VAL, SHIFT) \
123 do { \
124 p = BUF; \
125 memset(BUF, 0xff, sizeof(BUF)); \
126 for (int i = 0; i < SIZE; i++) { \
127 BREV_STORE_##SZ(p, (TYPE)(VAL), 1 << (SHIFT - NBITS)); \
128 } \
129 for (int i = 0; i < SIZE; i++) { \
130 check32(BUF[i], bitreverse(i)); \
131 } \
132 } while (0)
133
134 #define TEST_BREV_STORE_NEW(SZ, BUF, SHIFT) \
135 do { \
136 p = BUF; \
137 memset(BUF, 0xff, sizeof(BUF)); \
138 for (int i = 0; i < SIZE; i++) { \
139 BREV_STORE_##SZ(p, i, 1 << (SHIFT - NBITS)); \
140 } \
141 for (int i = 0; i < SIZE; i++) { \
142 check32(BUF[i], bitreverse(i)); \
143 } \
144 } while (0)
145
146 /*
147 * We'll set high_half[i] = i << 16 for use in the .H form of store
148 * which stores from the high half of the word.
149 */
150 int high_half[SIZE];
151
main()152 int main()
153 {
154 void *p;
155
156 for (int i = 0; i < SIZE; i++) {
157 bbuf[i] = bitreverse(i);
158 hbuf[i] = bitreverse(i);
159 wbuf[i] = bitreverse(i);
160 dbuf[i] = bitreverse(i);
161 high_half[i] = i << 16;
162 }
163
164 TEST_BREV_LOAD(b, int32_t, bbuf, 16, sext8(i));
165 TEST_BREV_LOAD(ub, int32_t, bbuf, 16, i);
166 TEST_BREV_LOAD(h, int32_t, hbuf, 15, i);
167 TEST_BREV_LOAD(uh, int32_t, hbuf, 15, i);
168 TEST_BREV_LOAD(w, int32_t, wbuf, 14, i);
169 TEST_BREV_LOAD(d, int64_t, dbuf, 13, i);
170
171 TEST_BREV_STORE(b, int32_t, bbuf, i, 16);
172 TEST_BREV_STORE(h, int32_t, hbuf, i, 15);
173 TEST_BREV_STORE(f, int32_t, hbuf, high_half[i], 15);
174 TEST_BREV_STORE(w, int32_t, wbuf, i, 14);
175 TEST_BREV_STORE(d, int64_t, dbuf, i, 13);
176
177 TEST_BREV_STORE_NEW(bnew, bbuf, 16);
178 TEST_BREV_STORE_NEW(hnew, hbuf, 15);
179 TEST_BREV_STORE_NEW(wnew, wbuf, 14);
180
181 puts(err ? "FAIL" : "PASS");
182 return err ? 1 : 0;
183 }
184