xref: /openbmc/qemu/target/loongarch/disas.c (revision aae1746c)
1*aae1746cSSong Gao /* SPDX-License-Identifier: GPL-2.0-or-later */
2*aae1746cSSong Gao /*
3*aae1746cSSong Gao  * QEMU LoongArch Disassembler
4*aae1746cSSong Gao  *
5*aae1746cSSong Gao  * Copyright (c) 2021 Loongson Technology Corporation Limited.
6*aae1746cSSong Gao  */
7*aae1746cSSong Gao 
8*aae1746cSSong Gao #include "qemu/osdep.h"
9*aae1746cSSong Gao #include "disas/dis-asm.h"
10*aae1746cSSong Gao #include "qemu/bitops.h"
11*aae1746cSSong Gao 
12*aae1746cSSong Gao typedef struct {
13*aae1746cSSong Gao     disassemble_info *info;
14*aae1746cSSong Gao     uint64_t pc;
15*aae1746cSSong Gao     uint32_t insn;
16*aae1746cSSong Gao } DisasContext;
17*aae1746cSSong Gao 
18*aae1746cSSong Gao static inline int plus_1(DisasContext *ctx, int x)
19*aae1746cSSong Gao {
20*aae1746cSSong Gao     return x + 1;
21*aae1746cSSong Gao }
22*aae1746cSSong Gao 
23*aae1746cSSong Gao static inline int shl_2(DisasContext *ctx, int x)
24*aae1746cSSong Gao {
25*aae1746cSSong Gao     return x << 2;
26*aae1746cSSong Gao }
27*aae1746cSSong Gao 
28*aae1746cSSong Gao #define output(C, INSN, FMT, ...)                                   \
29*aae1746cSSong Gao {                                                                   \
30*aae1746cSSong Gao     (C)->info->fprintf_func((C)->info->stream, "%08x   %-9s\t" FMT, \
31*aae1746cSSong Gao                             (C)->insn, INSN, ##__VA_ARGS__);        \
32*aae1746cSSong Gao }
33*aae1746cSSong Gao 
34*aae1746cSSong Gao #include "decode-insns.c.inc"
35*aae1746cSSong Gao 
36*aae1746cSSong Gao int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
37*aae1746cSSong Gao {
38*aae1746cSSong Gao     bfd_byte buffer[4];
39*aae1746cSSong Gao     uint32_t insn;
40*aae1746cSSong Gao     int status;
41*aae1746cSSong Gao 
42*aae1746cSSong Gao     status = (*info->read_memory_func)(memaddr, buffer, 4, info);
43*aae1746cSSong Gao     if (status != 0) {
44*aae1746cSSong Gao         (*info->memory_error_func)(status, memaddr, info);
45*aae1746cSSong Gao         return -1;
46*aae1746cSSong Gao     }
47*aae1746cSSong Gao     insn = bfd_getl32(buffer);
48*aae1746cSSong Gao     DisasContext ctx = {
49*aae1746cSSong Gao         .info = info,
50*aae1746cSSong Gao         .pc = memaddr,
51*aae1746cSSong Gao         .insn = insn
52*aae1746cSSong Gao     };
53*aae1746cSSong Gao 
54*aae1746cSSong Gao     if (!decode(&ctx, insn)) {
55*aae1746cSSong Gao         output(&ctx, "illegal", "");
56*aae1746cSSong Gao     }
57*aae1746cSSong Gao     return 4;
58*aae1746cSSong Gao }
59*aae1746cSSong Gao 
60*aae1746cSSong Gao static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
61*aae1746cSSong Gao {
62*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
63*aae1746cSSong Gao }
64*aae1746cSSong Gao 
65*aae1746cSSong Gao static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
66*aae1746cSSong Gao {
67*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
68*aae1746cSSong Gao }
69*aae1746cSSong Gao 
70*aae1746cSSong Gao static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
71*aae1746cSSong Gao {
72*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
73*aae1746cSSong Gao }
74*aae1746cSSong Gao 
75*aae1746cSSong Gao static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
76*aae1746cSSong Gao                           const char *mnemonic)
77*aae1746cSSong Gao {
78*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
79*aae1746cSSong Gao }
80*aae1746cSSong Gao 
81*aae1746cSSong Gao static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
82*aae1746cSSong Gao {
83*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
84*aae1746cSSong Gao }
85*aae1746cSSong Gao 
86*aae1746cSSong Gao static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
87*aae1746cSSong Gao                           const char *mnemonic)
88*aae1746cSSong Gao {
89*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls);
90*aae1746cSSong Gao }
91*aae1746cSSong Gao 
92*aae1746cSSong Gao static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
93*aae1746cSSong Gao                             const char *mnemonic)
94*aae1746cSSong Gao {
95*aae1746cSSong Gao     output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
96*aae1746cSSong Gao }
97*aae1746cSSong Gao 
98*aae1746cSSong Gao static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
99*aae1746cSSong Gao {
100*aae1746cSSong Gao     output(ctx, mnemonic, "%d", a->imm);
101*aae1746cSSong Gao }
102*aae1746cSSong Gao 
103*aae1746cSSong Gao static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
104*aae1746cSSong Gao                          const char *mnemonic)
105*aae1746cSSong Gao {
106*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
107*aae1746cSSong Gao }
108*aae1746cSSong Gao 
109*aae1746cSSong Gao static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
110*aae1746cSSong Gao {
111*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
112*aae1746cSSong Gao }
113*aae1746cSSong Gao 
114*aae1746cSSong Gao static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
115*aae1746cSSong Gao {
116*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
117*aae1746cSSong Gao }
118*aae1746cSSong Gao 
119*aae1746cSSong Gao static void output_ffff(DisasContext *ctx, arg_ffff *a, const char *mnemonic)
120*aae1746cSSong Gao {
121*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, f%d, f%d, f%d", a->fd, a->fj, a->fk, a->fa);
122*aae1746cSSong Gao }
123*aae1746cSSong Gao 
124*aae1746cSSong Gao static void output_fffc(DisasContext *ctx, arg_fffc *a, const char *mnemonic)
125*aae1746cSSong Gao {
126*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, f%d, f%d, %d", a->fd, a->fj, a->fk, a->ca);
127*aae1746cSSong Gao }
128*aae1746cSSong Gao 
129*aae1746cSSong Gao static void output_fr(DisasContext *ctx, arg_fr *a, const char *mnemonic)
130*aae1746cSSong Gao {
131*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, r%d", a->fd, a->rj);
132*aae1746cSSong Gao }
133*aae1746cSSong Gao 
134*aae1746cSSong Gao static void output_rf(DisasContext *ctx, arg_rf *a, const char *mnemonic)
135*aae1746cSSong Gao {
136*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, f%d", a->rd, a->fj);
137*aae1746cSSong Gao }
138*aae1746cSSong Gao 
139*aae1746cSSong Gao static void output_fcsrd_r(DisasContext *ctx, arg_fcsrd_r *a,
140*aae1746cSSong Gao                            const char *mnemonic)
141*aae1746cSSong Gao {
142*aae1746cSSong Gao     output(ctx, mnemonic, "fcsr%d, r%d", a->fcsrd, a->rj);
143*aae1746cSSong Gao }
144*aae1746cSSong Gao 
145*aae1746cSSong Gao static void output_r_fcsrs(DisasContext *ctx, arg_r_fcsrs *a,
146*aae1746cSSong Gao                            const char *mnemonic)
147*aae1746cSSong Gao {
148*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, fcsr%d", a->rd, a->fcsrs);
149*aae1746cSSong Gao }
150*aae1746cSSong Gao 
151*aae1746cSSong Gao static void output_cf(DisasContext *ctx, arg_cf *a, const char *mnemonic)
152*aae1746cSSong Gao {
153*aae1746cSSong Gao     output(ctx, mnemonic, "fcc%d, f%d", a->cd, a->fj);
154*aae1746cSSong Gao }
155*aae1746cSSong Gao 
156*aae1746cSSong Gao static void output_fc(DisasContext *ctx, arg_fc *a, const char *mnemonic)
157*aae1746cSSong Gao {
158*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, fcc%d", a->fd, a->cj);
159*aae1746cSSong Gao }
160*aae1746cSSong Gao 
161*aae1746cSSong Gao static void output_cr(DisasContext *ctx, arg_cr *a, const char *mnemonic)
162*aae1746cSSong Gao {
163*aae1746cSSong Gao     output(ctx, mnemonic, "fcc%d, r%d", a->cd, a->rj);
164*aae1746cSSong Gao }
165*aae1746cSSong Gao 
166*aae1746cSSong Gao static void output_rc(DisasContext *ctx, arg_rc *a, const char *mnemonic)
167*aae1746cSSong Gao {
168*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, fcc%d", a->rd, a->cj);
169*aae1746cSSong Gao }
170*aae1746cSSong Gao 
171*aae1746cSSong Gao static void output_frr(DisasContext *ctx, arg_frr *a, const char *mnemonic)
172*aae1746cSSong Gao {
173*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, r%d, r%d", a->fd, a->rj, a->rk);
174*aae1746cSSong Gao }
175*aae1746cSSong Gao 
176*aae1746cSSong Gao static void output_fr_i(DisasContext *ctx, arg_fr_i *a, const char *mnemonic)
177*aae1746cSSong Gao {
178*aae1746cSSong Gao     output(ctx, mnemonic, "f%d, r%d, %d", a->fd, a->rj, a->imm);
179*aae1746cSSong Gao }
180*aae1746cSSong Gao 
181*aae1746cSSong Gao static void output_r_offs(DisasContext *ctx, arg_r_offs *a,
182*aae1746cSSong Gao                           const char *mnemonic)
183*aae1746cSSong Gao {
184*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, %d # 0x%" PRIx64, a->rj, a->offs,
185*aae1746cSSong Gao            ctx->pc + a->offs);
186*aae1746cSSong Gao }
187*aae1746cSSong Gao 
188*aae1746cSSong Gao static void output_c_offs(DisasContext *ctx, arg_c_offs *a,
189*aae1746cSSong Gao                           const char *mnemonic)
190*aae1746cSSong Gao {
191*aae1746cSSong Gao     output(ctx, mnemonic, "fcc%d, %d # 0x%" PRIx64, a->cj, a->offs,
192*aae1746cSSong Gao            ctx->pc + a->offs);
193*aae1746cSSong Gao }
194*aae1746cSSong Gao 
195*aae1746cSSong Gao static void output_offs(DisasContext *ctx, arg_offs *a,
196*aae1746cSSong Gao                         const char *mnemonic)
197*aae1746cSSong Gao {
198*aae1746cSSong Gao     output(ctx, mnemonic, "%d # 0x%" PRIx64, a->offs, ctx->pc + a->offs);
199*aae1746cSSong Gao }
200*aae1746cSSong Gao 
201*aae1746cSSong Gao static void output_rr_offs(DisasContext *ctx, arg_rr_offs *a,
202*aae1746cSSong Gao                            const char *mnemonic)
203*aae1746cSSong Gao {
204*aae1746cSSong Gao     output(ctx, mnemonic, "r%d, r%d, %d # 0x%" PRIx64, a->rj,
205*aae1746cSSong Gao            a->rd, a->offs, ctx->pc + a->offs);
206*aae1746cSSong Gao }
207*aae1746cSSong Gao 
208*aae1746cSSong Gao #define INSN(insn, type)                                    \
209*aae1746cSSong Gao static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
210*aae1746cSSong Gao {                                                           \
211*aae1746cSSong Gao     output_##type(ctx, a, #insn);                           \
212*aae1746cSSong Gao     return true;                                            \
213*aae1746cSSong Gao }
214*aae1746cSSong Gao 
215*aae1746cSSong Gao INSN(clo_w,        rr)
216*aae1746cSSong Gao INSN(clz_w,        rr)
217*aae1746cSSong Gao INSN(cto_w,        rr)
218*aae1746cSSong Gao INSN(ctz_w,        rr)
219*aae1746cSSong Gao INSN(clo_d,        rr)
220*aae1746cSSong Gao INSN(clz_d,        rr)
221*aae1746cSSong Gao INSN(cto_d,        rr)
222*aae1746cSSong Gao INSN(ctz_d,        rr)
223*aae1746cSSong Gao INSN(revb_2h,      rr)
224*aae1746cSSong Gao INSN(revb_4h,      rr)
225*aae1746cSSong Gao INSN(revb_2w,      rr)
226*aae1746cSSong Gao INSN(revb_d,       rr)
227*aae1746cSSong Gao INSN(revh_2w,      rr)
228*aae1746cSSong Gao INSN(revh_d,       rr)
229*aae1746cSSong Gao INSN(bitrev_4b,    rr)
230*aae1746cSSong Gao INSN(bitrev_8b,    rr)
231*aae1746cSSong Gao INSN(bitrev_w,     rr)
232*aae1746cSSong Gao INSN(bitrev_d,     rr)
233*aae1746cSSong Gao INSN(ext_w_h,      rr)
234*aae1746cSSong Gao INSN(ext_w_b,      rr)
235*aae1746cSSong Gao INSN(cpucfg,       rr)
236*aae1746cSSong Gao INSN(asrtle_d,     rr_jk)
237*aae1746cSSong Gao INSN(asrtgt_d,     rr_jk)
238*aae1746cSSong Gao INSN(alsl_w,       rrr_sa)
239*aae1746cSSong Gao INSN(alsl_wu,      rrr_sa)
240*aae1746cSSong Gao INSN(bytepick_w,   rrr_sa)
241*aae1746cSSong Gao INSN(bytepick_d,   rrr_sa)
242*aae1746cSSong Gao INSN(add_w,        rrr)
243*aae1746cSSong Gao INSN(add_d,        rrr)
244*aae1746cSSong Gao INSN(sub_w,        rrr)
245*aae1746cSSong Gao INSN(sub_d,        rrr)
246*aae1746cSSong Gao INSN(slt,          rrr)
247*aae1746cSSong Gao INSN(sltu,         rrr)
248*aae1746cSSong Gao INSN(maskeqz,      rrr)
249*aae1746cSSong Gao INSN(masknez,      rrr)
250*aae1746cSSong Gao INSN(nor,          rrr)
251*aae1746cSSong Gao INSN(and,          rrr)
252*aae1746cSSong Gao INSN(or,           rrr)
253*aae1746cSSong Gao INSN(xor,          rrr)
254*aae1746cSSong Gao INSN(orn,          rrr)
255*aae1746cSSong Gao INSN(andn,         rrr)
256*aae1746cSSong Gao INSN(sll_w,        rrr)
257*aae1746cSSong Gao INSN(srl_w,        rrr)
258*aae1746cSSong Gao INSN(sra_w,        rrr)
259*aae1746cSSong Gao INSN(sll_d,        rrr)
260*aae1746cSSong Gao INSN(srl_d,        rrr)
261*aae1746cSSong Gao INSN(sra_d,        rrr)
262*aae1746cSSong Gao INSN(rotr_w,       rrr)
263*aae1746cSSong Gao INSN(rotr_d,       rrr)
264*aae1746cSSong Gao INSN(mul_w,        rrr)
265*aae1746cSSong Gao INSN(mulh_w,       rrr)
266*aae1746cSSong Gao INSN(mulh_wu,      rrr)
267*aae1746cSSong Gao INSN(mul_d,        rrr)
268*aae1746cSSong Gao INSN(mulh_d,       rrr)
269*aae1746cSSong Gao INSN(mulh_du,      rrr)
270*aae1746cSSong Gao INSN(mulw_d_w,     rrr)
271*aae1746cSSong Gao INSN(mulw_d_wu,    rrr)
272*aae1746cSSong Gao INSN(div_w,        rrr)
273*aae1746cSSong Gao INSN(mod_w,        rrr)
274*aae1746cSSong Gao INSN(div_wu,       rrr)
275*aae1746cSSong Gao INSN(mod_wu,       rrr)
276*aae1746cSSong Gao INSN(div_d,        rrr)
277*aae1746cSSong Gao INSN(mod_d,        rrr)
278*aae1746cSSong Gao INSN(div_du,       rrr)
279*aae1746cSSong Gao INSN(mod_du,       rrr)
280*aae1746cSSong Gao INSN(crc_w_b_w,    rrr)
281*aae1746cSSong Gao INSN(crc_w_h_w,    rrr)
282*aae1746cSSong Gao INSN(crc_w_w_w,    rrr)
283*aae1746cSSong Gao INSN(crc_w_d_w,    rrr)
284*aae1746cSSong Gao INSN(crcc_w_b_w,   rrr)
285*aae1746cSSong Gao INSN(crcc_w_h_w,   rrr)
286*aae1746cSSong Gao INSN(crcc_w_w_w,   rrr)
287*aae1746cSSong Gao INSN(crcc_w_d_w,   rrr)
288*aae1746cSSong Gao INSN(break,        i)
289*aae1746cSSong Gao INSN(syscall,      i)
290*aae1746cSSong Gao INSN(alsl_d,       rrr_sa)
291*aae1746cSSong Gao INSN(slli_w,       rr_i)
292*aae1746cSSong Gao INSN(slli_d,       rr_i)
293*aae1746cSSong Gao INSN(srli_w,       rr_i)
294*aae1746cSSong Gao INSN(srli_d,       rr_i)
295*aae1746cSSong Gao INSN(srai_w,       rr_i)
296*aae1746cSSong Gao INSN(srai_d,       rr_i)
297*aae1746cSSong Gao INSN(rotri_w,      rr_i)
298*aae1746cSSong Gao INSN(rotri_d,      rr_i)
299*aae1746cSSong Gao INSN(bstrins_w,    rr_ms_ls)
300*aae1746cSSong Gao INSN(bstrpick_w,   rr_ms_ls)
301*aae1746cSSong Gao INSN(bstrins_d,    rr_ms_ls)
302*aae1746cSSong Gao INSN(bstrpick_d,   rr_ms_ls)
303*aae1746cSSong Gao INSN(fadd_s,       fff)
304*aae1746cSSong Gao INSN(fadd_d,       fff)
305*aae1746cSSong Gao INSN(fsub_s,       fff)
306*aae1746cSSong Gao INSN(fsub_d,       fff)
307*aae1746cSSong Gao INSN(fmul_s,       fff)
308*aae1746cSSong Gao INSN(fmul_d,       fff)
309*aae1746cSSong Gao INSN(fdiv_s,       fff)
310*aae1746cSSong Gao INSN(fdiv_d,       fff)
311*aae1746cSSong Gao INSN(fmax_s,       fff)
312*aae1746cSSong Gao INSN(fmax_d,       fff)
313*aae1746cSSong Gao INSN(fmin_s,       fff)
314*aae1746cSSong Gao INSN(fmin_d,       fff)
315*aae1746cSSong Gao INSN(fmaxa_s,      fff)
316*aae1746cSSong Gao INSN(fmaxa_d,      fff)
317*aae1746cSSong Gao INSN(fmina_s,      fff)
318*aae1746cSSong Gao INSN(fmina_d,      fff)
319*aae1746cSSong Gao INSN(fscaleb_s,    fff)
320*aae1746cSSong Gao INSN(fscaleb_d,    fff)
321*aae1746cSSong Gao INSN(fcopysign_s,  fff)
322*aae1746cSSong Gao INSN(fcopysign_d,  fff)
323*aae1746cSSong Gao INSN(fabs_s,       ff)
324*aae1746cSSong Gao INSN(fabs_d,       ff)
325*aae1746cSSong Gao INSN(fneg_s,       ff)
326*aae1746cSSong Gao INSN(fneg_d,       ff)
327*aae1746cSSong Gao INSN(flogb_s,      ff)
328*aae1746cSSong Gao INSN(flogb_d,      ff)
329*aae1746cSSong Gao INSN(fclass_s,     ff)
330*aae1746cSSong Gao INSN(fclass_d,     ff)
331*aae1746cSSong Gao INSN(fsqrt_s,      ff)
332*aae1746cSSong Gao INSN(fsqrt_d,      ff)
333*aae1746cSSong Gao INSN(frecip_s,     ff)
334*aae1746cSSong Gao INSN(frecip_d,     ff)
335*aae1746cSSong Gao INSN(frsqrt_s,     ff)
336*aae1746cSSong Gao INSN(frsqrt_d,     ff)
337*aae1746cSSong Gao INSN(fmov_s,       ff)
338*aae1746cSSong Gao INSN(fmov_d,       ff)
339*aae1746cSSong Gao INSN(movgr2fr_w,   fr)
340*aae1746cSSong Gao INSN(movgr2fr_d,   fr)
341*aae1746cSSong Gao INSN(movgr2frh_w,  fr)
342*aae1746cSSong Gao INSN(movfr2gr_s,   rf)
343*aae1746cSSong Gao INSN(movfr2gr_d,   rf)
344*aae1746cSSong Gao INSN(movfrh2gr_s,  rf)
345*aae1746cSSong Gao INSN(movgr2fcsr,   fcsrd_r)
346*aae1746cSSong Gao INSN(movfcsr2gr,   r_fcsrs)
347*aae1746cSSong Gao INSN(movfr2cf,     cf)
348*aae1746cSSong Gao INSN(movcf2fr,     fc)
349*aae1746cSSong Gao INSN(movgr2cf,     cr)
350*aae1746cSSong Gao INSN(movcf2gr,     rc)
351*aae1746cSSong Gao INSN(fcvt_s_d,     ff)
352*aae1746cSSong Gao INSN(fcvt_d_s,     ff)
353*aae1746cSSong Gao INSN(ftintrm_w_s,  ff)
354*aae1746cSSong Gao INSN(ftintrm_w_d,  ff)
355*aae1746cSSong Gao INSN(ftintrm_l_s,  ff)
356*aae1746cSSong Gao INSN(ftintrm_l_d,  ff)
357*aae1746cSSong Gao INSN(ftintrp_w_s,  ff)
358*aae1746cSSong Gao INSN(ftintrp_w_d,  ff)
359*aae1746cSSong Gao INSN(ftintrp_l_s,  ff)
360*aae1746cSSong Gao INSN(ftintrp_l_d,  ff)
361*aae1746cSSong Gao INSN(ftintrz_w_s,  ff)
362*aae1746cSSong Gao INSN(ftintrz_w_d,  ff)
363*aae1746cSSong Gao INSN(ftintrz_l_s,  ff)
364*aae1746cSSong Gao INSN(ftintrz_l_d,  ff)
365*aae1746cSSong Gao INSN(ftintrne_w_s, ff)
366*aae1746cSSong Gao INSN(ftintrne_w_d, ff)
367*aae1746cSSong Gao INSN(ftintrne_l_s, ff)
368*aae1746cSSong Gao INSN(ftintrne_l_d, ff)
369*aae1746cSSong Gao INSN(ftint_w_s,    ff)
370*aae1746cSSong Gao INSN(ftint_w_d,    ff)
371*aae1746cSSong Gao INSN(ftint_l_s,    ff)
372*aae1746cSSong Gao INSN(ftint_l_d,    ff)
373*aae1746cSSong Gao INSN(ffint_s_w,    ff)
374*aae1746cSSong Gao INSN(ffint_s_l,    ff)
375*aae1746cSSong Gao INSN(ffint_d_w,    ff)
376*aae1746cSSong Gao INSN(ffint_d_l,    ff)
377*aae1746cSSong Gao INSN(frint_s,      ff)
378*aae1746cSSong Gao INSN(frint_d,      ff)
379*aae1746cSSong Gao INSN(slti,         rr_i)
380*aae1746cSSong Gao INSN(sltui,        rr_i)
381*aae1746cSSong Gao INSN(addi_w,       rr_i)
382*aae1746cSSong Gao INSN(addi_d,       rr_i)
383*aae1746cSSong Gao INSN(lu52i_d,      rr_i)
384*aae1746cSSong Gao INSN(andi,         rr_i)
385*aae1746cSSong Gao INSN(ori,          rr_i)
386*aae1746cSSong Gao INSN(xori,         rr_i)
387*aae1746cSSong Gao INSN(fmadd_s,      ffff)
388*aae1746cSSong Gao INSN(fmadd_d,      ffff)
389*aae1746cSSong Gao INSN(fmsub_s,      ffff)
390*aae1746cSSong Gao INSN(fmsub_d,      ffff)
391*aae1746cSSong Gao INSN(fnmadd_s,     ffff)
392*aae1746cSSong Gao INSN(fnmadd_d,     ffff)
393*aae1746cSSong Gao INSN(fnmsub_s,     ffff)
394*aae1746cSSong Gao INSN(fnmsub_d,     ffff)
395*aae1746cSSong Gao INSN(fsel,         fffc)
396*aae1746cSSong Gao INSN(addu16i_d,    rr_i)
397*aae1746cSSong Gao INSN(lu12i_w,      r_i)
398*aae1746cSSong Gao INSN(lu32i_d,      r_i)
399*aae1746cSSong Gao INSN(pcaddi,       r_i)
400*aae1746cSSong Gao INSN(pcalau12i,    r_i)
401*aae1746cSSong Gao INSN(pcaddu12i,    r_i)
402*aae1746cSSong Gao INSN(pcaddu18i,    r_i)
403*aae1746cSSong Gao INSN(ll_w,         rr_i)
404*aae1746cSSong Gao INSN(sc_w,         rr_i)
405*aae1746cSSong Gao INSN(ll_d,         rr_i)
406*aae1746cSSong Gao INSN(sc_d,         rr_i)
407*aae1746cSSong Gao INSN(ldptr_w,      rr_i)
408*aae1746cSSong Gao INSN(stptr_w,      rr_i)
409*aae1746cSSong Gao INSN(ldptr_d,      rr_i)
410*aae1746cSSong Gao INSN(stptr_d,      rr_i)
411*aae1746cSSong Gao INSN(ld_b,         rr_i)
412*aae1746cSSong Gao INSN(ld_h,         rr_i)
413*aae1746cSSong Gao INSN(ld_w,         rr_i)
414*aae1746cSSong Gao INSN(ld_d,         rr_i)
415*aae1746cSSong Gao INSN(st_b,         rr_i)
416*aae1746cSSong Gao INSN(st_h,         rr_i)
417*aae1746cSSong Gao INSN(st_w,         rr_i)
418*aae1746cSSong Gao INSN(st_d,         rr_i)
419*aae1746cSSong Gao INSN(ld_bu,        rr_i)
420*aae1746cSSong Gao INSN(ld_hu,        rr_i)
421*aae1746cSSong Gao INSN(ld_wu,        rr_i)
422*aae1746cSSong Gao INSN(preld,        hint_r_i)
423*aae1746cSSong Gao INSN(fld_s,        fr_i)
424*aae1746cSSong Gao INSN(fst_s,        fr_i)
425*aae1746cSSong Gao INSN(fld_d,        fr_i)
426*aae1746cSSong Gao INSN(fst_d,        fr_i)
427*aae1746cSSong Gao INSN(ldx_b,        rrr)
428*aae1746cSSong Gao INSN(ldx_h,        rrr)
429*aae1746cSSong Gao INSN(ldx_w,        rrr)
430*aae1746cSSong Gao INSN(ldx_d,        rrr)
431*aae1746cSSong Gao INSN(stx_b,        rrr)
432*aae1746cSSong Gao INSN(stx_h,        rrr)
433*aae1746cSSong Gao INSN(stx_w,        rrr)
434*aae1746cSSong Gao INSN(stx_d,        rrr)
435*aae1746cSSong Gao INSN(ldx_bu,       rrr)
436*aae1746cSSong Gao INSN(ldx_hu,       rrr)
437*aae1746cSSong Gao INSN(ldx_wu,       rrr)
438*aae1746cSSong Gao INSN(fldx_s,       frr)
439*aae1746cSSong Gao INSN(fldx_d,       frr)
440*aae1746cSSong Gao INSN(fstx_s,       frr)
441*aae1746cSSong Gao INSN(fstx_d,       frr)
442*aae1746cSSong Gao INSN(amswap_w,     rrr)
443*aae1746cSSong Gao INSN(amswap_d,     rrr)
444*aae1746cSSong Gao INSN(amadd_w,      rrr)
445*aae1746cSSong Gao INSN(amadd_d,      rrr)
446*aae1746cSSong Gao INSN(amand_w,      rrr)
447*aae1746cSSong Gao INSN(amand_d,      rrr)
448*aae1746cSSong Gao INSN(amor_w,       rrr)
449*aae1746cSSong Gao INSN(amor_d,       rrr)
450*aae1746cSSong Gao INSN(amxor_w,      rrr)
451*aae1746cSSong Gao INSN(amxor_d,      rrr)
452*aae1746cSSong Gao INSN(ammax_w,      rrr)
453*aae1746cSSong Gao INSN(ammax_d,      rrr)
454*aae1746cSSong Gao INSN(ammin_w,      rrr)
455*aae1746cSSong Gao INSN(ammin_d,      rrr)
456*aae1746cSSong Gao INSN(ammax_wu,     rrr)
457*aae1746cSSong Gao INSN(ammax_du,     rrr)
458*aae1746cSSong Gao INSN(ammin_wu,     rrr)
459*aae1746cSSong Gao INSN(ammin_du,     rrr)
460*aae1746cSSong Gao INSN(amswap_db_w,  rrr)
461*aae1746cSSong Gao INSN(amswap_db_d,  rrr)
462*aae1746cSSong Gao INSN(amadd_db_w,   rrr)
463*aae1746cSSong Gao INSN(amadd_db_d,   rrr)
464*aae1746cSSong Gao INSN(amand_db_w,   rrr)
465*aae1746cSSong Gao INSN(amand_db_d,   rrr)
466*aae1746cSSong Gao INSN(amor_db_w,    rrr)
467*aae1746cSSong Gao INSN(amor_db_d,    rrr)
468*aae1746cSSong Gao INSN(amxor_db_w,   rrr)
469*aae1746cSSong Gao INSN(amxor_db_d,   rrr)
470*aae1746cSSong Gao INSN(ammax_db_w,   rrr)
471*aae1746cSSong Gao INSN(ammax_db_d,   rrr)
472*aae1746cSSong Gao INSN(ammin_db_w,   rrr)
473*aae1746cSSong Gao INSN(ammin_db_d,   rrr)
474*aae1746cSSong Gao INSN(ammax_db_wu,  rrr)
475*aae1746cSSong Gao INSN(ammax_db_du,  rrr)
476*aae1746cSSong Gao INSN(ammin_db_wu,  rrr)
477*aae1746cSSong Gao INSN(ammin_db_du,  rrr)
478*aae1746cSSong Gao INSN(dbar,         i)
479*aae1746cSSong Gao INSN(ibar,         i)
480*aae1746cSSong Gao INSN(fldgt_s,      frr)
481*aae1746cSSong Gao INSN(fldgt_d,      frr)
482*aae1746cSSong Gao INSN(fldle_s,      frr)
483*aae1746cSSong Gao INSN(fldle_d,      frr)
484*aae1746cSSong Gao INSN(fstgt_s,      frr)
485*aae1746cSSong Gao INSN(fstgt_d,      frr)
486*aae1746cSSong Gao INSN(fstle_s,      frr)
487*aae1746cSSong Gao INSN(fstle_d,      frr)
488*aae1746cSSong Gao INSN(ldgt_b,       rrr)
489*aae1746cSSong Gao INSN(ldgt_h,       rrr)
490*aae1746cSSong Gao INSN(ldgt_w,       rrr)
491*aae1746cSSong Gao INSN(ldgt_d,       rrr)
492*aae1746cSSong Gao INSN(ldle_b,       rrr)
493*aae1746cSSong Gao INSN(ldle_h,       rrr)
494*aae1746cSSong Gao INSN(ldle_w,       rrr)
495*aae1746cSSong Gao INSN(ldle_d,       rrr)
496*aae1746cSSong Gao INSN(stgt_b,       rrr)
497*aae1746cSSong Gao INSN(stgt_h,       rrr)
498*aae1746cSSong Gao INSN(stgt_w,       rrr)
499*aae1746cSSong Gao INSN(stgt_d,       rrr)
500*aae1746cSSong Gao INSN(stle_b,       rrr)
501*aae1746cSSong Gao INSN(stle_h,       rrr)
502*aae1746cSSong Gao INSN(stle_w,       rrr)
503*aae1746cSSong Gao INSN(stle_d,       rrr)
504*aae1746cSSong Gao INSN(beqz,         r_offs)
505*aae1746cSSong Gao INSN(bnez,         r_offs)
506*aae1746cSSong Gao INSN(bceqz,        c_offs)
507*aae1746cSSong Gao INSN(bcnez,        c_offs)
508*aae1746cSSong Gao INSN(jirl,         rr_offs)
509*aae1746cSSong Gao INSN(b,            offs)
510*aae1746cSSong Gao INSN(bl,           offs)
511*aae1746cSSong Gao INSN(beq,          rr_offs)
512*aae1746cSSong Gao INSN(bne,          rr_offs)
513*aae1746cSSong Gao INSN(blt,          rr_offs)
514*aae1746cSSong Gao INSN(bge,          rr_offs)
515*aae1746cSSong Gao INSN(bltu,         rr_offs)
516*aae1746cSSong Gao INSN(bgeu,         rr_offs)
517*aae1746cSSong Gao 
518*aae1746cSSong Gao #define output_fcmp(C, PREFIX, SUFFIX)                                         \
519*aae1746cSSong Gao {                                                                              \
520*aae1746cSSong Gao     (C)->info->fprintf_func((C)->info->stream, "%08x   %s%s\tfcc%d, f%d, f%d", \
521*aae1746cSSong Gao                             (C)->insn, PREFIX, SUFFIX, a->cd,                  \
522*aae1746cSSong Gao                             a->fj, a->fk);                                     \
523*aae1746cSSong Gao }
524*aae1746cSSong Gao 
525*aae1746cSSong Gao static bool output_cff_fcond(DisasContext *ctx, arg_cff_fcond * a,
526*aae1746cSSong Gao                                const char *suffix)
527*aae1746cSSong Gao {
528*aae1746cSSong Gao     bool ret = true;
529*aae1746cSSong Gao     switch (a->fcond) {
530*aae1746cSSong Gao     case 0x0:
531*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_caf_", suffix);
532*aae1746cSSong Gao         break;
533*aae1746cSSong Gao     case 0x1:
534*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_saf_", suffix);
535*aae1746cSSong Gao         break;
536*aae1746cSSong Gao     case 0x2:
537*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_clt_", suffix);
538*aae1746cSSong Gao         break;
539*aae1746cSSong Gao     case 0x3:
540*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_slt_", suffix);
541*aae1746cSSong Gao         break;
542*aae1746cSSong Gao     case 0x4:
543*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_ceq_", suffix);
544*aae1746cSSong Gao         break;
545*aae1746cSSong Gao     case 0x5:
546*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_seq_", suffix);
547*aae1746cSSong Gao         break;
548*aae1746cSSong Gao     case 0x6:
549*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cle_", suffix);
550*aae1746cSSong Gao         break;
551*aae1746cSSong Gao     case 0x7:
552*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sle_", suffix);
553*aae1746cSSong Gao         break;
554*aae1746cSSong Gao     case 0x8:
555*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cun_", suffix);
556*aae1746cSSong Gao         break;
557*aae1746cSSong Gao     case 0x9:
558*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sun_", suffix);
559*aae1746cSSong Gao         break;
560*aae1746cSSong Gao     case 0xA:
561*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cult_", suffix);
562*aae1746cSSong Gao         break;
563*aae1746cSSong Gao     case 0xB:
564*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sult_", suffix);
565*aae1746cSSong Gao         break;
566*aae1746cSSong Gao     case 0xC:
567*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cueq_", suffix);
568*aae1746cSSong Gao         break;
569*aae1746cSSong Gao     case 0xD:
570*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sueq_", suffix);
571*aae1746cSSong Gao         break;
572*aae1746cSSong Gao     case 0xE:
573*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cule_", suffix);
574*aae1746cSSong Gao         break;
575*aae1746cSSong Gao     case 0xF:
576*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sule_", suffix);
577*aae1746cSSong Gao         break;
578*aae1746cSSong Gao     case 0x10:
579*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cne_", suffix);
580*aae1746cSSong Gao         break;
581*aae1746cSSong Gao     case 0x11:
582*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sne_", suffix);
583*aae1746cSSong Gao         break;
584*aae1746cSSong Gao     case 0x14:
585*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cor_", suffix);
586*aae1746cSSong Gao         break;
587*aae1746cSSong Gao     case 0x15:
588*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sor_", suffix);
589*aae1746cSSong Gao         break;
590*aae1746cSSong Gao     case 0x18:
591*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_cune_", suffix);
592*aae1746cSSong Gao         break;
593*aae1746cSSong Gao     case 0x19:
594*aae1746cSSong Gao         output_fcmp(ctx, "fcmp_sune_", suffix);
595*aae1746cSSong Gao         break;
596*aae1746cSSong Gao     default:
597*aae1746cSSong Gao         ret = false;
598*aae1746cSSong Gao     }
599*aae1746cSSong Gao     return ret;
600*aae1746cSSong Gao }
601*aae1746cSSong Gao 
602*aae1746cSSong Gao #define FCMP_INSN(suffix)                               \
603*aae1746cSSong Gao static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
604*aae1746cSSong Gao                                      arg_cff_fcond * a) \
605*aae1746cSSong Gao {                                                       \
606*aae1746cSSong Gao     return output_cff_fcond(ctx, a, #suffix);           \
607*aae1746cSSong Gao }
608*aae1746cSSong Gao 
609*aae1746cSSong Gao FCMP_INSN(s)
610*aae1746cSSong Gao FCMP_INSN(d)
611