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