qemu/tests/tcg/hexagon/brev.c
<<
>>
Prefs
   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
  21int err;
  22
  23#define NBITS          8
  24#define SIZE           (1 << NBITS)
  25
  26long long     dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
  27int           wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
  28short         hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
  29unsigned 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
  93int 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
 105int sext8(int x)
 106{
 107    return (x << 24) >> 24;
 108}
 109
 110void 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 */
 156int high_half[SIZE];
 157
 158int 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}
 191