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