xref: /openbmc/qemu/tests/tcg/hexagon/load_align.c (revision 9c9fff18c45b54fd9adf2282323aab1b6f0ec866)
17aa9ffabSTaylor Simpson /*
2*0d57cd61STaylor Simpson  *  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
37aa9ffabSTaylor Simpson  *
47aa9ffabSTaylor Simpson  *  This program is free software; you can redistribute it and/or modify
57aa9ffabSTaylor Simpson  *  it under the terms of the GNU General Public License as published by
67aa9ffabSTaylor Simpson  *  the Free Software Foundation; either version 2 of the License, or
77aa9ffabSTaylor Simpson  *  (at your option) any later version.
87aa9ffabSTaylor Simpson  *
97aa9ffabSTaylor Simpson  *  This program is distributed in the hope that it will be useful,
107aa9ffabSTaylor Simpson  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
117aa9ffabSTaylor Simpson  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
127aa9ffabSTaylor Simpson  *  GNU General Public License for more details.
137aa9ffabSTaylor Simpson  *
147aa9ffabSTaylor Simpson  *  You should have received a copy of the GNU General Public License
157aa9ffabSTaylor Simpson  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
167aa9ffabSTaylor Simpson  */
177aa9ffabSTaylor Simpson 
187aa9ffabSTaylor Simpson /*
197aa9ffabSTaylor Simpson  * Test load align instructions
207aa9ffabSTaylor Simpson  *
217aa9ffabSTaylor Simpson  * Example
227aa9ffabSTaylor Simpson  *     r1:0 = memh_fifo(r1+#0)
237aa9ffabSTaylor Simpson  * loads a half word from memory, shifts the destination register
247aa9ffabSTaylor Simpson  * right by one half word and inserts the loaded value into the high
257aa9ffabSTaylor Simpson  * half word of the destination.
267aa9ffabSTaylor Simpson  *
277aa9ffabSTaylor Simpson  * There are 8 addressing modes and byte and half word variants, for a
287aa9ffabSTaylor Simpson  * total of 16 instructions to test
297aa9ffabSTaylor Simpson  */
307aa9ffabSTaylor Simpson 
317aa9ffabSTaylor Simpson #include <stdio.h>
32*0d57cd61STaylor Simpson #include <stdint.h>
337aa9ffabSTaylor Simpson #include <string.h>
347aa9ffabSTaylor Simpson 
357aa9ffabSTaylor Simpson int err;
367aa9ffabSTaylor Simpson 
37*0d57cd61STaylor Simpson #include "hex_test.h"
38*0d57cd61STaylor Simpson 
39*0d57cd61STaylor Simpson int8_t buf[16] __attribute__((aligned(1 << 16)));
407aa9ffabSTaylor Simpson 
init_buf(void)417aa9ffabSTaylor Simpson void init_buf(void)
427aa9ffabSTaylor Simpson {
43*0d57cd61STaylor Simpson     for (int i = 0; i < 16; i++) {
447aa9ffabSTaylor Simpson         buf[i] = i + 1;
457aa9ffabSTaylor Simpson     }
467aa9ffabSTaylor Simpson }
477aa9ffabSTaylor Simpson 
487aa9ffabSTaylor Simpson /*
497aa9ffabSTaylor Simpson  ****************************************************************************
507aa9ffabSTaylor Simpson  * _io addressing mode (addr + offset)
517aa9ffabSTaylor Simpson  */
527aa9ffabSTaylor Simpson #define LOAD_io(SZ, RES, ADDR, OFF) \
537aa9ffabSTaylor Simpson     __asm__( \
547aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1+#" #OFF ")\n\t" \
557aa9ffabSTaylor Simpson         : "+r"(RES) \
567aa9ffabSTaylor Simpson         : "r"(ADDR))
577aa9ffabSTaylor Simpson #define LOAD_io_b(RES, ADDR, OFF) \
587aa9ffabSTaylor Simpson     LOAD_io(b, RES, ADDR, OFF)
597aa9ffabSTaylor Simpson #define LOAD_io_h(RES, ADDR, OFF) \
607aa9ffabSTaylor Simpson     LOAD_io(h, RES, ADDR, OFF)
617aa9ffabSTaylor Simpson 
627aa9ffabSTaylor Simpson #define TEST_io(NAME, SZ, SIZE, EXP1, EXP2, EXP3, EXP4) \
637aa9ffabSTaylor Simpson void test_##NAME(void) \
647aa9ffabSTaylor Simpson { \
65*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
667aa9ffabSTaylor Simpson     LOAD_io_##SZ(result, buf, 0 * (SIZE)); \
67*0d57cd61STaylor Simpson     check64(result, (EXP1)); \
687aa9ffabSTaylor Simpson     LOAD_io_##SZ(result, buf, 1 * (SIZE)); \
69*0d57cd61STaylor Simpson     check64(result, (EXP2)); \
707aa9ffabSTaylor Simpson     LOAD_io_##SZ(result, buf, 2 * (SIZE)); \
71*0d57cd61STaylor Simpson     check64(result, (EXP3)); \
727aa9ffabSTaylor Simpson     LOAD_io_##SZ(result, buf, 3 * (SIZE)); \
73*0d57cd61STaylor Simpson     check64(result, (EXP4)); \
747aa9ffabSTaylor Simpson }
757aa9ffabSTaylor Simpson 
767aa9ffabSTaylor Simpson TEST_io(loadalignb_io, b, 1,
777aa9ffabSTaylor Simpson         0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
787aa9ffabSTaylor Simpson         0x030201ffffffffffLL, 0x04030201ffffffffLL)
797aa9ffabSTaylor Simpson TEST_io(loadalignh_io, h, 2,
807aa9ffabSTaylor Simpson         0x0201ffffffffffffLL, 0x04030201ffffffffLL,
817aa9ffabSTaylor Simpson         0x060504030201ffffLL, 0x0807060504030201LL)
827aa9ffabSTaylor Simpson 
837aa9ffabSTaylor Simpson /*
847aa9ffabSTaylor Simpson  ****************************************************************************
857aa9ffabSTaylor Simpson  * _ur addressing mode (index << offset + base)
867aa9ffabSTaylor Simpson  */
877aa9ffabSTaylor Simpson #define LOAD_ur(SZ, RES, SHIFT, IDX) \
887aa9ffabSTaylor Simpson     __asm__( \
897aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1<<#" #SHIFT " + ##buf)\n\t" \
907aa9ffabSTaylor Simpson         : "+r"(RES) \
917aa9ffabSTaylor Simpson         : "r"(IDX))
927aa9ffabSTaylor Simpson #define LOAD_ur_b(RES, SHIFT, IDX) \
937aa9ffabSTaylor Simpson     LOAD_ur(b, RES, SHIFT, IDX)
947aa9ffabSTaylor Simpson #define LOAD_ur_h(RES, SHIFT, IDX) \
957aa9ffabSTaylor Simpson     LOAD_ur(h, RES, SHIFT, IDX)
967aa9ffabSTaylor Simpson 
977aa9ffabSTaylor Simpson #define TEST_ur(NAME, SZ, SHIFT, RES1, RES2, RES3, RES4) \
987aa9ffabSTaylor Simpson void test_##NAME(void) \
997aa9ffabSTaylor Simpson { \
100*0d57cd61STaylor Simpson     uint64_t result = ~0LL; \
1017aa9ffabSTaylor Simpson     LOAD_ur_##SZ(result, (SHIFT), 0); \
102*0d57cd61STaylor Simpson     check64(result, (RES1)); \
1037aa9ffabSTaylor Simpson     LOAD_ur_##SZ(result, (SHIFT), 1); \
104*0d57cd61STaylor Simpson     check64(result, (RES2)); \
1057aa9ffabSTaylor Simpson     LOAD_ur_##SZ(result, (SHIFT), 2); \
106*0d57cd61STaylor Simpson     check64(result, (RES3)); \
1077aa9ffabSTaylor Simpson     LOAD_ur_##SZ(result, (SHIFT), 3); \
108*0d57cd61STaylor Simpson     check64(result, (RES4)); \
1097aa9ffabSTaylor Simpson }
1107aa9ffabSTaylor Simpson 
1117aa9ffabSTaylor Simpson TEST_ur(loadalignb_ur, b, 1,
1127aa9ffabSTaylor Simpson         0x01ffffffffffffffLL, 0x0301ffffffffffffLL,
1137aa9ffabSTaylor Simpson         0x050301ffffffffffLL, 0x07050301ffffffffLL)
1147aa9ffabSTaylor Simpson TEST_ur(loadalignh_ur, h, 1,
1157aa9ffabSTaylor Simpson         0x0201ffffffffffffLL, 0x04030201ffffffffLL,
1167aa9ffabSTaylor Simpson         0x060504030201ffffLL, 0x0807060504030201LL)
1177aa9ffabSTaylor Simpson 
1187aa9ffabSTaylor Simpson /*
1197aa9ffabSTaylor Simpson  ****************************************************************************
1207aa9ffabSTaylor Simpson  * _ap addressing mode (addr = base)
1217aa9ffabSTaylor Simpson  */
1227aa9ffabSTaylor Simpson #define LOAD_ap(SZ, RES, PTR, ADDR) \
1237aa9ffabSTaylor Simpson     __asm__(  \
1247aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1 = ##" #ADDR ")\n\t" \
1257aa9ffabSTaylor Simpson         : "+r"(RES), "=r"(PTR))
1267aa9ffabSTaylor Simpson #define LOAD_ap_b(RES, PTR, ADDR) \
1277aa9ffabSTaylor Simpson     LOAD_ap(b, RES, PTR, ADDR)
1287aa9ffabSTaylor Simpson #define LOAD_ap_h(RES, PTR, ADDR) \
1297aa9ffabSTaylor Simpson     LOAD_ap(h, RES, PTR, ADDR)
1307aa9ffabSTaylor Simpson 
1317aa9ffabSTaylor Simpson #define TEST_ap(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
1327aa9ffabSTaylor Simpson void test_##NAME(void) \
1337aa9ffabSTaylor Simpson { \
134*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
1357aa9ffabSTaylor Simpson     void *ptr; \
1367aa9ffabSTaylor Simpson     LOAD_ap_##SZ(result, ptr, (buf + 0 * (SIZE))); \
137*0d57cd61STaylor Simpson     check64(result, (RES1)); \
1387aa9ffabSTaylor Simpson     checkp(ptr, &buf[0 * (SIZE)]); \
1397aa9ffabSTaylor Simpson     LOAD_ap_##SZ(result, ptr, (buf + 1 * (SIZE))); \
140*0d57cd61STaylor Simpson     check64(result, (RES2)); \
1417aa9ffabSTaylor Simpson     checkp(ptr, &buf[1 * (SIZE)]); \
1427aa9ffabSTaylor Simpson     LOAD_ap_##SZ(result, ptr, (buf + 2 * (SIZE))); \
143*0d57cd61STaylor Simpson     check64(result, (RES3)); \
1447aa9ffabSTaylor Simpson     checkp(ptr, &buf[2 * (SIZE)]); \
1457aa9ffabSTaylor Simpson     LOAD_ap_##SZ(result, ptr, (buf + 3 * (SIZE))); \
146*0d57cd61STaylor Simpson     check64(result, (RES4)); \
1477aa9ffabSTaylor Simpson     checkp(ptr, &buf[3 * (SIZE)]); \
1487aa9ffabSTaylor Simpson }
1497aa9ffabSTaylor Simpson 
1507aa9ffabSTaylor Simpson TEST_ap(loadalignb_ap, b, 1,
1517aa9ffabSTaylor Simpson         0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
1527aa9ffabSTaylor Simpson         0x030201ffffffffffLL, 0x04030201ffffffffLL)
1537aa9ffabSTaylor Simpson TEST_ap(loadalignh_ap, h, 2,
1547aa9ffabSTaylor Simpson         0x0201ffffffffffffLL, 0x04030201ffffffffLL,
1557aa9ffabSTaylor Simpson         0x060504030201ffffLL, 0x0807060504030201LL)
1567aa9ffabSTaylor Simpson 
1577aa9ffabSTaylor Simpson /*
1587aa9ffabSTaylor Simpson  ****************************************************************************
1597aa9ffabSTaylor Simpson  * _rp addressing mode (addr ++ modifer-reg)
1607aa9ffabSTaylor Simpson  */
1617aa9ffabSTaylor Simpson #define LOAD_pr(SZ, RES, PTR, INC) \
1627aa9ffabSTaylor Simpson     __asm__( \
1637aa9ffabSTaylor Simpson         "m0 = %2\n\t" \
1647aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1++m0)\n\t" \
1657aa9ffabSTaylor Simpson         : "+r"(RES), "+r"(PTR) \
1667aa9ffabSTaylor Simpson         : "r"(INC) \
1677aa9ffabSTaylor Simpson         : "m0")
1687aa9ffabSTaylor Simpson #define LOAD_pr_b(RES, PTR, INC) \
1697aa9ffabSTaylor Simpson     LOAD_pr(b, RES, PTR, INC)
1707aa9ffabSTaylor Simpson #define LOAD_pr_h(RES, PTR, INC) \
1717aa9ffabSTaylor Simpson     LOAD_pr(h, RES, PTR, INC)
1727aa9ffabSTaylor Simpson 
1737aa9ffabSTaylor Simpson #define TEST_pr(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
1747aa9ffabSTaylor Simpson void test_##NAME(void) \
1757aa9ffabSTaylor Simpson { \
176*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
1777aa9ffabSTaylor Simpson     void *ptr = buf; \
1787aa9ffabSTaylor Simpson     LOAD_pr_##SZ(result, ptr, (SIZE)); \
179*0d57cd61STaylor Simpson     check64(result, (RES1)); \
1807aa9ffabSTaylor Simpson     checkp(ptr, &buf[1 * (SIZE)]); \
1817aa9ffabSTaylor Simpson     LOAD_pr_##SZ(result, ptr, (SIZE)); \
182*0d57cd61STaylor Simpson     check64(result, (RES2)); \
1837aa9ffabSTaylor Simpson     checkp(ptr, &buf[2 * (SIZE)]); \
1847aa9ffabSTaylor Simpson     LOAD_pr_##SZ(result, ptr, (SIZE)); \
185*0d57cd61STaylor Simpson     check64(result, (RES3)); \
1867aa9ffabSTaylor Simpson     checkp(ptr, &buf[3 * (SIZE)]); \
1877aa9ffabSTaylor Simpson     LOAD_pr_##SZ(result, ptr, (SIZE)); \
188*0d57cd61STaylor Simpson     check64(result, (RES4)); \
1897aa9ffabSTaylor Simpson     checkp(ptr, &buf[4 * (SIZE)]); \
1907aa9ffabSTaylor Simpson }
1917aa9ffabSTaylor Simpson 
1927aa9ffabSTaylor Simpson TEST_pr(loadalignb_pr, b, 1,
1937aa9ffabSTaylor Simpson         0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
1947aa9ffabSTaylor Simpson         0x030201ffffffffffLL, 0x04030201ffffffffLL)
1957aa9ffabSTaylor Simpson TEST_pr(loadalignh_pr, h, 2,
1967aa9ffabSTaylor Simpson         0x0201ffffffffffffLL, 0x04030201ffffffffLL,
1977aa9ffabSTaylor Simpson         0x060504030201ffffLL, 0x0807060504030201LL)
1987aa9ffabSTaylor Simpson 
1997aa9ffabSTaylor Simpson /*
2007aa9ffabSTaylor Simpson  ****************************************************************************
2017aa9ffabSTaylor Simpson  * _pbr addressing mode (addr ++ modifer-reg:brev)
2027aa9ffabSTaylor Simpson  */
2037aa9ffabSTaylor Simpson #define LOAD_pbr(SZ, RES, PTR) \
2047aa9ffabSTaylor Simpson     __asm__( \
2057aa9ffabSTaylor Simpson         "r4 = #(1 << (16 - 3))\n\t" \
2067aa9ffabSTaylor Simpson         "m0 = r4\n\t" \
2077aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1++m0:brev)\n\t" \
2087aa9ffabSTaylor Simpson         : "+r"(RES), "+r"(PTR) \
2097aa9ffabSTaylor Simpson         : \
2107aa9ffabSTaylor Simpson         : "r4", "m0")
2117aa9ffabSTaylor Simpson #define LOAD_pbr_b(RES, PTR) \
2127aa9ffabSTaylor Simpson     LOAD_pbr(b, RES, PTR)
2137aa9ffabSTaylor Simpson #define LOAD_pbr_h(RES, PTR) \
2147aa9ffabSTaylor Simpson     LOAD_pbr(h, RES, PTR)
2157aa9ffabSTaylor Simpson 
2167aa9ffabSTaylor Simpson #define TEST_pbr(NAME, SZ, RES1, RES2, RES3, RES4) \
2177aa9ffabSTaylor Simpson void test_##NAME(void) \
2187aa9ffabSTaylor Simpson { \
219*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
2207aa9ffabSTaylor Simpson     void *ptr = buf; \
2217aa9ffabSTaylor Simpson     LOAD_pbr_##SZ(result, ptr); \
222*0d57cd61STaylor Simpson     check64(result, (RES1)); \
2237aa9ffabSTaylor Simpson     LOAD_pbr_##SZ(result, ptr); \
224*0d57cd61STaylor Simpson     check64(result, (RES2)); \
2257aa9ffabSTaylor Simpson     LOAD_pbr_##SZ(result, ptr); \
226*0d57cd61STaylor Simpson     check64(result, (RES3)); \
2277aa9ffabSTaylor Simpson     LOAD_pbr_##SZ(result, ptr); \
228*0d57cd61STaylor Simpson     check64(result, (RES4)); \
2297aa9ffabSTaylor Simpson }
2307aa9ffabSTaylor Simpson 
2317aa9ffabSTaylor Simpson TEST_pbr(loadalignb_pbr, b,
2327aa9ffabSTaylor Simpson     0x01ffffffffffffffLL, 0x0501ffffffffffffLL,
2337aa9ffabSTaylor Simpson     0x030501ffffffffffLL, 0x07030501ffffffffLL)
2347aa9ffabSTaylor Simpson TEST_pbr(loadalignh_pbr, h,
2357aa9ffabSTaylor Simpson     0x0201ffffffffffffLL, 0x06050201ffffffffLL,
2367aa9ffabSTaylor Simpson     0x040306050201ffffLL, 0x0807040306050201LL)
2377aa9ffabSTaylor Simpson 
2387aa9ffabSTaylor Simpson /*
2397aa9ffabSTaylor Simpson  ****************************************************************************
2407aa9ffabSTaylor Simpson  * _pi addressing mode (addr ++ inc)
2417aa9ffabSTaylor Simpson  */
2427aa9ffabSTaylor Simpson #define LOAD_pi(SZ, RES, PTR, INC) \
2437aa9ffabSTaylor Simpson     __asm__( \
2447aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1++#" #INC ")\n\t" \
2457aa9ffabSTaylor Simpson         : "+r"(RES), "+r"(PTR))
2467aa9ffabSTaylor Simpson #define LOAD_pi_b(RES, PTR, INC) \
2477aa9ffabSTaylor Simpson     LOAD_pi(b, RES, PTR, INC)
2487aa9ffabSTaylor Simpson #define LOAD_pi_h(RES, PTR, INC) \
2497aa9ffabSTaylor Simpson     LOAD_pi(h, RES, PTR, INC)
2507aa9ffabSTaylor Simpson 
2517aa9ffabSTaylor Simpson #define TEST_pi(NAME, SZ, INC, RES1, RES2, RES3, RES4) \
2527aa9ffabSTaylor Simpson void test_##NAME(void) \
2537aa9ffabSTaylor Simpson { \
254*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
2557aa9ffabSTaylor Simpson     void *ptr = buf; \
2567aa9ffabSTaylor Simpson     LOAD_pi_##SZ(result, ptr, (INC)); \
257*0d57cd61STaylor Simpson     check64(result, (RES1)); \
2587aa9ffabSTaylor Simpson     checkp(ptr, &buf[1 * (INC)]); \
2597aa9ffabSTaylor Simpson     LOAD_pi_##SZ(result, ptr, (INC)); \
260*0d57cd61STaylor Simpson     check64(result, (RES2)); \
2617aa9ffabSTaylor Simpson     checkp(ptr, &buf[2 * (INC)]); \
2627aa9ffabSTaylor Simpson     LOAD_pi_##SZ(result, ptr, (INC)); \
263*0d57cd61STaylor Simpson     check64(result, (RES3)); \
2647aa9ffabSTaylor Simpson     checkp(ptr, &buf[3 * (INC)]); \
2657aa9ffabSTaylor Simpson     LOAD_pi_##SZ(result, ptr, (INC)); \
266*0d57cd61STaylor Simpson     check64(result, (RES4)); \
2677aa9ffabSTaylor Simpson     checkp(ptr, &buf[4 * (INC)]); \
2687aa9ffabSTaylor Simpson }
2697aa9ffabSTaylor Simpson 
2707aa9ffabSTaylor Simpson TEST_pi(loadalignb_pi, b, 1,
2717aa9ffabSTaylor Simpson         0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
2727aa9ffabSTaylor Simpson         0x030201ffffffffffLL, 0x04030201ffffffffLL)
2737aa9ffabSTaylor Simpson TEST_pi(loadalignh_pi, h, 2,
2747aa9ffabSTaylor Simpson         0x0201ffffffffffffLL, 0x04030201ffffffffLL,
2757aa9ffabSTaylor Simpson         0x060504030201ffffLL, 0x0807060504030201LL)
2767aa9ffabSTaylor Simpson 
2777aa9ffabSTaylor Simpson /*
2787aa9ffabSTaylor Simpson  ****************************************************************************
2797aa9ffabSTaylor Simpson  * _pci addressing mode (addr ++ inc:circ)
2807aa9ffabSTaylor Simpson  */
2817aa9ffabSTaylor Simpson #define LOAD_pci(SZ, RES, PTR, START, LEN, INC) \
2827aa9ffabSTaylor Simpson     __asm__( \
2837aa9ffabSTaylor Simpson         "r4 = %3\n\t" \
2847aa9ffabSTaylor Simpson         "m0 = r4\n\t" \
2857aa9ffabSTaylor Simpson         "cs0 = %2\n\t" \
2867aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1++#" #INC ":circ(m0))\n\t" \
2877aa9ffabSTaylor Simpson         : "+r"(RES), "+r"(PTR) \
2887aa9ffabSTaylor Simpson         : "r"(START), "r"(LEN) \
2897aa9ffabSTaylor Simpson         : "r4", "m0", "cs0")
2907aa9ffabSTaylor Simpson #define LOAD_pci_b(RES, PTR, START, LEN, INC) \
2917aa9ffabSTaylor Simpson     LOAD_pci(b, RES, PTR, START, LEN, INC)
2927aa9ffabSTaylor Simpson #define LOAD_pci_h(RES, PTR, START, LEN, INC) \
2937aa9ffabSTaylor Simpson     LOAD_pci(h, RES, PTR, START, LEN, INC)
2947aa9ffabSTaylor Simpson 
2957aa9ffabSTaylor Simpson #define TEST_pci(NAME, SZ, LEN, INC, RES1, RES2, RES3, RES4) \
2967aa9ffabSTaylor Simpson void test_##NAME(void) \
2977aa9ffabSTaylor Simpson { \
298*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
2997aa9ffabSTaylor Simpson     void *ptr = buf; \
3007aa9ffabSTaylor Simpson     LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
301*0d57cd61STaylor Simpson     check64(result, (RES1)); \
3027aa9ffabSTaylor Simpson     checkp(ptr, &buf[(1 * (INC)) % (LEN)]); \
3037aa9ffabSTaylor Simpson     LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
304*0d57cd61STaylor Simpson     check64(result, (RES2)); \
3057aa9ffabSTaylor Simpson     checkp(ptr, &buf[(2 * (INC)) % (LEN)]); \
3067aa9ffabSTaylor Simpson     LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
307*0d57cd61STaylor Simpson     check64(result, (RES3)); \
3087aa9ffabSTaylor Simpson     checkp(ptr, &buf[(3 * (INC)) % (LEN)]); \
3097aa9ffabSTaylor Simpson     LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
310*0d57cd61STaylor Simpson     check64(result, (RES4)); \
3117aa9ffabSTaylor Simpson     checkp(ptr, &buf[(4 * (INC)) % (LEN)]); \
3127aa9ffabSTaylor Simpson }
3137aa9ffabSTaylor Simpson 
3147aa9ffabSTaylor Simpson TEST_pci(loadalignb_pci, b, 2, 1,
3157aa9ffabSTaylor Simpson     0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
3167aa9ffabSTaylor Simpson     0x010201ffffffffffLL, 0x02010201ffffffffLL)
3177aa9ffabSTaylor Simpson TEST_pci(loadalignh_pci, h, 4, 2,
3187aa9ffabSTaylor Simpson     0x0201ffffffffffffLL, 0x04030201ffffffffLL,
3197aa9ffabSTaylor Simpson     0x020104030201ffffLL, 0x0403020104030201LL)
3207aa9ffabSTaylor Simpson 
3217aa9ffabSTaylor Simpson /*
3227aa9ffabSTaylor Simpson  ****************************************************************************
3237aa9ffabSTaylor Simpson  * _pcr addressing mode (addr ++ I:circ(modifier-reg))
3247aa9ffabSTaylor Simpson  */
3257aa9ffabSTaylor Simpson #define LOAD_pcr(SZ, RES, PTR, START, LEN, INC) \
3267aa9ffabSTaylor Simpson     __asm__( \
3277aa9ffabSTaylor Simpson         "r4 = %2\n\t" \
3287aa9ffabSTaylor Simpson         "m1 = r4\n\t" \
3297aa9ffabSTaylor Simpson         "cs1 = %3\n\t" \
3307aa9ffabSTaylor Simpson         "%0 = mem" #SZ "_fifo(%1++I:circ(m1))\n\t" \
3317aa9ffabSTaylor Simpson         : "+r"(RES), "+r"(PTR) \
3327aa9ffabSTaylor Simpson         : "r"((((INC) & 0x7f) << 17) | ((LEN) & 0x1ffff)), \
3337aa9ffabSTaylor Simpson           "r"(START) \
3347aa9ffabSTaylor Simpson         : "r4", "m1", "cs1")
3357aa9ffabSTaylor Simpson #define LOAD_pcr_b(RES, PTR, START, LEN, INC) \
3367aa9ffabSTaylor Simpson     LOAD_pcr(b, RES, PTR, START, LEN, INC)
3377aa9ffabSTaylor Simpson #define LOAD_pcr_h(RES, PTR, START, LEN, INC) \
3387aa9ffabSTaylor Simpson     LOAD_pcr(h, RES, PTR, START, LEN, INC)
3397aa9ffabSTaylor Simpson 
3407aa9ffabSTaylor Simpson #define TEST_pcr(NAME, SZ, SIZE, LEN, INC, RES1, RES2, RES3, RES4) \
3417aa9ffabSTaylor Simpson void test_##NAME(void) \
3427aa9ffabSTaylor Simpson { \
343*0d57cd61STaylor Simpson     int64_t result = ~0LL; \
3447aa9ffabSTaylor Simpson     void *ptr = buf; \
3457aa9ffabSTaylor Simpson     LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
346*0d57cd61STaylor Simpson     check64(result, (RES1)); \
3477aa9ffabSTaylor Simpson     checkp(ptr, &buf[(1 * (INC) * (SIZE)) % (LEN)]); \
3487aa9ffabSTaylor Simpson     LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
349*0d57cd61STaylor Simpson     check64(result, (RES2)); \
3507aa9ffabSTaylor Simpson     checkp(ptr, &buf[(2 * (INC) * (SIZE)) % (LEN)]); \
3517aa9ffabSTaylor Simpson     LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
352*0d57cd61STaylor Simpson     check64(result, (RES3)); \
3537aa9ffabSTaylor Simpson     checkp(ptr, &buf[(3 * (INC) * (SIZE)) % (LEN)]); \
3547aa9ffabSTaylor Simpson     LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
355*0d57cd61STaylor Simpson     check64(result, (RES4)); \
3567aa9ffabSTaylor Simpson     checkp(ptr, &buf[(4 * (INC) * (SIZE)) % (LEN)]); \
3577aa9ffabSTaylor Simpson }
3587aa9ffabSTaylor Simpson 
3597aa9ffabSTaylor Simpson TEST_pcr(loadalignb_pcr, b, 1, 2, 1,
3607aa9ffabSTaylor Simpson     0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
3617aa9ffabSTaylor Simpson     0x010201ffffffffffLL, 0x02010201ffffffffLL)
3627aa9ffabSTaylor Simpson TEST_pcr(loadalignh_pcr, h, 2, 4, 1,
3637aa9ffabSTaylor Simpson     0x0201ffffffffffffLL, 0x04030201ffffffffLL,
3647aa9ffabSTaylor Simpson     0x020104030201ffffLL, 0x0403020104030201LL)
3657aa9ffabSTaylor Simpson 
main()3667aa9ffabSTaylor Simpson int main()
3677aa9ffabSTaylor Simpson {
3687aa9ffabSTaylor Simpson     init_buf();
3697aa9ffabSTaylor Simpson 
3707aa9ffabSTaylor Simpson     test_loadalignb_io();
3717aa9ffabSTaylor Simpson     test_loadalignh_io();
3727aa9ffabSTaylor Simpson 
3737aa9ffabSTaylor Simpson     test_loadalignb_ur();
3747aa9ffabSTaylor Simpson     test_loadalignh_ur();
3757aa9ffabSTaylor Simpson 
3767aa9ffabSTaylor Simpson     test_loadalignb_ap();
3777aa9ffabSTaylor Simpson     test_loadalignh_ap();
3787aa9ffabSTaylor Simpson 
3797aa9ffabSTaylor Simpson     test_loadalignb_pr();
3807aa9ffabSTaylor Simpson     test_loadalignh_pr();
3817aa9ffabSTaylor Simpson 
3827aa9ffabSTaylor Simpson     test_loadalignb_pbr();
3837aa9ffabSTaylor Simpson     test_loadalignh_pbr();
3847aa9ffabSTaylor Simpson 
3857aa9ffabSTaylor Simpson     test_loadalignb_pi();
3867aa9ffabSTaylor Simpson     test_loadalignh_pi();
3877aa9ffabSTaylor Simpson 
3887aa9ffabSTaylor Simpson     test_loadalignb_pci();
3897aa9ffabSTaylor Simpson     test_loadalignh_pci();
3907aa9ffabSTaylor Simpson 
3917aa9ffabSTaylor Simpson     test_loadalignb_pcr();
3927aa9ffabSTaylor Simpson     test_loadalignh_pcr();
3937aa9ffabSTaylor Simpson 
3947aa9ffabSTaylor Simpson     puts(err ? "FAIL" : "PASS");
3957aa9ffabSTaylor Simpson     return err ? 1 : 0;
3967aa9ffabSTaylor Simpson }
397