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