mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/riscv: accessors to registers upper part and 128-bit load/store
Get function to retrieve the 64 top bits of a register, stored in the gprh field of the cpu state. Set function that writes the 128-bit value at once. The access to the gprh field can not be protected at compile time to make sure it is accessed only in the 128-bit version of the processor because we have no way to indicate that the misa_mxl_max field is const. The 128-bit ISA adds ldu, lq and sq. We provide support for these instructions. Note that (a) we compute only 64-bit addresses to actually access memory, cowardly utilizing the existing address translation mechanism of QEMU, and (b) we assume for now little-endian memory accesses. Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20220106210108.138226-10-frederic.petrot@univ-grenoble-alpes.fr Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
76a361066f
commit
a2f827ff4f
4 changed files with 163 additions and 10 deletions
|
@ -134,7 +134,7 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
|
|||
return gen_branch(ctx, a, TCG_COND_GEU);
|
||||
}
|
||||
|
||||
static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
|
||||
static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop)
|
||||
{
|
||||
TCGv dest = dest_gpr(ctx, a->rd);
|
||||
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
|
@ -151,6 +151,45 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Compute only 64-bit addresses to use the address translation mechanism */
|
||||
static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
|
||||
{
|
||||
TCGv src1l = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
TCGv destl = dest_gpr(ctx, a->rd);
|
||||
TCGv desth = dest_gprh(ctx, a->rd);
|
||||
TCGv addrl = tcg_temp_new();
|
||||
|
||||
tcg_gen_addi_tl(addrl, src1l, a->imm);
|
||||
|
||||
if ((memop & MO_SIZE) <= MO_64) {
|
||||
tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, memop);
|
||||
if (memop & MO_SIGN) {
|
||||
tcg_gen_sari_tl(desth, destl, 63);
|
||||
} else {
|
||||
tcg_gen_movi_tl(desth, 0);
|
||||
}
|
||||
} else {
|
||||
/* assume little-endian memory access for now */
|
||||
tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ);
|
||||
tcg_gen_addi_tl(addrl, addrl, 8);
|
||||
tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ);
|
||||
}
|
||||
|
||||
gen_set_gpr128(ctx, a->rd, destl, desth);
|
||||
|
||||
tcg_temp_free(addrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
|
||||
{
|
||||
if (get_xl(ctx) == MXL_RV128) {
|
||||
return gen_load_i128(ctx, a, memop);
|
||||
} else {
|
||||
return gen_load_tl(ctx, a, memop);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_lb(DisasContext *ctx, arg_lb *a)
|
||||
{
|
||||
return gen_load(ctx, a, MO_SB);
|
||||
|
@ -166,6 +205,18 @@ static bool trans_lw(DisasContext *ctx, arg_lw *a)
|
|||
return gen_load(ctx, a, MO_TESL);
|
||||
}
|
||||
|
||||
static bool trans_ld(DisasContext *ctx, arg_ld *a)
|
||||
{
|
||||
REQUIRE_64_OR_128BIT(ctx);
|
||||
return gen_load(ctx, a, MO_TESQ);
|
||||
}
|
||||
|
||||
static bool trans_lq(DisasContext *ctx, arg_lq *a)
|
||||
{
|
||||
REQUIRE_128BIT(ctx);
|
||||
return gen_load(ctx, a, MO_TEUO);
|
||||
}
|
||||
|
||||
static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
|
||||
{
|
||||
return gen_load(ctx, a, MO_UB);
|
||||
|
@ -178,17 +229,17 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
|
|||
|
||||
static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
|
||||
{
|
||||
REQUIRE_64BIT(ctx);
|
||||
REQUIRE_64_OR_128BIT(ctx);
|
||||
return gen_load(ctx, a, MO_TEUL);
|
||||
}
|
||||
|
||||
static bool trans_ld(DisasContext *ctx, arg_ld *a)
|
||||
static bool trans_ldu(DisasContext *ctx, arg_ldu *a)
|
||||
{
|
||||
REQUIRE_64BIT(ctx);
|
||||
REQUIRE_128BIT(ctx);
|
||||
return gen_load(ctx, a, MO_TEUQ);
|
||||
}
|
||||
|
||||
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
|
||||
static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop)
|
||||
{
|
||||
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
|
||||
|
@ -204,6 +255,37 @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
|
||||
{
|
||||
TCGv src1l = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE);
|
||||
TCGv src2h = get_gprh(ctx, a->rs2);
|
||||
TCGv addrl = tcg_temp_new();
|
||||
|
||||
tcg_gen_addi_tl(addrl, src1l, a->imm);
|
||||
|
||||
if ((memop & MO_SIZE) <= MO_64) {
|
||||
tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop);
|
||||
} else {
|
||||
/* little-endian memory access assumed for now */
|
||||
tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ);
|
||||
tcg_gen_addi_tl(addrl, addrl, 8);
|
||||
tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ);
|
||||
}
|
||||
|
||||
tcg_temp_free(addrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
|
||||
{
|
||||
if (get_xl(ctx) == MXL_RV128) {
|
||||
return gen_store_i128(ctx, a, memop);
|
||||
} else {
|
||||
return gen_store_tl(ctx, a, memop);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_sb(DisasContext *ctx, arg_sb *a)
|
||||
{
|
||||
return gen_store(ctx, a, MO_SB);
|
||||
|
@ -221,10 +303,16 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
|
|||
|
||||
static bool trans_sd(DisasContext *ctx, arg_sd *a)
|
||||
{
|
||||
REQUIRE_64BIT(ctx);
|
||||
REQUIRE_64_OR_128BIT(ctx);
|
||||
return gen_store(ctx, a, MO_TEUQ);
|
||||
}
|
||||
|
||||
static bool trans_sq(DisasContext *ctx, arg_sq *a)
|
||||
{
|
||||
REQUIRE_128BIT(ctx);
|
||||
return gen_store(ctx, a, MO_TEUO);
|
||||
}
|
||||
|
||||
static bool trans_addi(DisasContext *ctx, arg_addi *a)
|
||||
{
|
||||
return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue