From: Christoph Müllner <[email protected]> This patch adds support for the T-Head MemPair instructions. The patch uses the T-Head specific decoder and translation.
Signed-off-by: Christoph Müllner <[email protected]> --- target/riscv/cpu.c | 1 + target/riscv/cpu.h | 1 + target/riscv/insn_trans/trans_xthead.c.inc | 90 ++++++++++++++++++++++ target/riscv/meson.build | 1 + target/riscv/translate.c | 3 + target/riscv/xtheadmempair.decode | 29 +++++++ 6 files changed, 125 insertions(+) create mode 100644 target/riscv/xtheadmempair.decode diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 990a1f57af..9370722ffa 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -926,6 +926,7 @@ static Property riscv_cpu_extensions[] = { DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false), DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false), DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false), + DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false), DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false), DEFINE_PROP_BOOL("xtheadxmae", RISCVCPU, cfg.ext_xtheadxmae, false), DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1982d9293f..6cc2d19075 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -446,6 +446,7 @@ struct RISCVCPUConfig { bool ext_xtheadcmo; bool ext_xtheadcondmov; bool ext_xtheadmac; + bool ext_xtheadmempair; bool ext_xtheadsync; bool ext_xtheadxmae; bool ext_XVentanaCondOps; diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index fc8307b113..a2bae249fb 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -284,3 +284,93 @@ static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a) ctx->ol = MXL_RV32; return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL); } + +static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, + int shamt) +{ + TCGv rd1 = dest_gpr(ctx, a->rd1); + TCGv rd2 = dest_gpr(ctx, a->rd2); + TCGv rs = get_gpr(ctx, a->rs, EXT_NONE); + TCGv addr1 = tcg_temp_new(); + TCGv addr2 = tcg_temp_new(); + + tcg_gen_movi_tl(addr1, a->sh2); + tcg_gen_shli_tl(addr1, addr1, shamt); + tcg_gen_add_tl(addr1, rs, addr1); + if ((memop & MO_SIZE) == MO_64) { + tcg_gen_addi_tl(addr2, addr1, 8); + } else { + tcg_gen_addi_tl(addr2, addr1, 4); + } + + if (get_xl(ctx) == MXL_RV32) { + tcg_gen_ext32u_tl(addr1, addr1); + tcg_gen_ext32u_tl(addr2, addr2); + } + + tcg_gen_qemu_ld_tl(rd1, addr1, ctx->mem_idx, memop); + tcg_gen_qemu_ld_tl(rd2, addr2, ctx->mem_idx, memop); + gen_set_gpr(ctx, a->rd1, rd1); + gen_set_gpr(ctx, a->rd2, rd2); + + tcg_temp_free(addr1); + tcg_temp_free(addr2); + return true; +} + +static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a) +{ + REQUIRE_64BIT(ctx); + return gen_loadpair_tl(ctx, a, MO_TESQ, 4); +} + +static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a) +{ + return gen_loadpair_tl(ctx, a, MO_TESL, 3); +} + +static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a) +{ + return gen_loadpair_tl(ctx, a, MO_TEUL, 3); +} + +static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, + int shamt) +{ + TCGv data1 = get_gpr(ctx, a->rd1, EXT_NONE); + TCGv data2 = get_gpr(ctx, a->rd2, EXT_NONE); + TCGv rs = get_gpr(ctx, a->rs, EXT_NONE); + TCGv addr1 = tcg_temp_new(); + TCGv addr2 = tcg_temp_new(); + + tcg_gen_movi_tl(addr1, a->sh2); + tcg_gen_shli_tl(addr1, addr1, shamt); + tcg_gen_add_tl(addr1, rs, addr1); + if ((memop & MO_SIZE) == MO_64) { + tcg_gen_addi_tl(addr2, addr1, 8); + } else { + tcg_gen_addi_tl(addr2, addr1, 4); + } + + if (get_xl(ctx) == MXL_RV32) { + tcg_gen_ext32u_tl(addr1, addr1); + tcg_gen_ext32u_tl(addr2, addr2); + } + + tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop); + tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop); + + tcg_temp_free(addr1); + tcg_temp_free(addr2); + return true; +} + +static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a) +{ + return gen_storepair_tl(ctx, a, MO_TESQ, 4); +} + +static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a) +{ + return gen_storepair_tl(ctx, a, MO_TESL, 3); +} diff --git a/target/riscv/meson.build b/target/riscv/meson.build index 55c019e55b..998f0ba336 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -8,6 +8,7 @@ gen = [ decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'), decodetree.process('xtheadcondmov.decode', extra_args: '--static-decode=decode_xtheadcondmov'), decodetree.process('xtheadmac.decode', extra_args: '--static-decode=decode_xtheadmac'), + decodetree.process('xtheadmempair.decode', extra_args: '--static-decode=decode_xtheadmempair'), decodetree.process('xtheadsync.decode', extra_args: '--static-decode=decode_xtheadsync'), decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'), ] diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 56cc89ce4a..308de419cb 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -138,6 +138,7 @@ MATERIALISE_EXT_PREDICATE(xtheadbs) MATERIALISE_EXT_PREDICATE(xtheadcmo) MATERIALISE_EXT_PREDICATE(xtheadcondmov); MATERIALISE_EXT_PREDICATE(xtheadmac); +MATERIALISE_EXT_PREDICATE(xtheadmempair); MATERIALISE_EXT_PREDICATE(xtheadsync) MATERIALISE_EXT_PREDICATE(XVentanaCondOps) @@ -731,6 +732,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm) #include "decode-xtheadcmo.c.inc" #include "decode-xtheadcondmov.c.inc" #include "decode-xtheadmac.c.inc" +#include "decode-xtheadmempair.c.inc" #include "decode-xtheadsync.c.inc" #include "decode-XVentanaCondOps.c.inc" @@ -1058,6 +1060,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) { has_xtheadcmo_p, decode_xtheadcmo }, { has_xtheadcondmov_p, decode_xtheadcondmov }, { has_xtheadmac_p, decode_xtheadmac }, + { has_xtheadmempair_p, decode_xtheadmempair }, { has_xtheadsync_p, decode_xtheadsync }, { has_XVentanaCondOps_p, decode_XVentanaCodeOps }, }; diff --git a/target/riscv/xtheadmempair.decode b/target/riscv/xtheadmempair.decode new file mode 100644 index 0000000000..135dc10a59 --- /dev/null +++ b/target/riscv/xtheadmempair.decode @@ -0,0 +1,29 @@ +# +# RISC-V instruction decode for the XTheadMemPair extension +# +# Copyright (c) 2022 Christoph Muellner, [email protected] +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +# The XTheadMemPair extension provides two-GP-register operations. +# +# It is documented in +# https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.0.0/xthead-2022-09-05-2.0.0.pdf + +# Fields +%sh2 25:2 +%rd2 20:5 +%rs 15:5 +%rd1 7:5 + +# Argument sets +&th_pair rd1 rs rd2 sh2 + +# Formats: +@th_pair ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2 + +th_ldd 11111 .. ..... ..... 100 ..... 0001011 @th_pair +th_lwd 11100 .. ..... ..... 100 ..... 0001011 @th_pair +th_lwud 11110 .. ..... ..... 100 ..... 0001011 @th_pair +th_sdd 11111 .. ..... ..... 101 ..... 0001011 @th_pair +th_swd 11100 .. ..... ..... 101 ..... 0001011 @th_pair -- 2.37.2
