target/tricore: Implement CRCN insn
reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Message-ID: <20230828112651.522058-3-kbastian@mail.uni-paderborn.de>
This commit is contained in:
parent
d97fa9a00d
commit
3e2a5107c5
@ -134,6 +134,7 @@ DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(crc32b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(crc32_be, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(crc32_le, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(crcn, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(shuffle, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
/* CSA */
|
||||
DEF_HELPER_2(call, void, env, i32)
|
||||
|
@ -2308,6 +2308,69 @@ uint32_t helper_crc32_le(uint32_t arg0, uint32_t arg1)
|
||||
return crc32(arg1, buf, 4);
|
||||
}
|
||||
|
||||
static uint32_t crc_div(uint32_t crc_in, uint32_t data, uint32_t gen,
|
||||
uint32_t n, uint32_t m)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
data = data << n;
|
||||
for (i = 0; i < m; i++) {
|
||||
if (crc_in & (1u << (n - 1))) {
|
||||
crc_in <<= 1;
|
||||
if (data & (1u << (m - 1))) {
|
||||
crc_in++;
|
||||
}
|
||||
crc_in ^= gen;
|
||||
} else {
|
||||
crc_in <<= 1;
|
||||
if (data & (1u << (m - 1))) {
|
||||
crc_in++;
|
||||
}
|
||||
}
|
||||
data <<= 1;
|
||||
}
|
||||
|
||||
return crc_in;
|
||||
}
|
||||
|
||||
uint32_t helper_crcn(uint32_t arg0, uint32_t arg1, uint32_t arg2)
|
||||
{
|
||||
uint32_t crc_out, crc_in;
|
||||
uint32_t n = extract32(arg0, 12, 4) + 1;
|
||||
uint32_t gen = extract32(arg0, 16, n);
|
||||
uint32_t inv = extract32(arg0, 9, 1);
|
||||
uint32_t le = extract32(arg0, 8, 1);
|
||||
uint32_t m = extract32(arg0, 0, 3) + 1;
|
||||
uint32_t data = extract32(arg1, 0, m);
|
||||
uint32_t seed = extract32(arg2, 0, n);
|
||||
|
||||
if (le == 1) {
|
||||
if (m == 0) {
|
||||
data = 0;
|
||||
} else {
|
||||
data = revbit32(data) >> (32 - m);
|
||||
}
|
||||
}
|
||||
|
||||
if (inv == 1) {
|
||||
seed = ~seed;
|
||||
}
|
||||
|
||||
if (m > n) {
|
||||
crc_in = (data >> (m - n)) ^ seed;
|
||||
} else {
|
||||
crc_in = (data << (n - m)) ^ seed;
|
||||
}
|
||||
|
||||
crc_out = crc_div(crc_in, data, gen, n, m);
|
||||
|
||||
if (inv) {
|
||||
crc_out = ~crc_out;
|
||||
}
|
||||
|
||||
return extract32(crc_out, 0, n);
|
||||
}
|
||||
|
||||
uint32_t helper_shuffle(uint32_t arg0, uint32_t arg1)
|
||||
{
|
||||
uint32_t resb;
|
||||
|
@ -6669,6 +6669,14 @@ static void decode_rrr_divide(DisasContext *ctx)
|
||||
gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
|
||||
cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
|
||||
break;
|
||||
case OPC2_32_RRR_CRCN:
|
||||
if (has_feature(ctx, TRICORE_FEATURE_162)) {
|
||||
gen_helper_crcn(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2],
|
||||
cpu_gpr_d[r3]);
|
||||
} else {
|
||||
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
|
||||
}
|
||||
break;
|
||||
case OPC2_32_RRR_ADD_F:
|
||||
gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
|
||||
break;
|
||||
|
@ -1247,6 +1247,7 @@ enum {
|
||||
OPC2_32_RRR_SUB_F = 0x03,
|
||||
OPC2_32_RRR_MADD_F = 0x06,
|
||||
OPC2_32_RRR_MSUB_F = 0x07,
|
||||
OPC2_32_RRR_CRCN = 0x01, /* 1.6.2 up */
|
||||
};
|
||||
/*
|
||||
* RRR1 Format
|
||||
|
@ -9,6 +9,7 @@ CFLAGS = -mtc162 -c -I$(TESTS_PATH)
|
||||
TESTS += test_abs.asm.tst
|
||||
TESTS += test_bmerge.asm.tst
|
||||
TESTS += test_clz.asm.tst
|
||||
TESTS += test_crcn.asm.tst
|
||||
TESTS += test_dextr.asm.tst
|
||||
TESTS += test_dvstep.asm.tst
|
||||
TESTS += test_fadd.asm.tst
|
||||
|
9
tests/tcg/tricore/asm/test_crcn.S
Normal file
9
tests/tcg/tricore/asm/test_crcn.S
Normal file
@ -0,0 +1,9 @@
|
||||
#include "macros.h"
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
# insn num result rs1 rs2 rs3
|
||||
# | | | | | |
|
||||
TEST_D_DDD(crcn, 1, 0x00002bed, 0x0, 0xa10ddeed, 0x0)
|
||||
|
||||
TEST_PASSFAIL
|
Loading…
Reference in New Issue
Block a user