master
inc 105 lines 2.39 KB
Raw
1 /*
2 * RISC-V translation routines for the Zilsd & Zclsd Extension.
3 *
4 * Copyright (c) 2025 Nucleisys, Inc.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 *
8 * The documentation of the ISA extensions can be found here:
9 * https://github.com/riscv/riscv-zilsd/releases/tag/v1.0
10 */
11
12 #define REQUIRE_ZILSD(ctx) do { \
13 if (!ctx->cfg_ptr->ext_zilsd) \
14 return false; \
15 } while (0)
16
17 #define REQUIRE_ZCLSD(ctx) do { \
18 if (!ctx->cfg_ptr->ext_zclsd) \
19 return false; \
20 } while (0)
21
22 static bool gen_load_i64(DisasContext *ctx, arg_ld *a)
23 {
24 if ((a->rd) % 2) {
25 return false;
26 }
27
28 TCGv dest_low = dest_gpr(ctx, a->rd);
29 TCGv dest_high = dest_gpr(ctx, a->rd + 1);
30 TCGv addr = get_address(ctx, a->rs1, a->imm);
31 TCGv_i64 tmp = tcg_temp_new_i64();
32
33 tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_SQ | ctx->mo_endianness);
34
35 if (a->rd == 0) {
36 return true;
37 }
38
39 tcg_gen_extr_i64_tl(dest_low, dest_high, tmp);
40
41 gen_set_gpr(ctx, a->rd, dest_low);
42 gen_set_gpr(ctx, a->rd + 1, dest_high);
43
44 return true;
45 }
46
47 static bool trans_zilsd_ld(DisasContext *ctx, arg_zilsd_ld *a)
48 {
49 REQUIRE_32BIT(ctx);
50 REQUIRE_ZILSD(ctx);
51 return gen_load_i64(ctx, a);
52 }
53
54 static bool trans_zclsd_ld(DisasContext *ctx, arg_zclsd_ld *a)
55 {
56 REQUIRE_32BIT(ctx);
57 REQUIRE_ZCLSD(ctx);
58 return gen_load_i64(ctx, a);
59 }
60
61 static bool trans_zclsd_ldsp(DisasContext *ctx, arg_zclsd_ldsp *a)
62 {
63 REQUIRE_32BIT(ctx);
64 REQUIRE_ZCLSD(ctx);
65
66 if (a->rd == 0) {
67 return false;
68 }
69 return gen_load_i64(ctx, a);
70 }
71
72 static bool gen_store_i64(DisasContext *ctx, arg_sd *a)
73 {
74 if ((a->rs2) % 2) {
75 return false;
76 }
77
78 TCGv data_low = get_gpr(ctx, a->rs2, EXT_NONE);
79 TCGv data_high = get_gpr(ctx, a->rs2 + 1, EXT_NONE);
80 TCGv addr = get_address(ctx, a->rs1, a->imm);
81 TCGv_i64 tmp = tcg_temp_new_i64();
82
83 if (a->rs2 == 0) {
84 tmp = tcg_constant_i64(0);
85 } else {
86 tcg_gen_concat_tl_i64(tmp, data_low, data_high);
87 }
88 tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_SQ | ctx->mo_endianness);
89
90 return true;
91 }
92
93 static bool trans_zilsd_sd(DisasContext *ctx, arg_zilsd_sd *a)
94 {
95 REQUIRE_32BIT(ctx);
96 REQUIRE_ZILSD(ctx);
97 return gen_store_i64(ctx, a);
98 }
99
100 static bool trans_zclsd_sd(DisasContext *ctx, arg_zclsd_sd *a)
101 {
102 REQUIRE_32BIT(ctx);
103 REQUIRE_ZCLSD(ctx);
104 return gen_store_i64(ctx, a);
105 }