qemu/tests/tcg/hexagon/brev.c
Taylor Simpson af7f182127 Hexagon (target/hexagon) bit reverse (brev) addressing
The following instructions are added
    L2_loadrub_pbr          Rd32 = memub(Rx32++Mu2:brev)
    L2_loadrb_pbr           Rd32 = memb(Rx32++Mu2:brev)
    L2_loadruh_pbr          Rd32 = memuh(Rx32++Mu2:brev)
    L2_loadrh_pbr           Rd32 = memh(Rx32++Mu2:brev)
    L2_loadri_pbr           Rd32 = memw(Rx32++Mu2:brev)
    L2_loadrd_pbr           Rdd32 = memd(Rx32++Mu2:brev)
    S2_storerb_pbr          memb(Rx32++Mu2:brev).=.Rt32
    S2_storerh_pbr          memh(Rx32++Mu2:brev).=.Rt32
    S2_storerf_pbr          memh(Rx32++Mu2:brev).=.Rt.H32
    S2_storeri_pbr          memw(Rx32++Mu2:brev).=.Rt32
    S2_storerd_pbr          memd(Rx32++Mu2:brev).=.Rt32
    S2_storerinew_pbr       memw(Rx32++Mu2:brev).=.Nt8.new
    S2_storerbnew_pbr       memw(Rx32++Mu2:brev).=.Nt8.new
    S2_storerhnew_pbr       memw(Rx32++Mu2:brev).=.Nt8.new

Test cases in tests/tcg/hexagon/brev.c

Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <1617930474-31979-24-git-send-email-tsimpson@quicinc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-05-01 16:03:10 -07:00

191 lines
5.4 KiB
C

/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
int err;
#define NBITS 8
#define SIZE (1 << NBITS)
long long dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
int wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
short hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
unsigned char bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
/*
* We use the C preporcessor to deal with the combinations of types
*/
#define BREV_LOAD(SZ, RES, ADDR, INC) \
__asm__( \
"m0 = %2\n\t" \
"%0 = mem" #SZ "(%1++m0:brev)\n\t" \
: "=r"(RES), "+r"(ADDR) \
: "r"(INC) \
: "m0")
#define BREV_LOAD_b(RES, ADDR, INC) \
BREV_LOAD(b, RES, ADDR, INC)
#define BREV_LOAD_ub(RES, ADDR, INC) \
BREV_LOAD(ub, RES, ADDR, INC)
#define BREV_LOAD_h(RES, ADDR, INC) \
BREV_LOAD(h, RES, ADDR, INC)
#define BREV_LOAD_uh(RES, ADDR, INC) \
BREV_LOAD(uh, RES, ADDR, INC)
#define BREV_LOAD_w(RES, ADDR, INC) \
BREV_LOAD(w, RES, ADDR, INC)
#define BREV_LOAD_d(RES, ADDR, INC) \
BREV_LOAD(d, RES, ADDR, INC)
#define BREV_STORE(SZ, PART, ADDR, VAL, INC) \
__asm__( \
"m0 = %2\n\t" \
"mem" #SZ "(%0++m0:brev) = %1" PART "\n\t" \
: "+r"(ADDR) \
: "r"(VAL), "r"(INC) \
: "m0", "memory")
#define BREV_STORE_b(ADDR, VAL, INC) \
BREV_STORE(b, "", ADDR, VAL, INC)
#define BREV_STORE_h(ADDR, VAL, INC) \
BREV_STORE(h, "", ADDR, VAL, INC)
#define BREV_STORE_f(ADDR, VAL, INC) \
BREV_STORE(h, ".H", ADDR, VAL, INC)
#define BREV_STORE_w(ADDR, VAL, INC) \
BREV_STORE(w, "", ADDR, VAL, INC)
#define BREV_STORE_d(ADDR, VAL, INC) \
BREV_STORE(d, "", ADDR, VAL, INC)
#define BREV_STORE_NEW(SZ, ADDR, VAL, INC) \
__asm__( \
"m0 = %2\n\t" \
"{\n\t" \
" r5 = %1\n\t" \
" mem" #SZ "(%0++m0:brev) = r5.new\n\t" \
"}\n\t" \
: "+r"(ADDR) \
: "r"(VAL), "r"(INC) \
: "r5", "m0", "memory")
#define BREV_STORE_bnew(ADDR, VAL, INC) \
BREV_STORE_NEW(b, ADDR, VAL, INC)
#define BREV_STORE_hnew(ADDR, VAL, INC) \
BREV_STORE_NEW(h, ADDR, VAL, INC)
#define BREV_STORE_wnew(ADDR, VAL, INC) \
BREV_STORE_NEW(w, ADDR, VAL, INC)
int bitreverse(int x)
{
int result = 0;
int i;
for (i = 0; i < NBITS; i++) {
result <<= 1;
result |= x & 1;
x >>= 1;
}
return result;
}
int sext8(int x)
{
return (x << 24) >> 24;
}
void check(int i, long long result, long long expect)
{
if (result != expect) {
printf("ERROR(%d): 0x%04llx != 0x%04llx\n", i, result, expect);
err++;
}
}
#define TEST_BREV_LOAD(SZ, TYPE, BUF, SHIFT, EXP) \
do { \
p = BUF; \
for (i = 0; i < SIZE; i++) { \
TYPE result; \
BREV_LOAD_##SZ(result, p, 1 << (SHIFT - NBITS)); \
check(i, result, EXP); \
} \
} while (0)
#define TEST_BREV_STORE(SZ, TYPE, BUF, VAL, SHIFT) \
do { \
p = BUF; \
memset(BUF, 0xff, sizeof(BUF)); \
for (i = 0; i < SIZE; i++) { \
BREV_STORE_##SZ(p, (TYPE)(VAL), 1 << (SHIFT - NBITS)); \
} \
for (i = 0; i < SIZE; i++) { \
check(i, BUF[i], bitreverse(i)); \
} \
} while (0)
#define TEST_BREV_STORE_NEW(SZ, BUF, SHIFT) \
do { \
p = BUF; \
memset(BUF, 0xff, sizeof(BUF)); \
for (i = 0; i < SIZE; i++) { \
BREV_STORE_##SZ(p, i, 1 << (SHIFT - NBITS)); \
} \
for (i = 0; i < SIZE; i++) { \
check(i, BUF[i], bitreverse(i)); \
} \
} while (0)
/*
* We'll set high_half[i] = i << 16 for use in the .H form of store
* which stores from the high half of the word.
*/
int high_half[SIZE];
int main()
{
void *p;
int i;
for (i = 0; i < SIZE; i++) {
bbuf[i] = bitreverse(i);
hbuf[i] = bitreverse(i);
wbuf[i] = bitreverse(i);
dbuf[i] = bitreverse(i);
high_half[i] = i << 16;
}
TEST_BREV_LOAD(b, int, bbuf, 16, sext8(i));
TEST_BREV_LOAD(ub, int, bbuf, 16, i);
TEST_BREV_LOAD(h, int, hbuf, 15, i);
TEST_BREV_LOAD(uh, int, hbuf, 15, i);
TEST_BREV_LOAD(w, int, wbuf, 14, i);
TEST_BREV_LOAD(d, long long, dbuf, 13, i);
TEST_BREV_STORE(b, int, bbuf, i, 16);
TEST_BREV_STORE(h, int, hbuf, i, 15);
TEST_BREV_STORE(f, int, hbuf, high_half[i], 15);
TEST_BREV_STORE(w, int, wbuf, i, 14);
TEST_BREV_STORE(d, long long, dbuf, i, 13);
TEST_BREV_STORE_NEW(bnew, bbuf, 16);
TEST_BREV_STORE_NEW(hnew, hbuf, 15);
TEST_BREV_STORE_NEW(wnew, wbuf, 14);
puts(err ? "FAIL" : "PASS");
return err ? 1 : 0;
}