146ef47e2STaylor Simpson /* 258ff2981SMichael Lambert * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved. 346ef47e2STaylor Simpson * 446ef47e2STaylor Simpson * This program is free software; you can redistribute it and/or modify 546ef47e2STaylor Simpson * it under the terms of the GNU General Public License as published by 646ef47e2STaylor Simpson * the Free Software Foundation; either version 2 of the License, or 746ef47e2STaylor Simpson * (at your option) any later version. 846ef47e2STaylor Simpson * 946ef47e2STaylor Simpson * This program is distributed in the hope that it will be useful, 1046ef47e2STaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 1146ef47e2STaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1246ef47e2STaylor Simpson * GNU General Public License for more details. 1346ef47e2STaylor Simpson * 1446ef47e2STaylor Simpson * You should have received a copy of the GNU General Public License 1546ef47e2STaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 1646ef47e2STaylor Simpson */ 1746ef47e2STaylor Simpson 1846ef47e2STaylor Simpson #include <stdio.h> 19*0d57cd61STaylor Simpson #include <stdint.h> 20*0d57cd61STaylor Simpson 21*0d57cd61STaylor Simpson int err; 22*0d57cd61STaylor Simpson 23*0d57cd61STaylor Simpson #include "hex_test.h" 2446ef47e2STaylor Simpson 2546ef47e2STaylor Simpson #define DEBUG 0 2646ef47e2STaylor Simpson #define DEBUG_PRINTF(...) \ 2746ef47e2STaylor Simpson do { \ 2846ef47e2STaylor Simpson if (DEBUG) { \ 2946ef47e2STaylor Simpson printf(__VA_ARGS__); \ 3046ef47e2STaylor Simpson } \ 3146ef47e2STaylor Simpson } while (0) 3246ef47e2STaylor Simpson 3346ef47e2STaylor Simpson 3446ef47e2STaylor Simpson #define NBYTES (1 << 8) 3546ef47e2STaylor Simpson #define NHALFS (NBYTES / sizeof(short)) 3646ef47e2STaylor Simpson #define NWORDS (NBYTES / sizeof(int)) 3746ef47e2STaylor Simpson #define NDOBLS (NBYTES / sizeof(long long)) 3846ef47e2STaylor Simpson 39*0d57cd61STaylor Simpson int64_t dbuf[NDOBLS] __attribute__((aligned(1 << 12))) = {0}; 40*0d57cd61STaylor Simpson int32_t wbuf[NWORDS] __attribute__((aligned(1 << 12))) = {0}; 41*0d57cd61STaylor Simpson int16_t hbuf[NHALFS] __attribute__((aligned(1 << 12))) = {0}; 42*0d57cd61STaylor Simpson uint8_t bbuf[NBYTES] __attribute__((aligned(1 << 12))) = {0}; 4346ef47e2STaylor Simpson 4446ef47e2STaylor Simpson /* 4546ef47e2STaylor Simpson * We use the C preporcessor to deal with the combinations of types 4646ef47e2STaylor Simpson */ 4746ef47e2STaylor Simpson 4846ef47e2STaylor Simpson #define INIT(BUF, N) \ 4946ef47e2STaylor Simpson void init_##BUF(void) \ 5046ef47e2STaylor Simpson { \ 51*0d57cd61STaylor Simpson for (int i = 0; i < N; i++) { \ 5246ef47e2STaylor Simpson BUF[i] = i; \ 5346ef47e2STaylor Simpson } \ 5446ef47e2STaylor Simpson } \ 5546ef47e2STaylor Simpson 5646ef47e2STaylor Simpson INIT(bbuf, NBYTES) 5746ef47e2STaylor Simpson INIT(hbuf, NHALFS) 5846ef47e2STaylor Simpson INIT(wbuf, NWORDS) 5946ef47e2STaylor Simpson INIT(dbuf, NDOBLS) 6046ef47e2STaylor Simpson 6146ef47e2STaylor Simpson /* 6246ef47e2STaylor Simpson * Macros for performing circular load 6346ef47e2STaylor Simpson * RES result 6446ef47e2STaylor Simpson * ADDR address 6546ef47e2STaylor Simpson * START start address of buffer 6646ef47e2STaylor Simpson * LEN length of buffer (in bytes) 6746ef47e2STaylor Simpson * INC address increment (in bytes for IMM, elements for REG) 6846ef47e2STaylor Simpson */ 6946ef47e2STaylor Simpson #define CIRC_LOAD_IMM(SIZE, RES, ADDR, START, LEN, INC) \ 7046ef47e2STaylor Simpson __asm__( \ 7146ef47e2STaylor Simpson "r4 = %3\n\t" \ 7246ef47e2STaylor Simpson "m0 = r4\n\t" \ 7346ef47e2STaylor Simpson "cs0 = %2\n\t" \ 7446ef47e2STaylor Simpson "%0 = mem" #SIZE "(%1++#" #INC ":circ(M0))\n\t" \ 7546ef47e2STaylor Simpson : "=r"(RES), "+r"(ADDR) \ 7646ef47e2STaylor Simpson : "r"(START), "r"(LEN) \ 7746ef47e2STaylor Simpson : "r4", "m0", "cs0") 7846ef47e2STaylor Simpson #define CIRC_LOAD_IMM_b(RES, ADDR, START, LEN, INC) \ 7946ef47e2STaylor Simpson CIRC_LOAD_IMM(b, RES, ADDR, START, LEN, INC) 8046ef47e2STaylor Simpson #define CIRC_LOAD_IMM_ub(RES, ADDR, START, LEN, INC) \ 8146ef47e2STaylor Simpson CIRC_LOAD_IMM(ub, RES, ADDR, START, LEN, INC) 8246ef47e2STaylor Simpson #define CIRC_LOAD_IMM_h(RES, ADDR, START, LEN, INC) \ 8346ef47e2STaylor Simpson CIRC_LOAD_IMM(h, RES, ADDR, START, LEN, INC) 8446ef47e2STaylor Simpson #define CIRC_LOAD_IMM_uh(RES, ADDR, START, LEN, INC) \ 8546ef47e2STaylor Simpson CIRC_LOAD_IMM(uh, RES, ADDR, START, LEN, INC) 8646ef47e2STaylor Simpson #define CIRC_LOAD_IMM_w(RES, ADDR, START, LEN, INC) \ 8746ef47e2STaylor Simpson CIRC_LOAD_IMM(w, RES, ADDR, START, LEN, INC) 8846ef47e2STaylor Simpson #define CIRC_LOAD_IMM_d(RES, ADDR, START, LEN, INC) \ 8946ef47e2STaylor Simpson CIRC_LOAD_IMM(d, RES, ADDR, START, LEN, INC) 9046ef47e2STaylor Simpson 9146ef47e2STaylor Simpson /* 9246ef47e2STaylor Simpson * The mreg has the following pieces 9346ef47e2STaylor Simpson * mreg[31:28] increment[10:7] 9446ef47e2STaylor Simpson * mreg[27:24] K value (used Hexagon v3 and earlier) 9546ef47e2STaylor Simpson * mreg[23:17] increment[6:0] 9646ef47e2STaylor Simpson * mreg[16:0] circular buffer length 9746ef47e2STaylor Simpson */ 98*0d57cd61STaylor Simpson static int32_t build_mreg(int32_t inc, int32_t K, int32_t len) 9946ef47e2STaylor Simpson { 10046ef47e2STaylor Simpson return ((inc & 0x780) << 21) | 10146ef47e2STaylor Simpson ((K & 0xf) << 24) | 10246ef47e2STaylor Simpson ((inc & 0x7f) << 17) | 10346ef47e2STaylor Simpson (len & 0x1ffff); 10446ef47e2STaylor Simpson } 10546ef47e2STaylor Simpson 10646ef47e2STaylor Simpson #define CIRC_LOAD_REG(SIZE, RES, ADDR, START, LEN, INC) \ 10746ef47e2STaylor Simpson __asm__( \ 10846ef47e2STaylor Simpson "r4 = %2\n\t" \ 10946ef47e2STaylor Simpson "m1 = r4\n\t" \ 11046ef47e2STaylor Simpson "cs1 = %3\n\t" \ 11146ef47e2STaylor Simpson "%0 = mem" #SIZE "(%1++I:circ(M1))\n\t" \ 11246ef47e2STaylor Simpson : "=r"(RES), "+r"(ADDR) \ 11346ef47e2STaylor Simpson : "r"(build_mreg((INC), 0, (LEN))), \ 11446ef47e2STaylor Simpson "r"(START) \ 11546ef47e2STaylor Simpson : "r4", "m1", "cs1") 11646ef47e2STaylor Simpson #define CIRC_LOAD_REG_b(RES, ADDR, START, LEN, INC) \ 11746ef47e2STaylor Simpson CIRC_LOAD_REG(b, RES, ADDR, START, LEN, INC) 11846ef47e2STaylor Simpson #define CIRC_LOAD_REG_ub(RES, ADDR, START, LEN, INC) \ 11946ef47e2STaylor Simpson CIRC_LOAD_REG(ub, RES, ADDR, START, LEN, INC) 12046ef47e2STaylor Simpson #define CIRC_LOAD_REG_h(RES, ADDR, START, LEN, INC) \ 12146ef47e2STaylor Simpson CIRC_LOAD_REG(h, RES, ADDR, START, LEN, INC) 12246ef47e2STaylor Simpson #define CIRC_LOAD_REG_uh(RES, ADDR, START, LEN, INC) \ 12346ef47e2STaylor Simpson CIRC_LOAD_REG(uh, RES, ADDR, START, LEN, INC) 12446ef47e2STaylor Simpson #define CIRC_LOAD_REG_w(RES, ADDR, START, LEN, INC) \ 12546ef47e2STaylor Simpson CIRC_LOAD_REG(w, RES, ADDR, START, LEN, INC) 12646ef47e2STaylor Simpson #define CIRC_LOAD_REG_d(RES, ADDR, START, LEN, INC) \ 12746ef47e2STaylor Simpson CIRC_LOAD_REG(d, RES, ADDR, START, LEN, INC) 12846ef47e2STaylor Simpson 12946ef47e2STaylor Simpson /* 13046ef47e2STaylor Simpson * Macros for performing circular store 13146ef47e2STaylor Simpson * VAL value to store 13246ef47e2STaylor Simpson * ADDR address 13346ef47e2STaylor Simpson * START start address of buffer 13446ef47e2STaylor Simpson * LEN length of buffer (in bytes) 13546ef47e2STaylor Simpson * INC address increment (in bytes for IMM, elements for REG) 13646ef47e2STaylor Simpson */ 13746ef47e2STaylor Simpson #define CIRC_STORE_IMM(SIZE, PART, VAL, ADDR, START, LEN, INC) \ 13846ef47e2STaylor Simpson __asm__( \ 13946ef47e2STaylor Simpson "r4 = %3\n\t" \ 14046ef47e2STaylor Simpson "m0 = r4\n\t" \ 14146ef47e2STaylor Simpson "cs0 = %1\n\t" \ 14246ef47e2STaylor Simpson "mem" #SIZE "(%0++#" #INC ":circ(M0)) = %2" PART "\n\t" \ 14346ef47e2STaylor Simpson : "+r"(ADDR) \ 14446ef47e2STaylor Simpson : "r"(START), "r"(VAL), "r"(LEN) \ 14546ef47e2STaylor Simpson : "r4", "m0", "cs0", "memory") 14646ef47e2STaylor Simpson #define CIRC_STORE_IMM_b(VAL, ADDR, START, LEN, INC) \ 14746ef47e2STaylor Simpson CIRC_STORE_IMM(b, "", VAL, ADDR, START, LEN, INC) 14846ef47e2STaylor Simpson #define CIRC_STORE_IMM_h(VAL, ADDR, START, LEN, INC) \ 14946ef47e2STaylor Simpson CIRC_STORE_IMM(h, "", VAL, ADDR, START, LEN, INC) 15046ef47e2STaylor Simpson #define CIRC_STORE_IMM_f(VAL, ADDR, START, LEN, INC) \ 15146ef47e2STaylor Simpson CIRC_STORE_IMM(h, ".H", VAL, ADDR, START, LEN, INC) 15246ef47e2STaylor Simpson #define CIRC_STORE_IMM_w(VAL, ADDR, START, LEN, INC) \ 15346ef47e2STaylor Simpson CIRC_STORE_IMM(w, "", VAL, ADDR, START, LEN, INC) 15446ef47e2STaylor Simpson #define CIRC_STORE_IMM_d(VAL, ADDR, START, LEN, INC) \ 15546ef47e2STaylor Simpson CIRC_STORE_IMM(d, "", VAL, ADDR, START, LEN, INC) 15646ef47e2STaylor Simpson 15746ef47e2STaylor Simpson #define CIRC_STORE_NEW_IMM(SIZE, VAL, ADDR, START, LEN, INC) \ 15846ef47e2STaylor Simpson __asm__( \ 15946ef47e2STaylor Simpson "r4 = %3\n\t" \ 16046ef47e2STaylor Simpson "m0 = r4\n\t" \ 16146ef47e2STaylor Simpson "cs0 = %1\n\t" \ 16246ef47e2STaylor Simpson "{\n\t" \ 16346ef47e2STaylor Simpson " r5 = %2\n\t" \ 16446ef47e2STaylor Simpson " mem" #SIZE "(%0++#" #INC ":circ(M0)) = r5.new\n\t" \ 16546ef47e2STaylor Simpson "}\n\t" \ 16646ef47e2STaylor Simpson : "+r"(ADDR) \ 16746ef47e2STaylor Simpson : "r"(START), "r"(VAL), "r"(LEN) \ 16846ef47e2STaylor Simpson : "r4", "r5", "m0", "cs0", "memory") 16946ef47e2STaylor Simpson #define CIRC_STORE_IMM_bnew(VAL, ADDR, START, LEN, INC) \ 17046ef47e2STaylor Simpson CIRC_STORE_NEW_IMM(b, VAL, ADDR, START, LEN, INC) 17146ef47e2STaylor Simpson #define CIRC_STORE_IMM_hnew(VAL, ADDR, START, LEN, INC) \ 17246ef47e2STaylor Simpson CIRC_STORE_NEW_IMM(h, VAL, ADDR, START, LEN, INC) 17346ef47e2STaylor Simpson #define CIRC_STORE_IMM_wnew(VAL, ADDR, START, LEN, INC) \ 17446ef47e2STaylor Simpson CIRC_STORE_NEW_IMM(w, VAL, ADDR, START, LEN, INC) 17546ef47e2STaylor Simpson 17646ef47e2STaylor Simpson #define CIRC_STORE_REG(SIZE, PART, VAL, ADDR, START, LEN, INC) \ 17746ef47e2STaylor Simpson __asm__( \ 17846ef47e2STaylor Simpson "r4 = %1\n\t" \ 17946ef47e2STaylor Simpson "m1 = r4\n\t" \ 18046ef47e2STaylor Simpson "cs1 = %2\n\t" \ 18146ef47e2STaylor Simpson "mem" #SIZE "(%0++I:circ(M1)) = %3" PART "\n\t" \ 18246ef47e2STaylor Simpson : "+r"(ADDR) \ 18346ef47e2STaylor Simpson : "r"(build_mreg((INC), 0, (LEN))), \ 18446ef47e2STaylor Simpson "r"(START), \ 18546ef47e2STaylor Simpson "r"(VAL) \ 18646ef47e2STaylor Simpson : "r4", "m1", "cs1", "memory") 18746ef47e2STaylor Simpson #define CIRC_STORE_REG_b(VAL, ADDR, START, LEN, INC) \ 18846ef47e2STaylor Simpson CIRC_STORE_REG(b, "", VAL, ADDR, START, LEN, INC) 18946ef47e2STaylor Simpson #define CIRC_STORE_REG_h(VAL, ADDR, START, LEN, INC) \ 19046ef47e2STaylor Simpson CIRC_STORE_REG(h, "", VAL, ADDR, START, LEN, INC) 19146ef47e2STaylor Simpson #define CIRC_STORE_REG_f(VAL, ADDR, START, LEN, INC) \ 19246ef47e2STaylor Simpson CIRC_STORE_REG(h, ".H", VAL, ADDR, START, LEN, INC) 19346ef47e2STaylor Simpson #define CIRC_STORE_REG_w(VAL, ADDR, START, LEN, INC) \ 19446ef47e2STaylor Simpson CIRC_STORE_REG(w, "", VAL, ADDR, START, LEN, INC) 19546ef47e2STaylor Simpson #define CIRC_STORE_REG_d(VAL, ADDR, START, LEN, INC) \ 19646ef47e2STaylor Simpson CIRC_STORE_REG(d, "", VAL, ADDR, START, LEN, INC) 19746ef47e2STaylor Simpson 19846ef47e2STaylor Simpson #define CIRC_STORE_NEW_REG(SIZE, VAL, ADDR, START, LEN, INC) \ 19946ef47e2STaylor Simpson __asm__( \ 20046ef47e2STaylor Simpson "r4 = %1\n\t" \ 20146ef47e2STaylor Simpson "m1 = r4\n\t" \ 20246ef47e2STaylor Simpson "cs1 = %2\n\t" \ 20346ef47e2STaylor Simpson "{\n\t" \ 20446ef47e2STaylor Simpson " r5 = %3\n\t" \ 20546ef47e2STaylor Simpson " mem" #SIZE "(%0++I:circ(M1)) = r5.new\n\t" \ 20646ef47e2STaylor Simpson "}\n\t" \ 20746ef47e2STaylor Simpson : "+r"(ADDR) \ 20846ef47e2STaylor Simpson : "r"(build_mreg((INC), 0, (LEN))), \ 20946ef47e2STaylor Simpson "r"(START), \ 21046ef47e2STaylor Simpson "r"(VAL) \ 21146ef47e2STaylor Simpson : "r4", "r5", "m1", "cs1", "memory") 21246ef47e2STaylor Simpson #define CIRC_STORE_REG_bnew(VAL, ADDR, START, LEN, INC) \ 21346ef47e2STaylor Simpson CIRC_STORE_NEW_REG(b, VAL, ADDR, START, LEN, INC) 21446ef47e2STaylor Simpson #define CIRC_STORE_REG_hnew(VAL, ADDR, START, LEN, INC) \ 21546ef47e2STaylor Simpson CIRC_STORE_NEW_REG(h, VAL, ADDR, START, LEN, INC) 21646ef47e2STaylor Simpson #define CIRC_STORE_REG_wnew(VAL, ADDR, START, LEN, INC) \ 21746ef47e2STaylor Simpson CIRC_STORE_NEW_REG(w, VAL, ADDR, START, LEN, INC) 21846ef47e2STaylor Simpson 21946ef47e2STaylor Simpson 22046ef47e2STaylor Simpson /* We'll test increments +1 and -1 */ 221*0d57cd61STaylor Simpson void __check_load(int line, int32_t i, int64_t res, int32_t inc, int32_t size) 22246ef47e2STaylor Simpson { 223*0d57cd61STaylor Simpson int32_t expect = (i * inc); 22446ef47e2STaylor Simpson while (expect >= size) { 22546ef47e2STaylor Simpson expect -= size; 22646ef47e2STaylor Simpson } 22746ef47e2STaylor Simpson while (expect < 0) { 22846ef47e2STaylor Simpson expect += size; 22946ef47e2STaylor Simpson } 230*0d57cd61STaylor Simpson __check32(line, res, expect); 23146ef47e2STaylor Simpson } 232*0d57cd61STaylor Simpson 233*0d57cd61STaylor Simpson #define check_load(I, RES, INC, SZ) __check_load(__LINE__, I, RES, INC, SZ) 23446ef47e2STaylor Simpson 23546ef47e2STaylor Simpson #define TEST_LOAD_IMM(SZ, TYPE, BUF, BUFSIZE, INC, FMT) \ 23646ef47e2STaylor Simpson void circ_test_load_imm_##SZ(void) \ 23746ef47e2STaylor Simpson { \ 23846ef47e2STaylor Simpson TYPE *p = (TYPE *)BUF; \ 239*0d57cd61STaylor Simpson int32_t size = 10; \ 240*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 24146ef47e2STaylor Simpson TYPE element; \ 24246ef47e2STaylor Simpson CIRC_LOAD_IMM_##SZ(element, p, BUF, size * sizeof(TYPE), (INC)); \ 24346ef47e2STaylor Simpson DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \ 24446ef47e2STaylor Simpson i, p, element); \ 24546ef47e2STaylor Simpson check_load(i, element, ((INC) / (int)sizeof(TYPE)), size); \ 24646ef47e2STaylor Simpson } \ 24746ef47e2STaylor Simpson p = (TYPE *)BUF; \ 248*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 24946ef47e2STaylor Simpson TYPE element; \ 25046ef47e2STaylor Simpson CIRC_LOAD_IMM_##SZ(element, p, BUF, size * sizeof(TYPE), -(INC)); \ 25146ef47e2STaylor Simpson DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \ 25246ef47e2STaylor Simpson i, p, element); \ 25346ef47e2STaylor Simpson check_load(i, element, (-(INC) / (int)sizeof(TYPE)), size); \ 25446ef47e2STaylor Simpson } \ 25546ef47e2STaylor Simpson } 25646ef47e2STaylor Simpson 257*0d57cd61STaylor Simpson TEST_LOAD_IMM(b, int8_t, bbuf, NBYTES, 1, d) 258*0d57cd61STaylor Simpson TEST_LOAD_IMM(ub, uint8_t, bbuf, NBYTES, 1, d) 259*0d57cd61STaylor Simpson TEST_LOAD_IMM(h, int16_t, hbuf, NHALFS, 2, d) 260*0d57cd61STaylor Simpson TEST_LOAD_IMM(uh, uint16_t, hbuf, NHALFS, 2, d) 261*0d57cd61STaylor Simpson TEST_LOAD_IMM(w, int32_t, wbuf, NWORDS, 4, d) 262*0d57cd61STaylor Simpson TEST_LOAD_IMM(d, int64_t, dbuf, NDOBLS, 8, lld) 26346ef47e2STaylor Simpson 26446ef47e2STaylor Simpson #define TEST_LOAD_REG(SZ, TYPE, BUF, BUFSIZE, FMT) \ 26546ef47e2STaylor Simpson void circ_test_load_reg_##SZ(void) \ 26646ef47e2STaylor Simpson { \ 26746ef47e2STaylor Simpson TYPE *p = (TYPE *)BUF; \ 268*0d57cd61STaylor Simpson int32_t size = 13; \ 269*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 27046ef47e2STaylor Simpson TYPE element; \ 27146ef47e2STaylor Simpson CIRC_LOAD_REG_##SZ(element, p, BUF, size * sizeof(TYPE), 1); \ 27246ef47e2STaylor Simpson DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \ 27346ef47e2STaylor Simpson i, p, element); \ 27446ef47e2STaylor Simpson check_load(i, element, 1, size); \ 27546ef47e2STaylor Simpson } \ 27646ef47e2STaylor Simpson p = (TYPE *)BUF; \ 277*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 27846ef47e2STaylor Simpson TYPE element; \ 27946ef47e2STaylor Simpson CIRC_LOAD_REG_##SZ(element, p, BUF, size * sizeof(TYPE), -1); \ 28046ef47e2STaylor Simpson DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \ 28146ef47e2STaylor Simpson i, p, element); \ 28246ef47e2STaylor Simpson check_load(i, element, -1, size); \ 28346ef47e2STaylor Simpson } \ 28446ef47e2STaylor Simpson } 28546ef47e2STaylor Simpson 286*0d57cd61STaylor Simpson TEST_LOAD_REG(b, int8_t, bbuf, NBYTES, d) 287*0d57cd61STaylor Simpson TEST_LOAD_REG(ub, uint8_t, bbuf, NBYTES, d) 288*0d57cd61STaylor Simpson TEST_LOAD_REG(h, int16_t, hbuf, NHALFS, d) 289*0d57cd61STaylor Simpson TEST_LOAD_REG(uh, uint16_t, hbuf, NHALFS, d) 290*0d57cd61STaylor Simpson TEST_LOAD_REG(w, int32_t, wbuf, NWORDS, d) 291*0d57cd61STaylor Simpson TEST_LOAD_REG(d, int64_t, dbuf, NDOBLS, lld) 29246ef47e2STaylor Simpson 29346ef47e2STaylor Simpson /* The circular stores will wrap around somewhere inside the buffer */ 29446ef47e2STaylor Simpson #define CIRC_VAL(SZ, TYPE, BUFSIZE) \ 295*0d57cd61STaylor Simpson TYPE circ_val_##SZ(int i, int32_t inc, int32_t size) \ 29646ef47e2STaylor Simpson { \ 29746ef47e2STaylor Simpson int mod = BUFSIZE % size; \ 29846ef47e2STaylor Simpson int elem = i * inc; \ 29946ef47e2STaylor Simpson if (elem < 0) { \ 30046ef47e2STaylor Simpson if (-elem <= size - mod) { \ 30146ef47e2STaylor Simpson return (elem + BUFSIZE - mod); \ 30246ef47e2STaylor Simpson } else { \ 30346ef47e2STaylor Simpson return (elem + BUFSIZE + size - mod); \ 30446ef47e2STaylor Simpson } \ 30546ef47e2STaylor Simpson } else if (elem < mod) {\ 30646ef47e2STaylor Simpson return (elem + BUFSIZE - mod); \ 30746ef47e2STaylor Simpson } else { \ 30846ef47e2STaylor Simpson return (elem + BUFSIZE - size - mod); \ 30946ef47e2STaylor Simpson } \ 31046ef47e2STaylor Simpson } 31146ef47e2STaylor Simpson 312*0d57cd61STaylor Simpson CIRC_VAL(b, uint8_t, NBYTES) 313*0d57cd61STaylor Simpson CIRC_VAL(h, int16_t, NHALFS) 314*0d57cd61STaylor Simpson CIRC_VAL(w, int32_t, NWORDS) 315*0d57cd61STaylor Simpson CIRC_VAL(d, int64_t, NDOBLS) 31646ef47e2STaylor Simpson 31746ef47e2STaylor Simpson /* 31846ef47e2STaylor Simpson * Circular stores should only write to the first "size" elements of the buffer 31946ef47e2STaylor Simpson * the remainder of the elements should have BUF[i] == i 32046ef47e2STaylor Simpson */ 32146ef47e2STaylor Simpson #define CHECK_STORE(SZ, BUF, BUFSIZE, FMT) \ 322*0d57cd61STaylor Simpson void check_store_##SZ(int32_t inc, int32_t size) \ 32346ef47e2STaylor Simpson { \ 324*0d57cd61STaylor Simpson for (int i = 0; i < size; i++) { \ 32546ef47e2STaylor Simpson DEBUG_PRINTF(#BUF "[%3d] = 0x%02" #FMT ", guess = 0x%02" #FMT "\n", \ 32646ef47e2STaylor Simpson i, BUF[i], circ_val_##SZ(i, inc, size)); \ 327*0d57cd61STaylor Simpson check64(BUF[i], circ_val_##SZ(i, inc, size)); \ 32846ef47e2STaylor Simpson } \ 329*0d57cd61STaylor Simpson for (int i = size; i < BUFSIZE; i++) { \ 330*0d57cd61STaylor Simpson check64(BUF[i], i); \ 33146ef47e2STaylor Simpson } \ 33246ef47e2STaylor Simpson } 33346ef47e2STaylor Simpson 33446ef47e2STaylor Simpson CHECK_STORE(b, bbuf, NBYTES, x) 33546ef47e2STaylor Simpson CHECK_STORE(h, hbuf, NHALFS, x) 33646ef47e2STaylor Simpson CHECK_STORE(w, wbuf, NWORDS, x) 33746ef47e2STaylor Simpson CHECK_STORE(d, dbuf, NDOBLS, llx) 33846ef47e2STaylor Simpson 33946ef47e2STaylor Simpson #define CIRC_TEST_STORE_IMM(SZ, CHK, TYPE, BUF, BUFSIZE, SHIFT, INC) \ 34046ef47e2STaylor Simpson void circ_test_store_imm_##SZ(void) \ 34146ef47e2STaylor Simpson { \ 342*0d57cd61STaylor Simpson uint32_t size = 27; \ 34346ef47e2STaylor Simpson TYPE *p = BUF; \ 34446ef47e2STaylor Simpson TYPE val = 0; \ 34546ef47e2STaylor Simpson init_##BUF(); \ 346*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 34746ef47e2STaylor Simpson CIRC_STORE_IMM_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), INC); \ 34846ef47e2STaylor Simpson val++; \ 34946ef47e2STaylor Simpson } \ 35046ef47e2STaylor Simpson check_store_##CHK(((INC) / (int)sizeof(TYPE)), size); \ 35146ef47e2STaylor Simpson p = BUF; \ 35246ef47e2STaylor Simpson val = 0; \ 35346ef47e2STaylor Simpson init_##BUF(); \ 354*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 35546ef47e2STaylor Simpson CIRC_STORE_IMM_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), \ 35646ef47e2STaylor Simpson -(INC)); \ 35746ef47e2STaylor Simpson val++; \ 35846ef47e2STaylor Simpson } \ 35946ef47e2STaylor Simpson check_store_##CHK((-(INC) / (int)sizeof(TYPE)), size); \ 36046ef47e2STaylor Simpson } 36146ef47e2STaylor Simpson 362*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(b, b, uint8_t, bbuf, NBYTES, 0, 1) 363*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(h, h, int16_t, hbuf, NHALFS, 0, 2) 364*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(f, h, int16_t, hbuf, NHALFS, 16, 2) 365*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(w, w, int32_t, wbuf, NWORDS, 0, 4) 366*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(d, d, int64_t, dbuf, NDOBLS, 0, 8) 367*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(bnew, b, uint8_t, bbuf, NBYTES, 0, 1) 368*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(hnew, h, int16_t, hbuf, NHALFS, 0, 2) 369*0d57cd61STaylor Simpson CIRC_TEST_STORE_IMM(wnew, w, int32_t, wbuf, NWORDS, 0, 4) 37046ef47e2STaylor Simpson 37146ef47e2STaylor Simpson #define CIRC_TEST_STORE_REG(SZ, CHK, TYPE, BUF, BUFSIZE, SHIFT) \ 37246ef47e2STaylor Simpson void circ_test_store_reg_##SZ(void) \ 37346ef47e2STaylor Simpson { \ 37446ef47e2STaylor Simpson TYPE *p = BUF; \ 375*0d57cd61STaylor Simpson uint32_t size = 19; \ 37646ef47e2STaylor Simpson TYPE val = 0; \ 37746ef47e2STaylor Simpson init_##BUF(); \ 378*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 37946ef47e2STaylor Simpson CIRC_STORE_REG_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), 1); \ 38046ef47e2STaylor Simpson val++; \ 38146ef47e2STaylor Simpson } \ 38246ef47e2STaylor Simpson check_store_##CHK(1, size); \ 38346ef47e2STaylor Simpson p = BUF; \ 38446ef47e2STaylor Simpson val = 0; \ 38546ef47e2STaylor Simpson init_##BUF(); \ 386*0d57cd61STaylor Simpson for (int i = 0; i < BUFSIZE; i++) { \ 38746ef47e2STaylor Simpson CIRC_STORE_REG_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), -1); \ 38846ef47e2STaylor Simpson val++; \ 38946ef47e2STaylor Simpson } \ 39046ef47e2STaylor Simpson check_store_##CHK(-1, size); \ 39146ef47e2STaylor Simpson } 39246ef47e2STaylor Simpson 393*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(b, b, uint8_t, bbuf, NBYTES, 0) 394*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(h, h, int16_t, hbuf, NHALFS, 0) 395*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(f, h, int16_t, hbuf, NHALFS, 16) 396*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(w, w, int32_t, wbuf, NWORDS, 0) 397*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(d, d, int64_t, dbuf, NDOBLS, 0) 398*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(bnew, b, uint8_t, bbuf, NBYTES, 0) 399*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(hnew, h, int16_t, hbuf, NHALFS, 0) 400*0d57cd61STaylor Simpson CIRC_TEST_STORE_REG(wnew, w, int32_t, wbuf, NWORDS, 0) 40146ef47e2STaylor Simpson 40246ef47e2STaylor Simpson /* Test the old scheme used in Hexagon V3 */ 40346ef47e2STaylor Simpson static void circ_test_v3(void) 40446ef47e2STaylor Simpson { 40546ef47e2STaylor Simpson int *p = wbuf; 406*0d57cd61STaylor Simpson int32_t size = 15; 40758ff2981SMichael Lambert /* set high bit in K to test unsigned extract in fcirc */ 408*0d57cd61STaylor Simpson int32_t K = 8; /* 1024 bytes */ 409*0d57cd61STaylor Simpson int32_t element; 41046ef47e2STaylor Simpson 41146ef47e2STaylor Simpson init_wbuf(); 41246ef47e2STaylor Simpson 413*0d57cd61STaylor Simpson for (int i = 0; i < NWORDS; i++) { 41446ef47e2STaylor Simpson __asm__( 41546ef47e2STaylor Simpson "r4 = %2\n\t" 41646ef47e2STaylor Simpson "m1 = r4\n\t" 41746ef47e2STaylor Simpson "%0 = memw(%1++I:circ(M1))\n\t" 41846ef47e2STaylor Simpson : "=r"(element), "+r"(p) 41946ef47e2STaylor Simpson : "r"(build_mreg(1, K, size * sizeof(int))) 42046ef47e2STaylor Simpson : "r4", "m1"); 42146ef47e2STaylor Simpson DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2d\n", i, p, element); 42246ef47e2STaylor Simpson check_load(i, element, 1, size); 42346ef47e2STaylor Simpson } 42446ef47e2STaylor Simpson } 42546ef47e2STaylor Simpson 42646ef47e2STaylor Simpson int main() 42746ef47e2STaylor Simpson { 42846ef47e2STaylor Simpson init_bbuf(); 42946ef47e2STaylor Simpson init_hbuf(); 43046ef47e2STaylor Simpson init_wbuf(); 43146ef47e2STaylor Simpson init_dbuf(); 43246ef47e2STaylor Simpson 43346ef47e2STaylor Simpson DEBUG_PRINTF("NBYTES = %d\n", NBYTES); 43446ef47e2STaylor Simpson DEBUG_PRINTF("Address of dbuf = 0x%p\n", dbuf); 43546ef47e2STaylor Simpson DEBUG_PRINTF("Address of wbuf = 0x%p\n", wbuf); 43646ef47e2STaylor Simpson DEBUG_PRINTF("Address of hbuf = 0x%p\n", hbuf); 43746ef47e2STaylor Simpson DEBUG_PRINTF("Address of bbuf = 0x%p\n", bbuf); 43846ef47e2STaylor Simpson 43946ef47e2STaylor Simpson circ_test_load_imm_b(); 44046ef47e2STaylor Simpson circ_test_load_imm_ub(); 44146ef47e2STaylor Simpson circ_test_load_imm_h(); 44246ef47e2STaylor Simpson circ_test_load_imm_uh(); 44346ef47e2STaylor Simpson circ_test_load_imm_w(); 44446ef47e2STaylor Simpson circ_test_load_imm_d(); 44546ef47e2STaylor Simpson 44646ef47e2STaylor Simpson circ_test_load_reg_b(); 44746ef47e2STaylor Simpson circ_test_load_reg_ub(); 44846ef47e2STaylor Simpson circ_test_load_reg_h(); 44946ef47e2STaylor Simpson circ_test_load_reg_uh(); 45046ef47e2STaylor Simpson circ_test_load_reg_w(); 45146ef47e2STaylor Simpson circ_test_load_reg_d(); 45246ef47e2STaylor Simpson 45346ef47e2STaylor Simpson circ_test_store_imm_b(); 45446ef47e2STaylor Simpson circ_test_store_imm_h(); 45546ef47e2STaylor Simpson circ_test_store_imm_f(); 45646ef47e2STaylor Simpson circ_test_store_imm_w(); 45746ef47e2STaylor Simpson circ_test_store_imm_d(); 45846ef47e2STaylor Simpson circ_test_store_imm_bnew(); 45946ef47e2STaylor Simpson circ_test_store_imm_hnew(); 46046ef47e2STaylor Simpson circ_test_store_imm_wnew(); 46146ef47e2STaylor Simpson 46246ef47e2STaylor Simpson circ_test_store_reg_b(); 46346ef47e2STaylor Simpson circ_test_store_reg_h(); 46446ef47e2STaylor Simpson circ_test_store_reg_f(); 46546ef47e2STaylor Simpson circ_test_store_reg_w(); 46646ef47e2STaylor Simpson circ_test_store_reg_d(); 46746ef47e2STaylor Simpson circ_test_store_reg_bnew(); 46846ef47e2STaylor Simpson circ_test_store_reg_hnew(); 46946ef47e2STaylor Simpson circ_test_store_reg_wnew(); 47046ef47e2STaylor Simpson 47146ef47e2STaylor Simpson circ_test_v3(); 47246ef47e2STaylor Simpson 47346ef47e2STaylor Simpson puts(err ? "FAIL" : "PASS"); 47446ef47e2STaylor Simpson return err ? 1 : 0; 47546ef47e2STaylor Simpson } 476