diff options
author | Bastian Koppelmann <kbastian@mail.uni-paderborn.de> | 2023-08-28 13:26:42 +0200 |
---|---|---|
committer | Bastian Koppelmann <kbastian@mail.uni-paderborn.de> | 2023-09-28 10:45:22 +0200 |
commit | 3e2a5107c52f5bf7ed68f4b468cff5be456f1097 (patch) | |
tree | 8a18adf6914e4ed77bf6413378d15db5ffcbbb0c /target | |
parent | d97fa9a00d5b333c8642670b7b55f9101d495dce (diff) | |
download | qemu-3e2a5107c52f5bf7ed68f4b468cff5be456f1097.zip qemu-3e2a5107c52f5bf7ed68f4b468cff5be456f1097.tar.gz qemu-3e2a5107c52f5bf7ed68f4b468cff5be456f1097.tar.bz2 |
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>
Diffstat (limited to 'target')
-rw-r--r-- | target/tricore/helper.h | 1 | ||||
-rw-r--r-- | target/tricore/op_helper.c | 63 | ||||
-rw-r--r-- | target/tricore/translate.c | 8 | ||||
-rw-r--r-- | target/tricore/tricore-opcodes.h | 1 |
4 files changed, 73 insertions, 0 deletions
diff --git a/target/tricore/helper.h b/target/tricore/helper.h index 31d71ea..1906454 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -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) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 89be1ed..0cf8eb5 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -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; diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 6ae5ccb..4e7e18f 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -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; diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index bc62b73..f070571 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -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 |