xref: /openbmc/qemu/target/loongarch/disas.c (revision 21063bce)
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"
11 #include "cpu-csr.h"
12 
13 typedef struct {
14     disassemble_info *info;
15     uint64_t pc;
16     uint32_t insn;
17 } DisasContext;
18 
19 static inline int plus_1(DisasContext *ctx, int x)
20 {
21     return x + 1;
22 }
23 
24 static inline int shl_2(DisasContext *ctx, int x)
25 {
26     return x << 2;
27 }
28 
29 #define CSR_NAME(REG) \
30     [LOONGARCH_CSR_##REG] = (#REG)
31 
32 static 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 
107 static 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 
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 
121 int 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 
145 static 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 
150 static 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 
155 static 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 
160 static 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 
166 static 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 
171 static 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 
177 static 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 
183 static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
184 {
185     output(ctx, mnemonic, "%d", a->imm);
186 }
187 
188 static 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 
194 static 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 
199 static 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 
204 static 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 
209 static 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 
214 static 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 
219 static 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 
224 static 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 
230 static 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 
236 static 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 
241 static 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 
246 static 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 
251 static 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 
256 static 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 
261 static 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 
266 static 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 
273 static 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 
280 static 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 
286 static 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 
293 static 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 
299 static 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 
306 static void output_empty(DisasContext *ctx, arg_empty *a,
307                          const char *mnemonic)
308 {
309     output(ctx, mnemonic, "");
310 }
311 
312 static 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 
317 static 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 
323 static 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 
328 #define INSN(insn, type)                                    \
329 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
330 {                                                           \
331     output_##type(ctx, a, #insn);                           \
332     return true;                                            \
333 }
334 
335 INSN(clo_w,        rr)
336 INSN(clz_w,        rr)
337 INSN(cto_w,        rr)
338 INSN(ctz_w,        rr)
339 INSN(clo_d,        rr)
340 INSN(clz_d,        rr)
341 INSN(cto_d,        rr)
342 INSN(ctz_d,        rr)
343 INSN(revb_2h,      rr)
344 INSN(revb_4h,      rr)
345 INSN(revb_2w,      rr)
346 INSN(revb_d,       rr)
347 INSN(revh_2w,      rr)
348 INSN(revh_d,       rr)
349 INSN(bitrev_4b,    rr)
350 INSN(bitrev_8b,    rr)
351 INSN(bitrev_w,     rr)
352 INSN(bitrev_d,     rr)
353 INSN(ext_w_h,      rr)
354 INSN(ext_w_b,      rr)
355 INSN(rdtimel_w,    rr)
356 INSN(rdtimeh_w,    rr)
357 INSN(rdtime_d,     rr)
358 INSN(cpucfg,       rr)
359 INSN(asrtle_d,     rr_jk)
360 INSN(asrtgt_d,     rr_jk)
361 INSN(alsl_w,       rrr_sa)
362 INSN(alsl_wu,      rrr_sa)
363 INSN(bytepick_w,   rrr_sa)
364 INSN(bytepick_d,   rrr_sa)
365 INSN(add_w,        rrr)
366 INSN(add_d,        rrr)
367 INSN(sub_w,        rrr)
368 INSN(sub_d,        rrr)
369 INSN(slt,          rrr)
370 INSN(sltu,         rrr)
371 INSN(maskeqz,      rrr)
372 INSN(masknez,      rrr)
373 INSN(nor,          rrr)
374 INSN(and,          rrr)
375 INSN(or,           rrr)
376 INSN(xor,          rrr)
377 INSN(orn,          rrr)
378 INSN(andn,         rrr)
379 INSN(sll_w,        rrr)
380 INSN(srl_w,        rrr)
381 INSN(sra_w,        rrr)
382 INSN(sll_d,        rrr)
383 INSN(srl_d,        rrr)
384 INSN(sra_d,        rrr)
385 INSN(rotr_w,       rrr)
386 INSN(rotr_d,       rrr)
387 INSN(mul_w,        rrr)
388 INSN(mulh_w,       rrr)
389 INSN(mulh_wu,      rrr)
390 INSN(mul_d,        rrr)
391 INSN(mulh_d,       rrr)
392 INSN(mulh_du,      rrr)
393 INSN(mulw_d_w,     rrr)
394 INSN(mulw_d_wu,    rrr)
395 INSN(div_w,        rrr)
396 INSN(mod_w,        rrr)
397 INSN(div_wu,       rrr)
398 INSN(mod_wu,       rrr)
399 INSN(div_d,        rrr)
400 INSN(mod_d,        rrr)
401 INSN(div_du,       rrr)
402 INSN(mod_du,       rrr)
403 INSN(crc_w_b_w,    rrr)
404 INSN(crc_w_h_w,    rrr)
405 INSN(crc_w_w_w,    rrr)
406 INSN(crc_w_d_w,    rrr)
407 INSN(crcc_w_b_w,   rrr)
408 INSN(crcc_w_h_w,   rrr)
409 INSN(crcc_w_w_w,   rrr)
410 INSN(crcc_w_d_w,   rrr)
411 INSN(break,        i)
412 INSN(syscall,      i)
413 INSN(alsl_d,       rrr_sa)
414 INSN(slli_w,       rr_i)
415 INSN(slli_d,       rr_i)
416 INSN(srli_w,       rr_i)
417 INSN(srli_d,       rr_i)
418 INSN(srai_w,       rr_i)
419 INSN(srai_d,       rr_i)
420 INSN(rotri_w,      rr_i)
421 INSN(rotri_d,      rr_i)
422 INSN(bstrins_w,    rr_ms_ls)
423 INSN(bstrpick_w,   rr_ms_ls)
424 INSN(bstrins_d,    rr_ms_ls)
425 INSN(bstrpick_d,   rr_ms_ls)
426 INSN(fadd_s,       fff)
427 INSN(fadd_d,       fff)
428 INSN(fsub_s,       fff)
429 INSN(fsub_d,       fff)
430 INSN(fmul_s,       fff)
431 INSN(fmul_d,       fff)
432 INSN(fdiv_s,       fff)
433 INSN(fdiv_d,       fff)
434 INSN(fmax_s,       fff)
435 INSN(fmax_d,       fff)
436 INSN(fmin_s,       fff)
437 INSN(fmin_d,       fff)
438 INSN(fmaxa_s,      fff)
439 INSN(fmaxa_d,      fff)
440 INSN(fmina_s,      fff)
441 INSN(fmina_d,      fff)
442 INSN(fscaleb_s,    fff)
443 INSN(fscaleb_d,    fff)
444 INSN(fcopysign_s,  fff)
445 INSN(fcopysign_d,  fff)
446 INSN(fabs_s,       ff)
447 INSN(fabs_d,       ff)
448 INSN(fneg_s,       ff)
449 INSN(fneg_d,       ff)
450 INSN(flogb_s,      ff)
451 INSN(flogb_d,      ff)
452 INSN(fclass_s,     ff)
453 INSN(fclass_d,     ff)
454 INSN(fsqrt_s,      ff)
455 INSN(fsqrt_d,      ff)
456 INSN(frecip_s,     ff)
457 INSN(frecip_d,     ff)
458 INSN(frsqrt_s,     ff)
459 INSN(frsqrt_d,     ff)
460 INSN(fmov_s,       ff)
461 INSN(fmov_d,       ff)
462 INSN(movgr2fr_w,   fr)
463 INSN(movgr2fr_d,   fr)
464 INSN(movgr2frh_w,  fr)
465 INSN(movfr2gr_s,   rf)
466 INSN(movfr2gr_d,   rf)
467 INSN(movfrh2gr_s,  rf)
468 INSN(movgr2fcsr,   fcsrd_r)
469 INSN(movfcsr2gr,   r_fcsrs)
470 INSN(movfr2cf,     cf)
471 INSN(movcf2fr,     fc)
472 INSN(movgr2cf,     cr)
473 INSN(movcf2gr,     rc)
474 INSN(fcvt_s_d,     ff)
475 INSN(fcvt_d_s,     ff)
476 INSN(ftintrm_w_s,  ff)
477 INSN(ftintrm_w_d,  ff)
478 INSN(ftintrm_l_s,  ff)
479 INSN(ftintrm_l_d,  ff)
480 INSN(ftintrp_w_s,  ff)
481 INSN(ftintrp_w_d,  ff)
482 INSN(ftintrp_l_s,  ff)
483 INSN(ftintrp_l_d,  ff)
484 INSN(ftintrz_w_s,  ff)
485 INSN(ftintrz_w_d,  ff)
486 INSN(ftintrz_l_s,  ff)
487 INSN(ftintrz_l_d,  ff)
488 INSN(ftintrne_w_s, ff)
489 INSN(ftintrne_w_d, ff)
490 INSN(ftintrne_l_s, ff)
491 INSN(ftintrne_l_d, ff)
492 INSN(ftint_w_s,    ff)
493 INSN(ftint_w_d,    ff)
494 INSN(ftint_l_s,    ff)
495 INSN(ftint_l_d,    ff)
496 INSN(ffint_s_w,    ff)
497 INSN(ffint_s_l,    ff)
498 INSN(ffint_d_w,    ff)
499 INSN(ffint_d_l,    ff)
500 INSN(frint_s,      ff)
501 INSN(frint_d,      ff)
502 INSN(slti,         rr_i)
503 INSN(sltui,        rr_i)
504 INSN(addi_w,       rr_i)
505 INSN(addi_d,       rr_i)
506 INSN(lu52i_d,      rr_i)
507 INSN(andi,         rr_i)
508 INSN(ori,          rr_i)
509 INSN(xori,         rr_i)
510 INSN(fmadd_s,      ffff)
511 INSN(fmadd_d,      ffff)
512 INSN(fmsub_s,      ffff)
513 INSN(fmsub_d,      ffff)
514 INSN(fnmadd_s,     ffff)
515 INSN(fnmadd_d,     ffff)
516 INSN(fnmsub_s,     ffff)
517 INSN(fnmsub_d,     ffff)
518 INSN(fsel,         fffc)
519 INSN(addu16i_d,    rr_i)
520 INSN(lu12i_w,      r_i)
521 INSN(lu32i_d,      r_i)
522 INSN(ll_w,         rr_i)
523 INSN(sc_w,         rr_i)
524 INSN(ll_d,         rr_i)
525 INSN(sc_d,         rr_i)
526 INSN(ldptr_w,      rr_i)
527 INSN(stptr_w,      rr_i)
528 INSN(ldptr_d,      rr_i)
529 INSN(stptr_d,      rr_i)
530 INSN(ld_b,         rr_i)
531 INSN(ld_h,         rr_i)
532 INSN(ld_w,         rr_i)
533 INSN(ld_d,         rr_i)
534 INSN(st_b,         rr_i)
535 INSN(st_h,         rr_i)
536 INSN(st_w,         rr_i)
537 INSN(st_d,         rr_i)
538 INSN(ld_bu,        rr_i)
539 INSN(ld_hu,        rr_i)
540 INSN(ld_wu,        rr_i)
541 INSN(preld,        hint_r_i)
542 INSN(fld_s,        fr_i)
543 INSN(fst_s,        fr_i)
544 INSN(fld_d,        fr_i)
545 INSN(fst_d,        fr_i)
546 INSN(ldx_b,        rrr)
547 INSN(ldx_h,        rrr)
548 INSN(ldx_w,        rrr)
549 INSN(ldx_d,        rrr)
550 INSN(stx_b,        rrr)
551 INSN(stx_h,        rrr)
552 INSN(stx_w,        rrr)
553 INSN(stx_d,        rrr)
554 INSN(ldx_bu,       rrr)
555 INSN(ldx_hu,       rrr)
556 INSN(ldx_wu,       rrr)
557 INSN(fldx_s,       frr)
558 INSN(fldx_d,       frr)
559 INSN(fstx_s,       frr)
560 INSN(fstx_d,       frr)
561 INSN(amswap_w,     rrr)
562 INSN(amswap_d,     rrr)
563 INSN(amadd_w,      rrr)
564 INSN(amadd_d,      rrr)
565 INSN(amand_w,      rrr)
566 INSN(amand_d,      rrr)
567 INSN(amor_w,       rrr)
568 INSN(amor_d,       rrr)
569 INSN(amxor_w,      rrr)
570 INSN(amxor_d,      rrr)
571 INSN(ammax_w,      rrr)
572 INSN(ammax_d,      rrr)
573 INSN(ammin_w,      rrr)
574 INSN(ammin_d,      rrr)
575 INSN(ammax_wu,     rrr)
576 INSN(ammax_du,     rrr)
577 INSN(ammin_wu,     rrr)
578 INSN(ammin_du,     rrr)
579 INSN(amswap_db_w,  rrr)
580 INSN(amswap_db_d,  rrr)
581 INSN(amadd_db_w,   rrr)
582 INSN(amadd_db_d,   rrr)
583 INSN(amand_db_w,   rrr)
584 INSN(amand_db_d,   rrr)
585 INSN(amor_db_w,    rrr)
586 INSN(amor_db_d,    rrr)
587 INSN(amxor_db_w,   rrr)
588 INSN(amxor_db_d,   rrr)
589 INSN(ammax_db_w,   rrr)
590 INSN(ammax_db_d,   rrr)
591 INSN(ammin_db_w,   rrr)
592 INSN(ammin_db_d,   rrr)
593 INSN(ammax_db_wu,  rrr)
594 INSN(ammax_db_du,  rrr)
595 INSN(ammin_db_wu,  rrr)
596 INSN(ammin_db_du,  rrr)
597 INSN(dbar,         i)
598 INSN(ibar,         i)
599 INSN(fldgt_s,      frr)
600 INSN(fldgt_d,      frr)
601 INSN(fldle_s,      frr)
602 INSN(fldle_d,      frr)
603 INSN(fstgt_s,      frr)
604 INSN(fstgt_d,      frr)
605 INSN(fstle_s,      frr)
606 INSN(fstle_d,      frr)
607 INSN(ldgt_b,       rrr)
608 INSN(ldgt_h,       rrr)
609 INSN(ldgt_w,       rrr)
610 INSN(ldgt_d,       rrr)
611 INSN(ldle_b,       rrr)
612 INSN(ldle_h,       rrr)
613 INSN(ldle_w,       rrr)
614 INSN(ldle_d,       rrr)
615 INSN(stgt_b,       rrr)
616 INSN(stgt_h,       rrr)
617 INSN(stgt_w,       rrr)
618 INSN(stgt_d,       rrr)
619 INSN(stle_b,       rrr)
620 INSN(stle_h,       rrr)
621 INSN(stle_w,       rrr)
622 INSN(stle_d,       rrr)
623 INSN(beqz,         r_offs)
624 INSN(bnez,         r_offs)
625 INSN(bceqz,        c_offs)
626 INSN(bcnez,        c_offs)
627 INSN(jirl,         rr_i)
628 INSN(b,            offs)
629 INSN(bl,           offs)
630 INSN(beq,          rr_offs)
631 INSN(bne,          rr_offs)
632 INSN(blt,          rr_offs)
633 INSN(bge,          rr_offs)
634 INSN(bltu,         rr_offs)
635 INSN(bgeu,         rr_offs)
636 INSN(csrrd,        r_csr)
637 INSN(csrwr,        r_csr)
638 INSN(csrxchg,      rr_csr)
639 INSN(iocsrrd_b,    rr)
640 INSN(iocsrrd_h,    rr)
641 INSN(iocsrrd_w,    rr)
642 INSN(iocsrrd_d,    rr)
643 INSN(iocsrwr_b,    rr)
644 INSN(iocsrwr_h,    rr)
645 INSN(iocsrwr_w,    rr)
646 INSN(iocsrwr_d,    rr)
647 INSN(tlbsrch,      empty)
648 INSN(tlbrd,        empty)
649 INSN(tlbwr,        empty)
650 INSN(tlbfill,      empty)
651 INSN(tlbclr,       empty)
652 INSN(tlbflush,     empty)
653 INSN(invtlb,       i_rr)
654 INSN(cacop,        cop_r_i)
655 INSN(lddir,        rr_i)
656 INSN(ldpte,        j_i)
657 INSN(ertn,         empty)
658 INSN(idle,         i)
659 INSN(dbcl,         i)
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 
668 static 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)                               \
746 static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
747                                      arg_cff_fcond * a) \
748 {                                                       \
749     return output_cff_fcond(ctx, a, #suffix);           \
750 }
751 
752 FCMP_INSN(s)
753 FCMP_INSN(d)
754 
755 #define PCADD_INSN(name)                                        \
756 static 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 
763 static uint64_t gen_pcaddi(uint64_t pc, int imm)
764 {
765     return pc + (imm << 2);
766 }
767 
768 static uint64_t gen_pcalau12i(uint64_t pc, int imm)
769 {
770     return (pc + (imm << 12)) & ~0xfff;
771 }
772 
773 static uint64_t gen_pcaddu12i(uint64_t pc, int imm)
774 {
775     return pc + (imm << 12);
776 }
777 
778 static uint64_t gen_pcaddu18i(uint64_t pc, int imm)
779 {
780     return pc + ((uint64_t)(imm) << 18);
781 }
782 
783 PCADD_INSN(pcaddi)
784 PCADD_INSN(pcalau12i)
785 PCADD_INSN(pcaddu12i)
786 PCADD_INSN(pcaddu18i)
787