]> git.proxmox.com Git - mirror_qemu.git/blame - target/loongarch/disas.c
target/loongarch: Implement vmul/vmuh/vmulw{ev/od}
[mirror_qemu.git] / target / loongarch / disas.c
CommitLineData
aae1746c
SG
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * QEMU LoongArch Disassembler
4 *
5 * Copyright (c) 2021 Loongson Technology Corporation Limited.
6 */
7
8#include "qemu/osdep.h"
9#include "disas/dis-asm.h"
10#include "qemu/bitops.h"
5b1dedfe 11#include "cpu-csr.h"
aae1746c
SG
12
13typedef struct {
14 disassemble_info *info;
15 uint64_t pc;
16 uint32_t insn;
17} DisasContext;
18
19static inline int plus_1(DisasContext *ctx, int x)
20{
21 return x + 1;
22}
23
24static inline int shl_2(DisasContext *ctx, int x)
25{
26 return x << 2;
27}
28
5b1dedfe
XY
29#define CSR_NAME(REG) \
30 [LOONGARCH_CSR_##REG] = (#REG)
31
32static const char * const csr_names[] = {
33 CSR_NAME(CRMD),
34 CSR_NAME(PRMD),
35 CSR_NAME(EUEN),
36 CSR_NAME(MISC),
37 CSR_NAME(ECFG),
38 CSR_NAME(ESTAT),
39 CSR_NAME(ERA),
40 CSR_NAME(BADV),
41 CSR_NAME(BADI),
42 CSR_NAME(EENTRY),
43 CSR_NAME(TLBIDX),
44 CSR_NAME(TLBEHI),
45 CSR_NAME(TLBELO0),
46 CSR_NAME(TLBELO1),
47 CSR_NAME(ASID),
48 CSR_NAME(PGDL),
49 CSR_NAME(PGDH),
50 CSR_NAME(PGD),
51 CSR_NAME(PWCL),
52 CSR_NAME(PWCH),
53 CSR_NAME(STLBPS),
54 CSR_NAME(RVACFG),
55 CSR_NAME(CPUID),
56 CSR_NAME(PRCFG1),
57 CSR_NAME(PRCFG2),
58 CSR_NAME(PRCFG3),
59 CSR_NAME(SAVE(0)),
60 CSR_NAME(SAVE(1)),
61 CSR_NAME(SAVE(2)),
62 CSR_NAME(SAVE(3)),
63 CSR_NAME(SAVE(4)),
64 CSR_NAME(SAVE(5)),
65 CSR_NAME(SAVE(6)),
66 CSR_NAME(SAVE(7)),
67 CSR_NAME(SAVE(8)),
68 CSR_NAME(SAVE(9)),
69 CSR_NAME(SAVE(10)),
70 CSR_NAME(SAVE(11)),
71 CSR_NAME(SAVE(12)),
72 CSR_NAME(SAVE(13)),
73 CSR_NAME(SAVE(14)),
74 CSR_NAME(SAVE(15)),
75 CSR_NAME(TID),
76 CSR_NAME(TCFG),
77 CSR_NAME(TVAL),
78 CSR_NAME(CNTC),
79 CSR_NAME(TICLR),
80 CSR_NAME(LLBCTL),
81 CSR_NAME(IMPCTL1),
82 CSR_NAME(IMPCTL2),
83 CSR_NAME(TLBRENTRY),
84 CSR_NAME(TLBRBADV),
85 CSR_NAME(TLBRERA),
86 CSR_NAME(TLBRSAVE),
87 CSR_NAME(TLBRELO0),
88 CSR_NAME(TLBRELO1),
89 CSR_NAME(TLBREHI),
90 CSR_NAME(TLBRPRMD),
91 CSR_NAME(MERRCTL),
92 CSR_NAME(MERRINFO1),
93 CSR_NAME(MERRINFO2),
94 CSR_NAME(MERRENTRY),
95 CSR_NAME(MERRERA),
96 CSR_NAME(MERRSAVE),
97 CSR_NAME(CTAG),
98 CSR_NAME(DMW(0)),
99 CSR_NAME(DMW(1)),
100 CSR_NAME(DMW(2)),
101 CSR_NAME(DMW(3)),
102 CSR_NAME(DBG),
103 CSR_NAME(DERA),
104 CSR_NAME(DSAVE),
105};
106
107static const char *get_csr_name(unsigned num)
108{
109 return ((num < ARRAY_SIZE(csr_names)) && (csr_names[num] != NULL)) ?
110 csr_names[num] : "Undefined CSR";
111}
112
aae1746c
SG
113#define output(C, INSN, FMT, ...) \
114{ \
115 (C)->info->fprintf_func((C)->info->stream, "%08x %-9s\t" FMT, \
116 (C)->insn, INSN, ##__VA_ARGS__); \
117}
118
119#include "decode-insns.c.inc"
120
121int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
122{
123 bfd_byte buffer[4];
124 uint32_t insn;
125 int status;
126
127 status = (*info->read_memory_func)(memaddr, buffer, 4, info);
128 if (status != 0) {
129 (*info->memory_error_func)(status, memaddr, info);
130 return -1;
131 }
132 insn = bfd_getl32(buffer);
133 DisasContext ctx = {
134 .info = info,
135 .pc = memaddr,
136 .insn = insn
137 };
138
139 if (!decode(&ctx, insn)) {
140 output(&ctx, "illegal", "");
141 }
142 return 4;
143}
144
145static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
146{
147 output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
148}
149
150static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
151{
152 output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
153}
154
155static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
156{
157 output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
158}
159
160static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
161 const char *mnemonic)
162{
163 output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
164}
165
166static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
167{
168 output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
169}
170
171static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
172 const char *mnemonic)
173{
174 output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls);
175}
176
177static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
178 const char *mnemonic)
179{
180 output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
181}
182
183static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
184{
185 output(ctx, mnemonic, "%d", a->imm);
186}
187
188static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
189 const char *mnemonic)
190{
191 output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
192}
193
194static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
195{
196 output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
197}
198
199static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
200{
201 output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
202}
203
204static void output_ffff(DisasContext *ctx, arg_ffff *a, const char *mnemonic)
205{
206 output(ctx, mnemonic, "f%d, f%d, f%d, f%d", a->fd, a->fj, a->fk, a->fa);
207}
208
209static void output_fffc(DisasContext *ctx, arg_fffc *a, const char *mnemonic)
210{
211 output(ctx, mnemonic, "f%d, f%d, f%d, %d", a->fd, a->fj, a->fk, a->ca);
212}
213
214static void output_fr(DisasContext *ctx, arg_fr *a, const char *mnemonic)
215{
216 output(ctx, mnemonic, "f%d, r%d", a->fd, a->rj);
217}
218
219static void output_rf(DisasContext *ctx, arg_rf *a, const char *mnemonic)
220{
221 output(ctx, mnemonic, "r%d, f%d", a->rd, a->fj);
222}
223
224static void output_fcsrd_r(DisasContext *ctx, arg_fcsrd_r *a,
225 const char *mnemonic)
226{
227 output(ctx, mnemonic, "fcsr%d, r%d", a->fcsrd, a->rj);
228}
229
230static void output_r_fcsrs(DisasContext *ctx, arg_r_fcsrs *a,
231 const char *mnemonic)
232{
233 output(ctx, mnemonic, "r%d, fcsr%d", a->rd, a->fcsrs);
234}
235
236static void output_cf(DisasContext *ctx, arg_cf *a, const char *mnemonic)
237{
238 output(ctx, mnemonic, "fcc%d, f%d", a->cd, a->fj);
239}
240
241static void output_fc(DisasContext *ctx, arg_fc *a, const char *mnemonic)
242{
243 output(ctx, mnemonic, "f%d, fcc%d", a->fd, a->cj);
244}
245
246static void output_cr(DisasContext *ctx, arg_cr *a, const char *mnemonic)
247{
248 output(ctx, mnemonic, "fcc%d, r%d", a->cd, a->rj);
249}
250
251static void output_rc(DisasContext *ctx, arg_rc *a, const char *mnemonic)
252{
253 output(ctx, mnemonic, "r%d, fcc%d", a->rd, a->cj);
254}
255
256static void output_frr(DisasContext *ctx, arg_frr *a, const char *mnemonic)
257{
258 output(ctx, mnemonic, "f%d, r%d, r%d", a->fd, a->rj, a->rk);
259}
260
261static void output_fr_i(DisasContext *ctx, arg_fr_i *a, const char *mnemonic)
262{
263 output(ctx, mnemonic, "f%d, r%d, %d", a->fd, a->rj, a->imm);
264}
265
266static void output_r_offs(DisasContext *ctx, arg_r_offs *a,
267 const char *mnemonic)
268{
269 output(ctx, mnemonic, "r%d, %d # 0x%" PRIx64, a->rj, a->offs,
270 ctx->pc + a->offs);
271}
272
273static void output_c_offs(DisasContext *ctx, arg_c_offs *a,
274 const char *mnemonic)
275{
276 output(ctx, mnemonic, "fcc%d, %d # 0x%" PRIx64, a->cj, a->offs,
277 ctx->pc + a->offs);
278}
279
280static void output_offs(DisasContext *ctx, arg_offs *a,
281 const char *mnemonic)
282{
283 output(ctx, mnemonic, "%d # 0x%" PRIx64, a->offs, ctx->pc + a->offs);
284}
285
286static void output_rr_offs(DisasContext *ctx, arg_rr_offs *a,
287 const char *mnemonic)
288{
289 output(ctx, mnemonic, "r%d, r%d, %d # 0x%" PRIx64, a->rj,
290 a->rd, a->offs, ctx->pc + a->offs);
291}
292
5b1dedfe
XY
293static void output_r_csr(DisasContext *ctx, arg_r_csr *a,
294 const char *mnemonic)
295{
296 output(ctx, mnemonic, "r%d, %d # %s", a->rd, a->csr, get_csr_name(a->csr));
297}
298
299static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
300 const char *mnemonic)
301{
302 output(ctx, mnemonic, "r%d, r%d, %d # %s",
303 a->rd, a->rj, a->csr, get_csr_name(a->csr));
304}
305
fcbbeb8e
XY
306static void output_empty(DisasContext *ctx, arg_empty *a,
307 const char *mnemonic)
308{
309 output(ctx, mnemonic, "");
310}
311
312static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic)
313{
314 output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
315}
316
d2cba6f7
XY
317static void output_cop_r_i(DisasContext *ctx, arg_cop_r_i *a,
318 const char *mnemonic)
319{
320 output(ctx, mnemonic, "%d, r%d, %d", a->cop, a->rj, a->imm);
321}
322
323static void output_j_i(DisasContext *ctx, arg_j_i *a, const char *mnemonic)
324{
325 output(ctx, mnemonic, "r%d, %d", a->rj, a->imm);
326}
327
aae1746c
SG
328#define INSN(insn, type) \
329static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
330{ \
331 output_##type(ctx, a, #insn); \
332 return true; \
333}
334
335INSN(clo_w, rr)
336INSN(clz_w, rr)
337INSN(cto_w, rr)
338INSN(ctz_w, rr)
339INSN(clo_d, rr)
340INSN(clz_d, rr)
341INSN(cto_d, rr)
342INSN(ctz_d, rr)
343INSN(revb_2h, rr)
344INSN(revb_4h, rr)
345INSN(revb_2w, rr)
346INSN(revb_d, rr)
347INSN(revh_2w, rr)
348INSN(revh_d, rr)
349INSN(bitrev_4b, rr)
350INSN(bitrev_8b, rr)
351INSN(bitrev_w, rr)
352INSN(bitrev_d, rr)
353INSN(ext_w_h, rr)
354INSN(ext_w_b, rr)
f9bf5074
XY
355INSN(rdtimel_w, rr)
356INSN(rdtimeh_w, rr)
357INSN(rdtime_d, rr)
aae1746c
SG
358INSN(cpucfg, rr)
359INSN(asrtle_d, rr_jk)
360INSN(asrtgt_d, rr_jk)
361INSN(alsl_w, rrr_sa)
362INSN(alsl_wu, rrr_sa)
363INSN(bytepick_w, rrr_sa)
364INSN(bytepick_d, rrr_sa)
365INSN(add_w, rrr)
366INSN(add_d, rrr)
367INSN(sub_w, rrr)
368INSN(sub_d, rrr)
369INSN(slt, rrr)
370INSN(sltu, rrr)
371INSN(maskeqz, rrr)
372INSN(masknez, rrr)
373INSN(nor, rrr)
374INSN(and, rrr)
375INSN(or, rrr)
376INSN(xor, rrr)
377INSN(orn, rrr)
378INSN(andn, rrr)
379INSN(sll_w, rrr)
380INSN(srl_w, rrr)
381INSN(sra_w, rrr)
382INSN(sll_d, rrr)
383INSN(srl_d, rrr)
384INSN(sra_d, rrr)
385INSN(rotr_w, rrr)
386INSN(rotr_d, rrr)
387INSN(mul_w, rrr)
388INSN(mulh_w, rrr)
389INSN(mulh_wu, rrr)
390INSN(mul_d, rrr)
391INSN(mulh_d, rrr)
392INSN(mulh_du, rrr)
393INSN(mulw_d_w, rrr)
394INSN(mulw_d_wu, rrr)
395INSN(div_w, rrr)
396INSN(mod_w, rrr)
397INSN(div_wu, rrr)
398INSN(mod_wu, rrr)
399INSN(div_d, rrr)
400INSN(mod_d, rrr)
401INSN(div_du, rrr)
402INSN(mod_du, rrr)
403INSN(crc_w_b_w, rrr)
404INSN(crc_w_h_w, rrr)
405INSN(crc_w_w_w, rrr)
406INSN(crc_w_d_w, rrr)
407INSN(crcc_w_b_w, rrr)
408INSN(crcc_w_h_w, rrr)
409INSN(crcc_w_w_w, rrr)
410INSN(crcc_w_d_w, rrr)
411INSN(break, i)
412INSN(syscall, i)
413INSN(alsl_d, rrr_sa)
414INSN(slli_w, rr_i)
415INSN(slli_d, rr_i)
416INSN(srli_w, rr_i)
417INSN(srli_d, rr_i)
418INSN(srai_w, rr_i)
419INSN(srai_d, rr_i)
420INSN(rotri_w, rr_i)
421INSN(rotri_d, rr_i)
422INSN(bstrins_w, rr_ms_ls)
423INSN(bstrpick_w, rr_ms_ls)
424INSN(bstrins_d, rr_ms_ls)
425INSN(bstrpick_d, rr_ms_ls)
426INSN(fadd_s, fff)
427INSN(fadd_d, fff)
428INSN(fsub_s, fff)
429INSN(fsub_d, fff)
430INSN(fmul_s, fff)
431INSN(fmul_d, fff)
432INSN(fdiv_s, fff)
433INSN(fdiv_d, fff)
434INSN(fmax_s, fff)
435INSN(fmax_d, fff)
436INSN(fmin_s, fff)
437INSN(fmin_d, fff)
438INSN(fmaxa_s, fff)
439INSN(fmaxa_d, fff)
440INSN(fmina_s, fff)
441INSN(fmina_d, fff)
442INSN(fscaleb_s, fff)
443INSN(fscaleb_d, fff)
444INSN(fcopysign_s, fff)
445INSN(fcopysign_d, fff)
446INSN(fabs_s, ff)
447INSN(fabs_d, ff)
448INSN(fneg_s, ff)
449INSN(fneg_d, ff)
450INSN(flogb_s, ff)
451INSN(flogb_d, ff)
452INSN(fclass_s, ff)
453INSN(fclass_d, ff)
454INSN(fsqrt_s, ff)
455INSN(fsqrt_d, ff)
456INSN(frecip_s, ff)
457INSN(frecip_d, ff)
458INSN(frsqrt_s, ff)
459INSN(frsqrt_d, ff)
460INSN(fmov_s, ff)
461INSN(fmov_d, ff)
462INSN(movgr2fr_w, fr)
463INSN(movgr2fr_d, fr)
464INSN(movgr2frh_w, fr)
465INSN(movfr2gr_s, rf)
466INSN(movfr2gr_d, rf)
467INSN(movfrh2gr_s, rf)
468INSN(movgr2fcsr, fcsrd_r)
469INSN(movfcsr2gr, r_fcsrs)
470INSN(movfr2cf, cf)
471INSN(movcf2fr, fc)
472INSN(movgr2cf, cr)
473INSN(movcf2gr, rc)
474INSN(fcvt_s_d, ff)
475INSN(fcvt_d_s, ff)
476INSN(ftintrm_w_s, ff)
477INSN(ftintrm_w_d, ff)
478INSN(ftintrm_l_s, ff)
479INSN(ftintrm_l_d, ff)
480INSN(ftintrp_w_s, ff)
481INSN(ftintrp_w_d, ff)
482INSN(ftintrp_l_s, ff)
483INSN(ftintrp_l_d, ff)
484INSN(ftintrz_w_s, ff)
485INSN(ftintrz_w_d, ff)
486INSN(ftintrz_l_s, ff)
487INSN(ftintrz_l_d, ff)
488INSN(ftintrne_w_s, ff)
489INSN(ftintrne_w_d, ff)
490INSN(ftintrne_l_s, ff)
491INSN(ftintrne_l_d, ff)
492INSN(ftint_w_s, ff)
493INSN(ftint_w_d, ff)
494INSN(ftint_l_s, ff)
495INSN(ftint_l_d, ff)
496INSN(ffint_s_w, ff)
497INSN(ffint_s_l, ff)
498INSN(ffint_d_w, ff)
499INSN(ffint_d_l, ff)
500INSN(frint_s, ff)
501INSN(frint_d, ff)
502INSN(slti, rr_i)
503INSN(sltui, rr_i)
504INSN(addi_w, rr_i)
505INSN(addi_d, rr_i)
506INSN(lu52i_d, rr_i)
507INSN(andi, rr_i)
508INSN(ori, rr_i)
509INSN(xori, rr_i)
510INSN(fmadd_s, ffff)
511INSN(fmadd_d, ffff)
512INSN(fmsub_s, ffff)
513INSN(fmsub_d, ffff)
514INSN(fnmadd_s, ffff)
515INSN(fnmadd_d, ffff)
516INSN(fnmsub_s, ffff)
517INSN(fnmsub_d, ffff)
518INSN(fsel, fffc)
519INSN(addu16i_d, rr_i)
520INSN(lu12i_w, r_i)
521INSN(lu32i_d, r_i)
aae1746c
SG
522INSN(ll_w, rr_i)
523INSN(sc_w, rr_i)
524INSN(ll_d, rr_i)
525INSN(sc_d, rr_i)
526INSN(ldptr_w, rr_i)
527INSN(stptr_w, rr_i)
528INSN(ldptr_d, rr_i)
529INSN(stptr_d, rr_i)
530INSN(ld_b, rr_i)
531INSN(ld_h, rr_i)
532INSN(ld_w, rr_i)
533INSN(ld_d, rr_i)
534INSN(st_b, rr_i)
535INSN(st_h, rr_i)
536INSN(st_w, rr_i)
537INSN(st_d, rr_i)
538INSN(ld_bu, rr_i)
539INSN(ld_hu, rr_i)
540INSN(ld_wu, rr_i)
541INSN(preld, hint_r_i)
542INSN(fld_s, fr_i)
543INSN(fst_s, fr_i)
544INSN(fld_d, fr_i)
545INSN(fst_d, fr_i)
546INSN(ldx_b, rrr)
547INSN(ldx_h, rrr)
548INSN(ldx_w, rrr)
549INSN(ldx_d, rrr)
550INSN(stx_b, rrr)
551INSN(stx_h, rrr)
552INSN(stx_w, rrr)
553INSN(stx_d, rrr)
554INSN(ldx_bu, rrr)
555INSN(ldx_hu, rrr)
556INSN(ldx_wu, rrr)
557INSN(fldx_s, frr)
558INSN(fldx_d, frr)
559INSN(fstx_s, frr)
560INSN(fstx_d, frr)
561INSN(amswap_w, rrr)
562INSN(amswap_d, rrr)
563INSN(amadd_w, rrr)
564INSN(amadd_d, rrr)
565INSN(amand_w, rrr)
566INSN(amand_d, rrr)
567INSN(amor_w, rrr)
568INSN(amor_d, rrr)
569INSN(amxor_w, rrr)
570INSN(amxor_d, rrr)
571INSN(ammax_w, rrr)
572INSN(ammax_d, rrr)
573INSN(ammin_w, rrr)
574INSN(ammin_d, rrr)
575INSN(ammax_wu, rrr)
576INSN(ammax_du, rrr)
577INSN(ammin_wu, rrr)
578INSN(ammin_du, rrr)
579INSN(amswap_db_w, rrr)
580INSN(amswap_db_d, rrr)
581INSN(amadd_db_w, rrr)
582INSN(amadd_db_d, rrr)
583INSN(amand_db_w, rrr)
584INSN(amand_db_d, rrr)
585INSN(amor_db_w, rrr)
586INSN(amor_db_d, rrr)
587INSN(amxor_db_w, rrr)
588INSN(amxor_db_d, rrr)
589INSN(ammax_db_w, rrr)
590INSN(ammax_db_d, rrr)
591INSN(ammin_db_w, rrr)
592INSN(ammin_db_d, rrr)
593INSN(ammax_db_wu, rrr)
594INSN(ammax_db_du, rrr)
595INSN(ammin_db_wu, rrr)
596INSN(ammin_db_du, rrr)
597INSN(dbar, i)
598INSN(ibar, i)
599INSN(fldgt_s, frr)
600INSN(fldgt_d, frr)
601INSN(fldle_s, frr)
602INSN(fldle_d, frr)
603INSN(fstgt_s, frr)
604INSN(fstgt_d, frr)
605INSN(fstle_s, frr)
606INSN(fstle_d, frr)
607INSN(ldgt_b, rrr)
608INSN(ldgt_h, rrr)
609INSN(ldgt_w, rrr)
610INSN(ldgt_d, rrr)
611INSN(ldle_b, rrr)
612INSN(ldle_h, rrr)
613INSN(ldle_w, rrr)
614INSN(ldle_d, rrr)
615INSN(stgt_b, rrr)
616INSN(stgt_h, rrr)
617INSN(stgt_w, rrr)
618INSN(stgt_d, rrr)
619INSN(stle_b, rrr)
620INSN(stle_h, rrr)
621INSN(stle_w, rrr)
622INSN(stle_d, rrr)
623INSN(beqz, r_offs)
624INSN(bnez, r_offs)
625INSN(bceqz, c_offs)
626INSN(bcnez, c_offs)
c2b618a8 627INSN(jirl, rr_i)
aae1746c
SG
628INSN(b, offs)
629INSN(bl, offs)
630INSN(beq, rr_offs)
631INSN(bne, rr_offs)
632INSN(blt, rr_offs)
633INSN(bge, rr_offs)
634INSN(bltu, rr_offs)
635INSN(bgeu, rr_offs)
5b1dedfe
XY
636INSN(csrrd, r_csr)
637INSN(csrwr, r_csr)
638INSN(csrxchg, rr_csr)
f84a2aac
XY
639INSN(iocsrrd_b, rr)
640INSN(iocsrrd_h, rr)
641INSN(iocsrrd_w, rr)
642INSN(iocsrrd_d, rr)
643INSN(iocsrwr_b, rr)
644INSN(iocsrwr_h, rr)
645INSN(iocsrwr_w, rr)
646INSN(iocsrwr_d, rr)
fcbbeb8e
XY
647INSN(tlbsrch, empty)
648INSN(tlbrd, empty)
649INSN(tlbwr, empty)
650INSN(tlbfill, empty)
651INSN(tlbclr, empty)
652INSN(tlbflush, empty)
653INSN(invtlb, i_rr)
d2cba6f7
XY
654INSN(cacop, cop_r_i)
655INSN(lddir, rr_i)
656INSN(ldpte, j_i)
657INSN(ertn, empty)
658INSN(idle, i)
659INSN(dbcl, i)
aae1746c
SG
660
661#define output_fcmp(C, PREFIX, SUFFIX) \
662{ \
663 (C)->info->fprintf_func((C)->info->stream, "%08x %s%s\tfcc%d, f%d, f%d", \
664 (C)->insn, PREFIX, SUFFIX, a->cd, \
665 a->fj, a->fk); \
666}
667
668static bool output_cff_fcond(DisasContext *ctx, arg_cff_fcond * a,
669 const char *suffix)
670{
671 bool ret = true;
672 switch (a->fcond) {
673 case 0x0:
674 output_fcmp(ctx, "fcmp_caf_", suffix);
675 break;
676 case 0x1:
677 output_fcmp(ctx, "fcmp_saf_", suffix);
678 break;
679 case 0x2:
680 output_fcmp(ctx, "fcmp_clt_", suffix);
681 break;
682 case 0x3:
683 output_fcmp(ctx, "fcmp_slt_", suffix);
684 break;
685 case 0x4:
686 output_fcmp(ctx, "fcmp_ceq_", suffix);
687 break;
688 case 0x5:
689 output_fcmp(ctx, "fcmp_seq_", suffix);
690 break;
691 case 0x6:
692 output_fcmp(ctx, "fcmp_cle_", suffix);
693 break;
694 case 0x7:
695 output_fcmp(ctx, "fcmp_sle_", suffix);
696 break;
697 case 0x8:
698 output_fcmp(ctx, "fcmp_cun_", suffix);
699 break;
700 case 0x9:
701 output_fcmp(ctx, "fcmp_sun_", suffix);
702 break;
703 case 0xA:
704 output_fcmp(ctx, "fcmp_cult_", suffix);
705 break;
706 case 0xB:
707 output_fcmp(ctx, "fcmp_sult_", suffix);
708 break;
709 case 0xC:
710 output_fcmp(ctx, "fcmp_cueq_", suffix);
711 break;
712 case 0xD:
713 output_fcmp(ctx, "fcmp_sueq_", suffix);
714 break;
715 case 0xE:
716 output_fcmp(ctx, "fcmp_cule_", suffix);
717 break;
718 case 0xF:
719 output_fcmp(ctx, "fcmp_sule_", suffix);
720 break;
721 case 0x10:
722 output_fcmp(ctx, "fcmp_cne_", suffix);
723 break;
724 case 0x11:
725 output_fcmp(ctx, "fcmp_sne_", suffix);
726 break;
727 case 0x14:
728 output_fcmp(ctx, "fcmp_cor_", suffix);
729 break;
730 case 0x15:
731 output_fcmp(ctx, "fcmp_sor_", suffix);
732 break;
733 case 0x18:
734 output_fcmp(ctx, "fcmp_cune_", suffix);
735 break;
736 case 0x19:
737 output_fcmp(ctx, "fcmp_sune_", suffix);
738 break;
739 default:
740 ret = false;
741 }
742 return ret;
743}
744
745#define FCMP_INSN(suffix) \
746static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
747 arg_cff_fcond * a) \
748{ \
749 return output_cff_fcond(ctx, a, #suffix); \
750}
751
752FCMP_INSN(s)
753FCMP_INSN(d)
69c9a5cf
RH
754
755#define PCADD_INSN(name) \
756static bool trans_##name(DisasContext *ctx, arg_##name *a) \
757{ \
758 output(ctx, #name, "r%d, %d # 0x%" PRIx64, \
759 a->rd, a->imm, gen_##name(ctx->pc, a->imm)); \
760 return true; \
761}
762
763static uint64_t gen_pcaddi(uint64_t pc, int imm)
764{
765 return pc + (imm << 2);
766}
767
768static uint64_t gen_pcalau12i(uint64_t pc, int imm)
769{
770 return (pc + (imm << 12)) & ~0xfff;
771}
772
773static uint64_t gen_pcaddu12i(uint64_t pc, int imm)
774{
775 return pc + (imm << 12);
776}
777
778static uint64_t gen_pcaddu18i(uint64_t pc, int imm)
779{
780 return pc + ((uint64_t)(imm) << 18);
781}
782
783PCADD_INSN(pcaddi)
784PCADD_INSN(pcalau12i)
785PCADD_INSN(pcaddu12i)
786PCADD_INSN(pcaddu18i)
57b4f1ac
SG
787
788#define INSN_LSX(insn, type) \
789static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
790{ \
791 output_##type(ctx, a, #insn); \
792 return true; \
793}
794
795static void output_vvv(DisasContext *ctx, arg_vvv *a, const char *mnemonic)
796{
797 output(ctx, mnemonic, "v%d, v%d, v%d", a->vd, a->vj, a->vk);
798}
799
d8be64c1
SG
800static void output_vv_i(DisasContext *ctx, arg_vv_i *a, const char *mnemonic)
801{
802 output(ctx, mnemonic, "v%d, v%d, 0x%x", a->vd, a->vj, a->imm);
803}
804
be9ec557
SG
805static void output_vv(DisasContext *ctx, arg_vv *a, const char *mnemonic)
806{
807 output(ctx, mnemonic, "v%d, v%d", a->vd, a->vj);
808}
809
57b4f1ac
SG
810INSN_LSX(vadd_b, vvv)
811INSN_LSX(vadd_h, vvv)
812INSN_LSX(vadd_w, vvv)
813INSN_LSX(vadd_d, vvv)
814INSN_LSX(vadd_q, vvv)
815INSN_LSX(vsub_b, vvv)
816INSN_LSX(vsub_h, vvv)
817INSN_LSX(vsub_w, vvv)
818INSN_LSX(vsub_d, vvv)
819INSN_LSX(vsub_q, vvv)
d8be64c1
SG
820
821INSN_LSX(vaddi_bu, vv_i)
822INSN_LSX(vaddi_hu, vv_i)
823INSN_LSX(vaddi_wu, vv_i)
824INSN_LSX(vaddi_du, vv_i)
825INSN_LSX(vsubi_bu, vv_i)
826INSN_LSX(vsubi_hu, vv_i)
827INSN_LSX(vsubi_wu, vv_i)
828INSN_LSX(vsubi_du, vv_i)
be9ec557
SG
829
830INSN_LSX(vneg_b, vv)
831INSN_LSX(vneg_h, vv)
832INSN_LSX(vneg_w, vv)
833INSN_LSX(vneg_d, vv)
a94cb911
SG
834
835INSN_LSX(vsadd_b, vvv)
836INSN_LSX(vsadd_h, vvv)
837INSN_LSX(vsadd_w, vvv)
838INSN_LSX(vsadd_d, vvv)
839INSN_LSX(vsadd_bu, vvv)
840INSN_LSX(vsadd_hu, vvv)
841INSN_LSX(vsadd_wu, vvv)
842INSN_LSX(vsadd_du, vvv)
843INSN_LSX(vssub_b, vvv)
844INSN_LSX(vssub_h, vvv)
845INSN_LSX(vssub_w, vvv)
846INSN_LSX(vssub_d, vvv)
847INSN_LSX(vssub_bu, vvv)
848INSN_LSX(vssub_hu, vvv)
849INSN_LSX(vssub_wu, vvv)
850INSN_LSX(vssub_du, vvv)
c037fbc9
SG
851
852INSN_LSX(vhaddw_h_b, vvv)
853INSN_LSX(vhaddw_w_h, vvv)
854INSN_LSX(vhaddw_d_w, vvv)
855INSN_LSX(vhaddw_q_d, vvv)
856INSN_LSX(vhaddw_hu_bu, vvv)
857INSN_LSX(vhaddw_wu_hu, vvv)
858INSN_LSX(vhaddw_du_wu, vvv)
859INSN_LSX(vhaddw_qu_du, vvv)
860INSN_LSX(vhsubw_h_b, vvv)
861INSN_LSX(vhsubw_w_h, vvv)
862INSN_LSX(vhsubw_d_w, vvv)
863INSN_LSX(vhsubw_q_d, vvv)
864INSN_LSX(vhsubw_hu_bu, vvv)
865INSN_LSX(vhsubw_wu_hu, vvv)
866INSN_LSX(vhsubw_du_wu, vvv)
867INSN_LSX(vhsubw_qu_du, vvv)
2d5f950c
SG
868
869INSN_LSX(vaddwev_h_b, vvv)
870INSN_LSX(vaddwev_w_h, vvv)
871INSN_LSX(vaddwev_d_w, vvv)
872INSN_LSX(vaddwev_q_d, vvv)
873INSN_LSX(vaddwod_h_b, vvv)
874INSN_LSX(vaddwod_w_h, vvv)
875INSN_LSX(vaddwod_d_w, vvv)
876INSN_LSX(vaddwod_q_d, vvv)
877INSN_LSX(vsubwev_h_b, vvv)
878INSN_LSX(vsubwev_w_h, vvv)
879INSN_LSX(vsubwev_d_w, vvv)
880INSN_LSX(vsubwev_q_d, vvv)
881INSN_LSX(vsubwod_h_b, vvv)
882INSN_LSX(vsubwod_w_h, vvv)
883INSN_LSX(vsubwod_d_w, vvv)
884INSN_LSX(vsubwod_q_d, vvv)
885
886INSN_LSX(vaddwev_h_bu, vvv)
887INSN_LSX(vaddwev_w_hu, vvv)
888INSN_LSX(vaddwev_d_wu, vvv)
889INSN_LSX(vaddwev_q_du, vvv)
890INSN_LSX(vaddwod_h_bu, vvv)
891INSN_LSX(vaddwod_w_hu, vvv)
892INSN_LSX(vaddwod_d_wu, vvv)
893INSN_LSX(vaddwod_q_du, vvv)
894INSN_LSX(vsubwev_h_bu, vvv)
895INSN_LSX(vsubwev_w_hu, vvv)
896INSN_LSX(vsubwev_d_wu, vvv)
897INSN_LSX(vsubwev_q_du, vvv)
898INSN_LSX(vsubwod_h_bu, vvv)
899INSN_LSX(vsubwod_w_hu, vvv)
900INSN_LSX(vsubwod_d_wu, vvv)
901INSN_LSX(vsubwod_q_du, vvv)
902
903INSN_LSX(vaddwev_h_bu_b, vvv)
904INSN_LSX(vaddwev_w_hu_h, vvv)
905INSN_LSX(vaddwev_d_wu_w, vvv)
906INSN_LSX(vaddwev_q_du_d, vvv)
907INSN_LSX(vaddwod_h_bu_b, vvv)
908INSN_LSX(vaddwod_w_hu_h, vvv)
909INSN_LSX(vaddwod_d_wu_w, vvv)
910INSN_LSX(vaddwod_q_du_d, vvv)
39e9b0a7
SG
911
912INSN_LSX(vavg_b, vvv)
913INSN_LSX(vavg_h, vvv)
914INSN_LSX(vavg_w, vvv)
915INSN_LSX(vavg_d, vvv)
916INSN_LSX(vavg_bu, vvv)
917INSN_LSX(vavg_hu, vvv)
918INSN_LSX(vavg_wu, vvv)
919INSN_LSX(vavg_du, vvv)
920INSN_LSX(vavgr_b, vvv)
921INSN_LSX(vavgr_h, vvv)
922INSN_LSX(vavgr_w, vvv)
923INSN_LSX(vavgr_d, vvv)
924INSN_LSX(vavgr_bu, vvv)
925INSN_LSX(vavgr_hu, vvv)
926INSN_LSX(vavgr_wu, vvv)
927INSN_LSX(vavgr_du, vvv)
49725659
SG
928
929INSN_LSX(vabsd_b, vvv)
930INSN_LSX(vabsd_h, vvv)
931INSN_LSX(vabsd_w, vvv)
932INSN_LSX(vabsd_d, vvv)
933INSN_LSX(vabsd_bu, vvv)
934INSN_LSX(vabsd_hu, vvv)
935INSN_LSX(vabsd_wu, vvv)
936INSN_LSX(vabsd_du, vvv)
af448cb3
SG
937
938INSN_LSX(vadda_b, vvv)
939INSN_LSX(vadda_h, vvv)
940INSN_LSX(vadda_w, vvv)
941INSN_LSX(vadda_d, vvv)
9ab29520
SG
942
943INSN_LSX(vmax_b, vvv)
944INSN_LSX(vmax_h, vvv)
945INSN_LSX(vmax_w, vvv)
946INSN_LSX(vmax_d, vvv)
947INSN_LSX(vmin_b, vvv)
948INSN_LSX(vmin_h, vvv)
949INSN_LSX(vmin_w, vvv)
950INSN_LSX(vmin_d, vvv)
951INSN_LSX(vmax_bu, vvv)
952INSN_LSX(vmax_hu, vvv)
953INSN_LSX(vmax_wu, vvv)
954INSN_LSX(vmax_du, vvv)
955INSN_LSX(vmin_bu, vvv)
956INSN_LSX(vmin_hu, vvv)
957INSN_LSX(vmin_wu, vvv)
958INSN_LSX(vmin_du, vvv)
959INSN_LSX(vmaxi_b, vv_i)
960INSN_LSX(vmaxi_h, vv_i)
961INSN_LSX(vmaxi_w, vv_i)
962INSN_LSX(vmaxi_d, vv_i)
963INSN_LSX(vmini_b, vv_i)
964INSN_LSX(vmini_h, vv_i)
965INSN_LSX(vmini_w, vv_i)
966INSN_LSX(vmini_d, vv_i)
967INSN_LSX(vmaxi_bu, vv_i)
968INSN_LSX(vmaxi_hu, vv_i)
969INSN_LSX(vmaxi_wu, vv_i)
970INSN_LSX(vmaxi_du, vv_i)
971INSN_LSX(vmini_bu, vv_i)
972INSN_LSX(vmini_hu, vv_i)
973INSN_LSX(vmini_wu, vv_i)
974INSN_LSX(vmini_du, vv_i)
cd1c49ad
SG
975
976INSN_LSX(vmul_b, vvv)
977INSN_LSX(vmul_h, vvv)
978INSN_LSX(vmul_w, vvv)
979INSN_LSX(vmul_d, vvv)
980INSN_LSX(vmuh_b, vvv)
981INSN_LSX(vmuh_h, vvv)
982INSN_LSX(vmuh_w, vvv)
983INSN_LSX(vmuh_d, vvv)
984INSN_LSX(vmuh_bu, vvv)
985INSN_LSX(vmuh_hu, vvv)
986INSN_LSX(vmuh_wu, vvv)
987INSN_LSX(vmuh_du, vvv)
988
989INSN_LSX(vmulwev_h_b, vvv)
990INSN_LSX(vmulwev_w_h, vvv)
991INSN_LSX(vmulwev_d_w, vvv)
992INSN_LSX(vmulwev_q_d, vvv)
993INSN_LSX(vmulwod_h_b, vvv)
994INSN_LSX(vmulwod_w_h, vvv)
995INSN_LSX(vmulwod_d_w, vvv)
996INSN_LSX(vmulwod_q_d, vvv)
997INSN_LSX(vmulwev_h_bu, vvv)
998INSN_LSX(vmulwev_w_hu, vvv)
999INSN_LSX(vmulwev_d_wu, vvv)
1000INSN_LSX(vmulwev_q_du, vvv)
1001INSN_LSX(vmulwod_h_bu, vvv)
1002INSN_LSX(vmulwod_w_hu, vvv)
1003INSN_LSX(vmulwod_d_wu, vvv)
1004INSN_LSX(vmulwod_q_du, vvv)
1005INSN_LSX(vmulwev_h_bu_b, vvv)
1006INSN_LSX(vmulwev_w_hu_h, vvv)
1007INSN_LSX(vmulwev_d_wu_w, vvv)
1008INSN_LSX(vmulwev_q_du_d, vvv)
1009INSN_LSX(vmulwod_h_bu_b, vvv)
1010INSN_LSX(vmulwod_w_hu_h, vvv)
1011INSN_LSX(vmulwod_d_wu_w, vvv)
1012INSN_LSX(vmulwod_q_du_d, vvv)