1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (c) 2021 Loongson Technology Corporation Limited
4 */
5
6static bool gen_load(DisasContext *ctx, arg_rr_i *a, MemOp mop)
7{
8    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
9    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
10
11    addr = make_address_i(ctx, addr, a->imm);
12
13    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
14    gen_set_gpr(a->rd, dest, EXT_NONE);
15    return true;
16}
17
18static bool gen_store(DisasContext *ctx, arg_rr_i *a, MemOp mop)
19{
20    TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
21    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
22
23    addr = make_address_i(ctx, addr, a->imm);
24
25    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
26    return true;
27}
28
29static bool gen_loadx(DisasContext *ctx, arg_rrr *a, MemOp mop)
30{
31    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
32    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
33    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
34    TCGv addr = make_address_x(ctx, src1, src2);
35
36    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
37    gen_set_gpr(a->rd, dest, EXT_NONE);
38
39    return true;
40}
41
42static bool gen_storex(DisasContext *ctx, arg_rrr *a, MemOp mop)
43{
44    TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
45    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
46    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
47    TCGv addr = make_address_x(ctx, src1, src2);
48
49    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
50
51    return true;
52}
53
54static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
55{
56    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
57    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
58    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
59
60    gen_helper_asrtgt_d(tcg_env, src1, src2);
61    src1 = make_address_i(ctx, src1, 0);
62    tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
63    gen_set_gpr(a->rd, dest, EXT_NONE);
64
65    return true;
66}
67
68static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
69{
70    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
71    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
72    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
73
74    gen_helper_asrtle_d(tcg_env, src1, src2);
75    src1 = make_address_i(ctx, src1, 0);
76    tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
77    gen_set_gpr(a->rd, dest, EXT_NONE);
78
79    return true;
80}
81
82static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
83{
84    TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
85    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
86    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
87
88    gen_helper_asrtgt_d(tcg_env, src1, src2);
89    src1 = make_address_i(ctx, src1, 0);
90    tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
91
92    return true;
93}
94
95static bool gen_store_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
96{
97    TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
98    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
99    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
100
101    gen_helper_asrtle_d(tcg_env, src1, src2);
102    src1 = make_address_i(ctx, src1, 0);
103    tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
104
105    return true;
106}
107
108static bool trans_preld(DisasContext *ctx, arg_preld *a)
109{
110    return true;
111}
112
113static bool trans_preldx(DisasContext *ctx, arg_preldx * a)
114{
115    return true;
116}
117
118static bool trans_dbar(DisasContext *ctx, arg_dbar * a)
119{
120    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
121    return true;
122}
123
124static bool trans_ibar(DisasContext *ctx, arg_ibar *a)
125{
126    ctx->base.is_jmp = DISAS_STOP;
127    return true;
128}
129
130static bool gen_ldptr(DisasContext *ctx, arg_rr_i *a, MemOp mop)
131{
132    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
133    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
134
135    addr = make_address_i(ctx, addr, a->imm);
136
137    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
138    gen_set_gpr(a->rd, dest, EXT_NONE);
139    return true;
140}
141
142static bool gen_stptr(DisasContext *ctx, arg_rr_i *a, MemOp mop)
143{
144    TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
145    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
146
147    addr = make_address_i(ctx, addr, a->imm);
148
149    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
150    return true;
151}
152
153TRANS(ld_b, ALL, gen_load, MO_SB)
154TRANS(ld_h, ALL, gen_load, MO_TESW)
155TRANS(ld_w, ALL, gen_load, MO_TESL)
156TRANS(ld_d, 64, gen_load, MO_TEUQ)
157TRANS(st_b, ALL, gen_store, MO_UB)
158TRANS(st_h, ALL, gen_store, MO_TEUW)
159TRANS(st_w, ALL, gen_store, MO_TEUL)
160TRANS(st_d, 64, gen_store, MO_TEUQ)
161TRANS(ld_bu, ALL, gen_load, MO_UB)
162TRANS(ld_hu, ALL, gen_load, MO_TEUW)
163TRANS(ld_wu, 64, gen_load, MO_TEUL)
164TRANS(ldx_b, 64, gen_loadx, MO_SB)
165TRANS(ldx_h, 64, gen_loadx, MO_TESW)
166TRANS(ldx_w, 64, gen_loadx, MO_TESL)
167TRANS(ldx_d, 64, gen_loadx, MO_TEUQ)
168TRANS(stx_b, 64, gen_storex, MO_UB)
169TRANS(stx_h, 64, gen_storex, MO_TEUW)
170TRANS(stx_w, 64, gen_storex, MO_TEUL)
171TRANS(stx_d, 64, gen_storex, MO_TEUQ)
172TRANS(ldx_bu, 64, gen_loadx, MO_UB)
173TRANS(ldx_hu, 64, gen_loadx, MO_TEUW)
174TRANS(ldx_wu, 64, gen_loadx, MO_TEUL)
175TRANS(ldptr_w, 64, gen_ldptr, MO_TESL)
176TRANS(stptr_w, 64, gen_stptr, MO_TEUL)
177TRANS(ldptr_d, 64, gen_ldptr, MO_TEUQ)
178TRANS(stptr_d, 64, gen_stptr, MO_TEUQ)
179TRANS(ldgt_b, 64, gen_load_gt, MO_SB)
180TRANS(ldgt_h, 64, gen_load_gt, MO_TESW)
181TRANS(ldgt_w, 64, gen_load_gt, MO_TESL)
182TRANS(ldgt_d, 64, gen_load_gt, MO_TEUQ)
183TRANS(ldle_b, 64, gen_load_le, MO_SB)
184TRANS(ldle_h, 64, gen_load_le, MO_TESW)
185TRANS(ldle_w, 64, gen_load_le, MO_TESL)
186TRANS(ldle_d, 64, gen_load_le, MO_TEUQ)
187TRANS(stgt_b, 64, gen_store_gt, MO_UB)
188TRANS(stgt_h, 64, gen_store_gt, MO_TEUW)
189TRANS(stgt_w, 64, gen_store_gt, MO_TEUL)
190TRANS(stgt_d, 64, gen_store_gt, MO_TEUQ)
191TRANS(stle_b, 64, gen_store_le, MO_UB)
192TRANS(stle_h, 64, gen_store_le, MO_TEUW)
193TRANS(stle_w, 64, gen_store_le, MO_TEUL)
194TRANS(stle_d, 64, gen_store_le, MO_TEUQ)
195