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 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 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 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