175fd0b74Schristos /* Opcode decoder for the Renesas RX 2*e992f068Schristos Copyright (C) 2008-2022 Free Software Foundation, Inc. 375fd0b74Schristos Written by DJ Delorie <dj@redhat.com> 475fd0b74Schristos 575fd0b74Schristos This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler. 675fd0b74Schristos 775fd0b74Schristos This program is free software; you can redistribute it and/or modify 875fd0b74Schristos it under the terms of the GNU General Public License as published by 975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or 1075fd0b74Schristos (at your option) any later version. 1175fd0b74Schristos 1275fd0b74Schristos This program is distributed in the hope that it will be useful, 1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1575fd0b74Schristos GNU General Public License for more details. 1675fd0b74Schristos 1775fd0b74Schristos You should have received a copy of the GNU General Public License 1875fd0b74Schristos along with this program; if not, write to the Free Software 1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 2075fd0b74Schristos 02110-1301, USA. */ 2175fd0b74Schristos 2275fd0b74Schristos /* The RX decoder in libopcodes is used by the simulator, gdb's 2375fd0b74Schristos analyzer, and the disassembler. Given an opcode data source, 2475fd0b74Schristos it decodes the next opcode into the following structures. */ 2575fd0b74Schristos 2675fd0b74Schristos #ifdef __cplusplus 2775fd0b74Schristos extern "C" { 2875fd0b74Schristos #endif 2975fd0b74Schristos 3075fd0b74Schristos typedef enum 3175fd0b74Schristos { 3275fd0b74Schristos RX_AnySize = 0, 3375fd0b74Schristos RX_Byte, /* undefined extension */ 3475fd0b74Schristos RX_UByte, 3575fd0b74Schristos RX_SByte, 3675fd0b74Schristos RX_Word, /* undefined extension */ 3775fd0b74Schristos RX_UWord, 3875fd0b74Schristos RX_SWord, 3975fd0b74Schristos RX_3Byte, 4075fd0b74Schristos RX_Long, 41012573ebSchristos RX_Double, 4275fd0b74Schristos RX_Bad_Size, 4375fd0b74Schristos RX_MAX_SIZE 4475fd0b74Schristos } RX_Size; 4575fd0b74Schristos 4675fd0b74Schristos typedef enum 4775fd0b74Schristos { 4875fd0b74Schristos RX_Operand_None, 4975fd0b74Schristos RX_Operand_Immediate, /* #addend */ 5075fd0b74Schristos RX_Operand_Register, /* Rn */ 5175fd0b74Schristos RX_Operand_Indirect, /* [Rn + addend] */ 5275fd0b74Schristos RX_Operand_Zero_Indirect,/* [Rn] */ 5375fd0b74Schristos RX_Operand_Postinc, /* [Rn+] */ 5475fd0b74Schristos RX_Operand_Predec, /* [-Rn] */ 5575fd0b74Schristos RX_Operand_Condition, /* eq, gtu, etc */ 5675fd0b74Schristos RX_Operand_Flag, /* [UIOSZC] */ 5775fd0b74Schristos RX_Operand_TwoReg, /* [Rn + scale*R2] */ 58012573ebSchristos RX_Operand_DoubleReg, /* DRn */ 59012573ebSchristos RX_Operand_DoubleRegH,/* DRHn */ 60012573ebSchristos RX_Operand_DoubleRegL,/* DRLn */ 61012573ebSchristos RX_Operand_DoubleCReg,/* DCRxx */ 62012573ebSchristos RX_Operand_DoubleCond,/* UN/EQ/LE/LT */ 6375fd0b74Schristos } RX_Operand_Type; 6475fd0b74Schristos 6575fd0b74Schristos typedef enum 6675fd0b74Schristos { 6775fd0b74Schristos RXO_unknown, 6875fd0b74Schristos RXO_mov, /* d = s (signed) */ 6975fd0b74Schristos RXO_movbi, /* d = [s,s2] (signed) */ 7075fd0b74Schristos RXO_movbir, /* [s,s2] = d (signed) */ 7175fd0b74Schristos RXO_pushm, /* s..s2 */ 7275fd0b74Schristos RXO_popm, /* s..s2 */ 7375fd0b74Schristos RXO_xchg, /* s <-> d */ 7475fd0b74Schristos RXO_stcc, /* d = s if cond(s2) */ 7575fd0b74Schristos RXO_rtsd, /* rtsd, 1=imm, 2-0 = reg if reg type */ 7675fd0b74Schristos 7775fd0b74Schristos /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note 7875fd0b74Schristos that d may be "None". */ 7975fd0b74Schristos RXO_and, 8075fd0b74Schristos RXO_or, 8175fd0b74Schristos RXO_xor, 8275fd0b74Schristos RXO_add, 8375fd0b74Schristos RXO_sub, 8475fd0b74Schristos RXO_mul, 8575fd0b74Schristos RXO_div, 8675fd0b74Schristos RXO_divu, 8775fd0b74Schristos RXO_shll, 8875fd0b74Schristos RXO_shar, 8975fd0b74Schristos RXO_shlr, 9075fd0b74Schristos 9175fd0b74Schristos RXO_adc, /* d = d + s + carry */ 9275fd0b74Schristos RXO_sbb, /* d = d - s - ~carry */ 9375fd0b74Schristos RXO_abs, /* d = |s| */ 9475fd0b74Schristos RXO_max, /* d = max(d,s) */ 9575fd0b74Schristos RXO_min, /* d = min(d,s) */ 9675fd0b74Schristos RXO_emul, /* d:64 = d:32 * s */ 9775fd0b74Schristos RXO_emulu, /* d:64 = d:32 * s (unsigned) */ 9875fd0b74Schristos 9975fd0b74Schristos RXO_rolc, /* d <<= 1 through carry */ 10075fd0b74Schristos RXO_rorc, /* d >>= 1 through carry*/ 10175fd0b74Schristos RXO_rotl, /* d <<= #s without carry */ 10275fd0b74Schristos RXO_rotr, /* d >>= #s without carry*/ 10375fd0b74Schristos RXO_revw, /* d = revw(s) */ 10475fd0b74Schristos RXO_revl, /* d = revl(s) */ 10575fd0b74Schristos RXO_branch, /* pc = d if cond(s) */ 10675fd0b74Schristos RXO_branchrel,/* pc += d if cond(s) */ 10775fd0b74Schristos RXO_jsr, /* pc = d */ 10875fd0b74Schristos RXO_jsrrel, /* pc += d */ 10975fd0b74Schristos RXO_rts, 11075fd0b74Schristos RXO_nop, 11175fd0b74Schristos RXO_nop2, 11275fd0b74Schristos RXO_nop3, 11375fd0b74Schristos RXO_nop4, 11475fd0b74Schristos RXO_nop5, 11575fd0b74Schristos RXO_nop6, 11675fd0b74Schristos RXO_nop7, 11775fd0b74Schristos 11875fd0b74Schristos RXO_scmpu, 11975fd0b74Schristos RXO_smovu, 12075fd0b74Schristos RXO_smovb, 12175fd0b74Schristos RXO_suntil, 12275fd0b74Schristos RXO_swhile, 12375fd0b74Schristos RXO_smovf, 12475fd0b74Schristos RXO_sstr, 12575fd0b74Schristos 12675fd0b74Schristos RXO_rmpa, 12775fd0b74Schristos RXO_mulhi, 12875fd0b74Schristos RXO_mullo, 12975fd0b74Schristos RXO_machi, 13075fd0b74Schristos RXO_maclo, 13175fd0b74Schristos RXO_mvtachi, 13275fd0b74Schristos RXO_mvtaclo, 13375fd0b74Schristos RXO_mvfachi, 13475fd0b74Schristos RXO_mvfacmi, 13575fd0b74Schristos RXO_mvfaclo, 13675fd0b74Schristos RXO_racw, 13775fd0b74Schristos 13875fd0b74Schristos RXO_sat, /* sat(d) */ 13975fd0b74Schristos RXO_satr, 14075fd0b74Schristos 14175fd0b74Schristos RXO_fadd, /* d op= s */ 14275fd0b74Schristos RXO_fcmp, 14375fd0b74Schristos RXO_fsub, 14475fd0b74Schristos RXO_ftoi, 14575fd0b74Schristos RXO_fmul, 14675fd0b74Schristos RXO_fdiv, 14775fd0b74Schristos RXO_round, 14875fd0b74Schristos RXO_itof, 14975fd0b74Schristos 15075fd0b74Schristos RXO_bset, /* d |= (1<<s) */ 15175fd0b74Schristos RXO_bclr, /* d &= ~(1<<s) */ 15275fd0b74Schristos RXO_btst, /* s & (1<<s2) */ 15375fd0b74Schristos RXO_bnot, /* d ^= (1<<s) */ 15475fd0b74Schristos RXO_bmcc, /* d<s> = cond(s2) */ 15575fd0b74Schristos 15675fd0b74Schristos RXO_clrpsw, /* flag index in d */ 15775fd0b74Schristos RXO_setpsw, /* flag index in d */ 15875fd0b74Schristos RXO_mvtipl, /* new IPL in s */ 15975fd0b74Schristos 16075fd0b74Schristos RXO_rtfi, 16175fd0b74Schristos RXO_rte, 16275fd0b74Schristos RXO_rtd, /* undocumented */ 16375fd0b74Schristos RXO_brk, 16475fd0b74Schristos RXO_dbt, /* undocumented */ 16575fd0b74Schristos RXO_int, /* vector id in s */ 16675fd0b74Schristos RXO_stop, 16775fd0b74Schristos RXO_wait, 16875fd0b74Schristos 16975fd0b74Schristos RXO_sccnd, /* d = cond(s) ? 1 : 0 */ 17075fd0b74Schristos 17175fd0b74Schristos RXO_fsqrt, 17275fd0b74Schristos RXO_ftou, 17375fd0b74Schristos RXO_utof, 17475fd0b74Schristos RXO_movco, 17575fd0b74Schristos RXO_movli, 17675fd0b74Schristos RXO_emaca, 17775fd0b74Schristos RXO_emsba, 17875fd0b74Schristos RXO_emula, 17975fd0b74Schristos RXO_maclh, 18075fd0b74Schristos RXO_msbhi, 18175fd0b74Schristos RXO_msblh, 18275fd0b74Schristos RXO_msblo, 18375fd0b74Schristos RXO_mullh, 18475fd0b74Schristos RXO_mvfacgu, 18575fd0b74Schristos RXO_mvtacgu, 18675fd0b74Schristos RXO_racl, 18775fd0b74Schristos RXO_rdacl, 18875fd0b74Schristos RXO_rdacw, 189012573ebSchristos 190012573ebSchristos RXO_bfmov, 191012573ebSchristos RXO_bfmovz, 192012573ebSchristos RXO_rstr, 193012573ebSchristos RXO_save, 194012573ebSchristos RXO_dmov, 195012573ebSchristos RXO_dpopm, 196012573ebSchristos RXO_dpushm, 197012573ebSchristos RXO_mvfdc, 198012573ebSchristos RXO_mvfdr, 199012573ebSchristos RXO_mvtdc, 200012573ebSchristos RXO_dabs, 201012573ebSchristos RXO_dadd, 202012573ebSchristos RXO_dcmp, 203012573ebSchristos RXO_ddiv, 204012573ebSchristos RXO_dmul, 205012573ebSchristos RXO_dneg, 206012573ebSchristos RXO_dround, 207012573ebSchristos RXO_dsqrt, 208012573ebSchristos RXO_dsub, 209012573ebSchristos RXO_dtoi, 210012573ebSchristos RXO_dtof, 211012573ebSchristos RXO_dtou, 212012573ebSchristos RXO_ftod, 213012573ebSchristos RXO_itod, 214012573ebSchristos RXO_utod 21575fd0b74Schristos } RX_Opcode_ID; 21675fd0b74Schristos 21775fd0b74Schristos /* Condition bitpatterns, as registers. */ 21875fd0b74Schristos #define RXC_eq 0 21975fd0b74Schristos #define RXC_z 0 22075fd0b74Schristos #define RXC_ne 1 22175fd0b74Schristos #define RXC_nz 1 22275fd0b74Schristos #define RXC_c 2 22375fd0b74Schristos #define RXC_nc 3 22475fd0b74Schristos #define RXC_gtu 4 22575fd0b74Schristos #define RXC_leu 5 22675fd0b74Schristos #define RXC_pz 6 22775fd0b74Schristos #define RXC_n 7 22875fd0b74Schristos #define RXC_ge 8 22975fd0b74Schristos #define RXC_lt 9 23075fd0b74Schristos #define RXC_gt 10 23175fd0b74Schristos #define RXC_le 11 23275fd0b74Schristos #define RXC_o 12 23375fd0b74Schristos #define RXC_no 13 23475fd0b74Schristos #define RXC_always 14 23575fd0b74Schristos #define RXC_never 15 23675fd0b74Schristos 23775fd0b74Schristos typedef struct 23875fd0b74Schristos { 23975fd0b74Schristos RX_Operand_Type type; 24075fd0b74Schristos int reg; 24175fd0b74Schristos int addend; 24275fd0b74Schristos RX_Size size; 24375fd0b74Schristos } RX_Opcode_Operand; 24475fd0b74Schristos 24575fd0b74Schristos typedef struct 24675fd0b74Schristos { 24775fd0b74Schristos RX_Opcode_ID id; 24875fd0b74Schristos int n_bytes; 24975fd0b74Schristos int prefix; 25075fd0b74Schristos char * syntax; 25175fd0b74Schristos RX_Size size; 25275fd0b74Schristos /* By convention, these are destination, source1, source2. */ 25375fd0b74Schristos RX_Opcode_Operand op[3]; 25475fd0b74Schristos 25575fd0b74Schristos /* The logic here is: 25675fd0b74Schristos newflags = (oldflags & ~(int)flags_0) | flags_1 | (op_flags & flags_s) 25775fd0b74Schristos Only the O, S, Z, and C flags are affected. */ 25875fd0b74Schristos char flags_0; /* This also clears out flags-to-be-set. */ 25975fd0b74Schristos char flags_1; 26075fd0b74Schristos char flags_s; 26175fd0b74Schristos } RX_Opcode_Decoded; 26275fd0b74Schristos 26375fd0b74Schristos /* Within the syntax, %c-style format specifiers are as follows: 26475fd0b74Schristos 26575fd0b74Schristos %% = '%' character 26675fd0b74Schristos %0 = operand[0] (destination) 26775fd0b74Schristos %1 = operand[1] (source) 26875fd0b74Schristos %2 = operand[2] (2nd source) 26975fd0b74Schristos %s = operation size (b/w/l) 27075fd0b74Schristos %SN = operand size [N] (N=0,1,2) 27175fd0b74Schristos %aN = op[N] as an address (N=0,1,2) 27275fd0b74Schristos 27375fd0b74Schristos Register numbers 0..15 are general registers. 16..31 are control 27475fd0b74Schristos registers. 32..47 are condition codes. */ 27575fd0b74Schristos 27675fd0b74Schristos int rx_decode_opcode (unsigned long, RX_Opcode_Decoded *, int (*)(void *), void *); 27775fd0b74Schristos 27875fd0b74Schristos #ifdef __cplusplus 27975fd0b74Schristos } 28075fd0b74Schristos #endif 281