/* * OpenRISC disassembler * * Copyright (c) 2018 Richard Henderson <rth@twiddle.net> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" #include "disas/dis-asm.h" #include "qemu/bitops.h" #include "cpu.h" typedef disassemble_info DisasContext; /* Include the auto-generated decoder. */ #include "decode-insns.c.inc" #define output(mnemonic, format, ...) \ (info->fprintf_func(info->stream, "%-9s " format, \ mnemonic, ##__VA_ARGS__)) int print_insn_or1k(bfd_vma addr, disassemble_info *info) { bfd_byte buffer[4]; uint32_t insn; int status; status = info->read_memory_func(addr, buffer, 4, info); if (status != 0) { info->memory_error_func(status, addr, info); return -1; } insn = bfd_getb32(buffer); if (!decode(info, insn)) { output(".long", "%#08x", insn); } return 4; } #define INSN(opcode, format, ...) \ static bool trans_l_##opcode(disassemble_info *info, arg_l_##opcode *a) \ { \ output("l." #opcode, format, ##__VA_ARGS__); \ return true; \ } INSN(add, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(addc, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(sub, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(and, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(or, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(xor, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(sll, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(srl, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(sra, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(ror, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(exths, "r%d, r%d", a->d, a->a) INSN(extbs, "r%d, r%d", a->d, a->a) INSN(exthz, "r%d, r%d", a->d, a->a) INSN(extbz, "r%d, r%d", a->d, a->a) INSN(cmov, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(ff1, "r%d, r%d", a->d, a->a) INSN(fl1, "r%d, r%d", a->d, a->a) INSN(mul, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(mulu, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(div, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(divu, "r%d, r%d, r%d", a->d, a->a, a->b) INSN(muld, "r%d, r%d", a->a, a->b) INSN(muldu, "r%d, r%d", a->a, a->b) INSN(j, "%d", a->n) INSN(jal, "%d", a->n) INSN(bf, "%d", a->n) INSN(bnf, "%d", a->n) INSN(jr, "r%d", a->b) INSN(jalr, "r%d", a->b) INSN(lwa, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lwz, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lws, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lbz, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lbs, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lhz, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(lhs, "r%d, %d(r%d)", a->d, a->i, a->a) INSN(swa, "%d(r%d), r%d", a->i, a->a, a->b) INSN(sw, "%d(r%d), r%d", a->i, a->a, a->b) INSN(sb, "%d(r%d), r%d", a->i, a->a, a->b) INSN(sh, "%d(r%d), r%d", a->i, a->a, a->b) INSN(nop, "") INSN(adrp, "r%d, %d", a->d, a->i) INSN(addi, "r%d, r%d, %d", a->d, a->a, a->i) INSN(addic, "r%d, r%d, %d", a->d, a->a, a->i) INSN(muli, "r%d, r%d, %d", a->d, a->a, a->i) INSN(maci, "r%d, %d", a->a, a->i) INSN(andi, "r%d, r%d, %d", a->d, a->a, a->k) INSN(ori, "r%d, r%d, %d", a->d, a->a, a->k) INSN(xori, "r%d, r%d, %d", a->d, a->a, a->i) INSN(mfspr, "r%d, r%d, %d", a->d, a->a, a->k) INSN(mtspr, "r%d, r%d, %d", a->a, a->b, a->k) INSN(mac, "r%d, r%d", a->a, a->b) INSN(msb, "r%d, r%d", a->a, a->b) INSN(macu, "r%d, r%d", a->a, a->b) INSN(msbu, "r%d, r%d", a->a, a->b) INSN(slli, "r%d, r%d, %d", a->d, a->a, a->l) INSN(srli, "r%d, r%d, %d", a->d, a->a, a->l) INSN(srai, "r%d, r%d, %d", a->d, a->a, a->l) INSN(rori, "r%d, r%d, %d", a->d, a->a, a->l) INSN(movhi, "r%d, %d", a->d, a->k) INSN(macrc, "r%d", a->d) INSN(sfeq, "r%d, r%d", a->a, a->b) INSN(sfne, "r%d, r%d", a->a, a->b) INSN(sfgtu, "r%d, r%d", a->a, a->b) INSN(sfgeu, "r%d, r%d", a->a, a->b) INSN(sfltu, "r%d, r%d", a->a, a->b) INSN(sfleu, "r%d, r%d", a->a, a->b) INSN(sfgts, "r%d, r%d", a->a, a->b) INSN(sfges, "r%d, r%d", a->a, a->b) INSN(sflts, "r%d, r%d", a->a, a->b) INSN(sfles, "r%d, r%d", a->a, a->b) INSN(sfeqi, "r%d, %d", a->a, a->i) INSN(sfnei, "r%d, %d", a->a, a->i) INSN(sfgtui, "r%d, %d", a->a, a->i) INSN(sfgeui, "r%d, %d", a->a, a->i) INSN(sfltui, "r%d, %d", a->a, a->i) INSN(sfleui, "r%d, %d", a->a, a->i) INSN(sfgtsi, "r%d, %d", a->a, a->i) INSN(sfgesi, "r%d, %d", a->a, a->i) INSN(sfltsi, "r%d, %d", a->a, a->i) INSN(sflesi, "r%d, %d", a->a, a->i) INSN(sys, "%d", a->k) INSN(trap, "%d", a->k) INSN(msync, "") INSN(psync, "") INSN(csync, "") INSN(rfe, "") #define FP_INSN(opcode, suffix, format, ...) \ static bool trans_lf_##opcode##_##suffix(disassemble_info *info, \ arg_lf_##opcode##_##suffix *a) \ { \ output("lf." #opcode "." #suffix, format, ##__VA_ARGS__); \ return true; \ } FP_INSN(add, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(sub, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(mul, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(div, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(rem, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(itof, s, "r%d, r%d", a->d, a->a) FP_INSN(ftoi, s, "r%d, r%d", a->d, a->a) FP_INSN(madd, s, "r%d, r%d, r%d", a->d, a->a, a->b) FP_INSN(sfeq, s, "r%d, r%d", a->a, a->b) FP_INSN(sfne, s, "r%d, r%d", a->a, a->b) FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b) FP_INSN(sfge, s, "r%d, r%d", a->a, a->b) FP_INSN(sflt, s, "r%d, r%d", a->a, a->b) FP_INSN(sfle, s, "r%d, r%d", a->a, a->b) FP_INSN(sfun, s, "r%d, r%d", a->a, a->b) FP_INSN(sfueq, s, "r%d, r%d", a->a, a->b) FP_INSN(sfuge, s, "r%d, r%d", a->a, a->b) FP_INSN(sfugt, s, "r%d, r%d", a->a, a->b) FP_INSN(sfule, s, "r%d, r%d", a->a, a->b) FP_INSN(sfult, s, "r%d, r%d", a->a, a->b) FP_INSN(add, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sub, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(mul, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(div, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(rem, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(madd, d, "r%d,r%d, r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(itof, d, "r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1) FP_INSN(ftoi, d, "r%d,r%d, r%d,r%d", a->d, a->d + a->dp + 1, a->a, a->a + a->ap + 1) FP_INSN(stod, d, "r%d,r%d, r%d", a->d, a->d + a->dp + 1, a->a) FP_INSN(dtos, d, "r%d r%d,r%d", a->d, a->a, a->a + a->ap + 1) FP_INSN(sfeq, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfne, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfgt, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfge, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sflt, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfle, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfun, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfueq, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfuge, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfugt, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfule, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1) FP_INSN(sfult, d, "r%d,r%d, r%d,r%d", a->a, a->a + a->ap + 1, a->b, a->b + a->bp + 1)