master
inc 115 lines 2.92 KB
Raw
1 /*
2 * RISC-V translation routines for the ZALASR (Load-Aquire and Store-Release)
3 * Extension.
4 *
5 * Copyright (c) 2025 Roan Richmond, roan.richmond@codethink.co.uk
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 *
9 * The documentation of the ISA extension can be found here:
10 * https://github.com/riscv/riscv-zalasr/tree/v0.9
11 */
12
13 #define REQUIRE_ZALASR(ctx) do { \
14 if (!ctx->cfg_ptr->ext_zalasr) { \
15 return false; \
16 } \
17 } while (0)
18
19 static bool gen_load_acquire(DisasContext *ctx, arg_lb_aqrl *a, MemOp memop)
20 {
21 decode_save_opc(ctx, 0);
22
23 TCGv addr = get_address(ctx, a->rs1, 0);
24 TCGv dest = get_gpr(ctx, a->rd, EXT_NONE);
25 TCGBar bar = (a->rl) ? TCG_BAR_STRL : 0;
26
27 /* Check that AQ is set, as this is mandatory */
28 if (!a->aq) {
29 return false;
30 }
31
32 memop |= MO_ALIGN | ctx->mo_endianness;
33 memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
34
35 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
36 gen_set_gpr(ctx, a->rd, dest);
37
38 /* Add a memory barrier implied by AQ (mandatory) and RL (optional) */
39 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ | bar);
40
41 return true;
42 }
43
44 static bool trans_lb_aqrl(DisasContext *ctx, arg_lb_aqrl *a)
45 {
46 REQUIRE_ZALASR(ctx);
47 return gen_load_acquire(ctx, a, MO_SB);
48 }
49
50 static bool trans_lh_aqrl(DisasContext *ctx, arg_lh_aqrl *a)
51 {
52 REQUIRE_ZALASR(ctx);
53 return gen_load_acquire(ctx, a, MO_SW);
54 }
55
56 static bool trans_lw_aqrl(DisasContext *ctx, arg_lw_aqrl *a)
57 {
58 REQUIRE_ZALASR(ctx);
59 return gen_load_acquire(ctx, a, MO_SL);
60 }
61
62 static bool trans_ld_aqrl(DisasContext *ctx, arg_ld_aqrl *a)
63 {
64 REQUIRE_64BIT(ctx);
65 REQUIRE_ZALASR(ctx);
66 return gen_load_acquire(ctx, a, MO_UQ);
67 }
68
69 static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
70 {
71 decode_save_opc(ctx, 0);
72
73 TCGv addr = get_address(ctx, a->rs1, 0);
74 TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
75 TCGBar bar = (a->aq) ? TCG_BAR_LDAQ : 0;
76
77 /* Check that RL is set, as this is mandatory */
78 if (!a->rl) {
79 return false;
80 }
81
82 memop |= MO_ALIGN | ctx->mo_endianness;
83 memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
84
85 /* Add a memory barrier implied by RL (mandatory) and AQ (optional) */
86 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL | bar);
87
88 tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
89 return true;
90 }
91
92 static bool trans_sb_aqrl(DisasContext *ctx, arg_sb_aqrl *a)
93 {
94 REQUIRE_ZALASR(ctx);
95 return gen_store_release(ctx, a, MO_SB);
96 }
97
98 static bool trans_sh_aqrl(DisasContext *ctx, arg_sh_aqrl *a)
99 {
100 REQUIRE_ZALASR(ctx);
101 return gen_store_release(ctx, a, MO_SW);
102 }
103
104 static bool trans_sw_aqrl(DisasContext *ctx, arg_sw_aqrl *a)
105 {
106 REQUIRE_ZALASR(ctx);
107 return gen_store_release(ctx, a, MO_SL);
108 }
109
110 static bool trans_sd_aqrl(DisasContext *ctx, arg_sd_aqrl *a)
111 {
112 REQUIRE_64BIT(ctx);
113 REQUIRE_ZALASR(ctx);
114 return gen_store_release(ctx, a, MO_UQ);
115 }