qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

brev.c (5517B)


      1 /*
      2  *  Copyright(c) 2019-2021 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 
     21 int err;
     22 
     23 #define NBITS          8
     24 #define SIZE           (1 << NBITS)
     25 
     26 long long     dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     27 int           wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     28 short         hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     29 unsigned char bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     30 
     31 /*
     32  * We use the C preporcessor to deal with the combinations of types
     33  */
     34 
     35 #define BREV_LOAD(SZ, RES, ADDR, INC) \
     36     __asm__( \
     37         "m0 = %2\n\t" \
     38         "%0 = mem" #SZ "(%1++m0:brev)\n\t" \
     39         : "=r"(RES), "+r"(ADDR) \
     40         : "r"(INC) \
     41         : "m0")
     42 
     43 #define BREV_LOAD_b(RES, ADDR, INC) \
     44     BREV_LOAD(b, RES, ADDR, INC)
     45 #define BREV_LOAD_ub(RES, ADDR, INC) \
     46     BREV_LOAD(ub, RES, ADDR, INC)
     47 #define BREV_LOAD_h(RES, ADDR, INC) \
     48     BREV_LOAD(h, RES, ADDR, INC)
     49 #define BREV_LOAD_uh(RES, ADDR, INC) \
     50     BREV_LOAD(uh, RES, ADDR, INC)
     51 #define BREV_LOAD_w(RES, ADDR, INC) \
     52     BREV_LOAD(w, RES, ADDR, INC)
     53 #define BREV_LOAD_d(RES, ADDR, INC) \
     54     BREV_LOAD(d, RES, ADDR, INC)
     55 
     56 #define BREV_STORE(SZ, PART, ADDR, VAL, INC) \
     57     __asm__( \
     58         "m0 = %2\n\t" \
     59         "mem" #SZ "(%0++m0:brev) = %1" PART "\n\t" \
     60         : "+r"(ADDR) \
     61         : "r"(VAL), "r"(INC) \
     62         : "m0", "memory")
     63 
     64 #define BREV_STORE_b(ADDR, VAL, INC) \
     65     BREV_STORE(b, "", ADDR, VAL, INC)
     66 #define BREV_STORE_h(ADDR, VAL, INC) \
     67     BREV_STORE(h, "", ADDR, VAL, INC)
     68 #define BREV_STORE_f(ADDR, VAL, INC) \
     69     BREV_STORE(h, ".H", ADDR, VAL, INC)
     70 #define BREV_STORE_w(ADDR, VAL, INC) \
     71     BREV_STORE(w, "", ADDR, VAL, INC)
     72 #define BREV_STORE_d(ADDR, VAL, INC) \
     73     BREV_STORE(d, "", ADDR, VAL, INC)
     74 
     75 #define BREV_STORE_NEW(SZ, ADDR, VAL, INC) \
     76     __asm__( \
     77         "m0 = %2\n\t" \
     78         "{\n\t" \
     79         "    r5 = %1\n\t" \
     80         "    mem" #SZ "(%0++m0:brev) = r5.new\n\t" \
     81         "}\n\t" \
     82         : "+r"(ADDR) \
     83         : "r"(VAL), "r"(INC) \
     84         : "r5", "m0", "memory")
     85 
     86 #define BREV_STORE_bnew(ADDR, VAL, INC) \
     87     BREV_STORE_NEW(b, ADDR, VAL, INC)
     88 #define BREV_STORE_hnew(ADDR, VAL, INC) \
     89     BREV_STORE_NEW(h, ADDR, VAL, INC)
     90 #define BREV_STORE_wnew(ADDR, VAL, INC) \
     91     BREV_STORE_NEW(w, ADDR, VAL, INC)
     92 
     93 int bitreverse(int x)
     94 {
     95     int result = 0;
     96     int i;
     97     for (i = 0; i < NBITS; i++) {
     98         result <<= 1;
     99         result |= x & 1;
    100         x >>= 1;
    101     }
    102     return result;
    103 }
    104 
    105 int sext8(int x)
    106 {
    107     return (x << 24) >> 24;
    108 }
    109 
    110 void check(int i, long long result, long long expect)
    111 {
    112     if (result != expect) {
    113         printf("ERROR(%d): 0x%04llx != 0x%04llx\n", i, result, expect);
    114         err++;
    115     }
    116 }
    117 
    118 #define TEST_BREV_LOAD(SZ, TYPE, BUF, SHIFT, EXP) \
    119     do { \
    120         p = BUF; \
    121         for (i = 0; i < SIZE; i++) { \
    122             TYPE result; \
    123             BREV_LOAD_##SZ(result, p, 1 << (SHIFT - NBITS)); \
    124             check(i, result, EXP); \
    125         } \
    126     } while (0)
    127 
    128 #define TEST_BREV_STORE(SZ, TYPE, BUF, VAL, SHIFT) \
    129     do { \
    130         p = BUF; \
    131         memset(BUF, 0xff, sizeof(BUF)); \
    132         for (i = 0; i < SIZE; i++) { \
    133             BREV_STORE_##SZ(p, (TYPE)(VAL), 1 << (SHIFT - NBITS)); \
    134         } \
    135         for (i = 0; i < SIZE; i++) { \
    136             check(i, BUF[i], bitreverse(i)); \
    137         } \
    138     } while (0)
    139 
    140 #define TEST_BREV_STORE_NEW(SZ, BUF, SHIFT) \
    141     do { \
    142         p = BUF; \
    143         memset(BUF, 0xff, sizeof(BUF)); \
    144         for (i = 0; i < SIZE; i++) { \
    145             BREV_STORE_##SZ(p, i, 1 << (SHIFT - NBITS)); \
    146         } \
    147         for (i = 0; i < SIZE; i++) { \
    148             check(i, BUF[i], bitreverse(i)); \
    149         } \
    150     } while (0)
    151 
    152 /*
    153  * We'll set high_half[i] = i << 16 for use in the .H form of store
    154  * which stores from the high half of the word.
    155  */
    156 int high_half[SIZE];
    157 
    158 int main()
    159 {
    160     void *p;
    161     int i;
    162 
    163     for (i = 0; i < SIZE; i++) {
    164         bbuf[i] = bitreverse(i);
    165         hbuf[i] = bitreverse(i);
    166         wbuf[i] = bitreverse(i);
    167         dbuf[i] = bitreverse(i);
    168         high_half[i] = i << 16;
    169     }
    170 
    171     TEST_BREV_LOAD(b,  int,       bbuf, 16, sext8(i));
    172     TEST_BREV_LOAD(ub, int,       bbuf, 16, i);
    173     TEST_BREV_LOAD(h,  int,       hbuf, 15, i);
    174     TEST_BREV_LOAD(uh, int,       hbuf, 15, i);
    175     TEST_BREV_LOAD(w,  int,       wbuf, 14, i);
    176     TEST_BREV_LOAD(d,  long long, dbuf, 13, i);
    177 
    178     TEST_BREV_STORE(b, int,       bbuf, i,            16);
    179     TEST_BREV_STORE(h, int,       hbuf, i,            15);
    180     TEST_BREV_STORE(f, int,       hbuf, high_half[i], 15);
    181     TEST_BREV_STORE(w, int,       wbuf, i,            14);
    182     TEST_BREV_STORE(d, long long, dbuf, i,            13);
    183 
    184     TEST_BREV_STORE_NEW(bnew, bbuf, 16);
    185     TEST_BREV_STORE_NEW(hnew, hbuf, 15);
    186     TEST_BREV_STORE_NEW(wnew, wbuf, 14);
    187 
    188     puts(err ? "FAIL" : "PASS");
    189     return err ? 1 : 0;
    190 }