1a5a4af3bSchristos /* Opcode decoder for the Renesas RX 2*8b657b07Schristos Copyright (C) 2008-2022 Free Software Foundation, Inc. 3a5a4af3bSchristos Written by DJ Delorie <dj@redhat.com> 4a5a4af3bSchristos 5a5a4af3bSchristos This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler. 6a5a4af3bSchristos 7a5a4af3bSchristos This program is free software; you can redistribute it and/or modify 8a5a4af3bSchristos it under the terms of the GNU General Public License as published by 9a5a4af3bSchristos the Free Software Foundation; either version 3 of the License, or 10a5a4af3bSchristos (at your option) any later version. 11a5a4af3bSchristos 12a5a4af3bSchristos This program is distributed in the hope that it will be useful, 13a5a4af3bSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14a5a4af3bSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a5a4af3bSchristos GNU General Public License for more details. 16a5a4af3bSchristos 17a5a4af3bSchristos You should have received a copy of the GNU General Public License 18a5a4af3bSchristos along with this program; if not, write to the Free Software 19a5a4af3bSchristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20a5a4af3bSchristos 02110-1301, USA. */ 21a5a4af3bSchristos 22a5a4af3bSchristos /* The RX decoder in libopcodes is used by the simulator, gdb's 23a5a4af3bSchristos analyzer, and the disassembler. Given an opcode data source, 24a5a4af3bSchristos it decodes the next opcode into the following structures. */ 25a5a4af3bSchristos 26a5a4af3bSchristos #ifdef __cplusplus 27a5a4af3bSchristos extern "C" { 28a5a4af3bSchristos #endif 29a5a4af3bSchristos 30a5a4af3bSchristos typedef enum 31a5a4af3bSchristos { 32a5a4af3bSchristos RX_AnySize = 0, 33a5a4af3bSchristos RX_Byte, /* undefined extension */ 34a5a4af3bSchristos RX_UByte, 35a5a4af3bSchristos RX_SByte, 36a5a4af3bSchristos RX_Word, /* undefined extension */ 37a5a4af3bSchristos RX_UWord, 38a5a4af3bSchristos RX_SWord, 39a5a4af3bSchristos RX_3Byte, 40a5a4af3bSchristos RX_Long, 4147c37bc2Schristos RX_Double, 42e5cb852cSchristos RX_Bad_Size, 43e5cb852cSchristos RX_MAX_SIZE 44a5a4af3bSchristos } RX_Size; 45a5a4af3bSchristos 46a5a4af3bSchristos typedef enum 47a5a4af3bSchristos { 48a5a4af3bSchristos RX_Operand_None, 49a5a4af3bSchristos RX_Operand_Immediate, /* #addend */ 50a5a4af3bSchristos RX_Operand_Register, /* Rn */ 51a5a4af3bSchristos RX_Operand_Indirect, /* [Rn + addend] */ 52e5cb852cSchristos RX_Operand_Zero_Indirect,/* [Rn] */ 53a5a4af3bSchristos RX_Operand_Postinc, /* [Rn+] */ 54a5a4af3bSchristos RX_Operand_Predec, /* [-Rn] */ 55a5a4af3bSchristos RX_Operand_Condition, /* eq, gtu, etc */ 56a5a4af3bSchristos RX_Operand_Flag, /* [UIOSZC] */ 57a5a4af3bSchristos RX_Operand_TwoReg, /* [Rn + scale*R2] */ 5847c37bc2Schristos RX_Operand_DoubleReg, /* DRn */ 5947c37bc2Schristos RX_Operand_DoubleRegH,/* DRHn */ 6047c37bc2Schristos RX_Operand_DoubleRegL,/* DRLn */ 6147c37bc2Schristos RX_Operand_DoubleCReg,/* DCRxx */ 6247c37bc2Schristos RX_Operand_DoubleCond,/* UN/EQ/LE/LT */ 63a5a4af3bSchristos } RX_Operand_Type; 64a5a4af3bSchristos 65a5a4af3bSchristos typedef enum 66a5a4af3bSchristos { 67a5a4af3bSchristos RXO_unknown, 68a5a4af3bSchristos RXO_mov, /* d = s (signed) */ 69a5a4af3bSchristos RXO_movbi, /* d = [s,s2] (signed) */ 70a5a4af3bSchristos RXO_movbir, /* [s,s2] = d (signed) */ 71a5a4af3bSchristos RXO_pushm, /* s..s2 */ 72a5a4af3bSchristos RXO_popm, /* s..s2 */ 73a5a4af3bSchristos RXO_xchg, /* s <-> d */ 74a5a4af3bSchristos RXO_stcc, /* d = s if cond(s2) */ 75a5a4af3bSchristos RXO_rtsd, /* rtsd, 1=imm, 2-0 = reg if reg type */ 76a5a4af3bSchristos 77a5a4af3bSchristos /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note 78a5a4af3bSchristos that d may be "None". */ 79a5a4af3bSchristos RXO_and, 80a5a4af3bSchristos RXO_or, 81a5a4af3bSchristos RXO_xor, 82a5a4af3bSchristos RXO_add, 83a5a4af3bSchristos RXO_sub, 84a5a4af3bSchristos RXO_mul, 85a5a4af3bSchristos RXO_div, 86a5a4af3bSchristos RXO_divu, 87a5a4af3bSchristos RXO_shll, 88a5a4af3bSchristos RXO_shar, 89a5a4af3bSchristos RXO_shlr, 90a5a4af3bSchristos 91a5a4af3bSchristos RXO_adc, /* d = d + s + carry */ 92a5a4af3bSchristos RXO_sbb, /* d = d - s - ~carry */ 93a5a4af3bSchristos RXO_abs, /* d = |s| */ 94a5a4af3bSchristos RXO_max, /* d = max(d,s) */ 95a5a4af3bSchristos RXO_min, /* d = min(d,s) */ 96a5a4af3bSchristos RXO_emul, /* d:64 = d:32 * s */ 97a5a4af3bSchristos RXO_emulu, /* d:64 = d:32 * s (unsigned) */ 98a5a4af3bSchristos 99a5a4af3bSchristos RXO_rolc, /* d <<= 1 through carry */ 100a5a4af3bSchristos RXO_rorc, /* d >>= 1 through carry*/ 101a5a4af3bSchristos RXO_rotl, /* d <<= #s without carry */ 102a5a4af3bSchristos RXO_rotr, /* d >>= #s without carry*/ 103a5a4af3bSchristos RXO_revw, /* d = revw(s) */ 104a5a4af3bSchristos RXO_revl, /* d = revl(s) */ 105a5a4af3bSchristos RXO_branch, /* pc = d if cond(s) */ 106a5a4af3bSchristos RXO_branchrel,/* pc += d if cond(s) */ 107a5a4af3bSchristos RXO_jsr, /* pc = d */ 108a5a4af3bSchristos RXO_jsrrel, /* pc += d */ 109a5a4af3bSchristos RXO_rts, 110a5a4af3bSchristos RXO_nop, 111a5a4af3bSchristos RXO_nop2, 112a5a4af3bSchristos RXO_nop3, 113e5cb852cSchristos RXO_nop4, 114e5cb852cSchristos RXO_nop5, 115e5cb852cSchristos RXO_nop6, 116e5cb852cSchristos RXO_nop7, 117a5a4af3bSchristos 118a5a4af3bSchristos RXO_scmpu, 119a5a4af3bSchristos RXO_smovu, 120a5a4af3bSchristos RXO_smovb, 121a5a4af3bSchristos RXO_suntil, 122a5a4af3bSchristos RXO_swhile, 123a5a4af3bSchristos RXO_smovf, 124a5a4af3bSchristos RXO_sstr, 125a5a4af3bSchristos 126a5a4af3bSchristos RXO_rmpa, 127a5a4af3bSchristos RXO_mulhi, 128a5a4af3bSchristos RXO_mullo, 129a5a4af3bSchristos RXO_machi, 130a5a4af3bSchristos RXO_maclo, 131a5a4af3bSchristos RXO_mvtachi, 132a5a4af3bSchristos RXO_mvtaclo, 133a5a4af3bSchristos RXO_mvfachi, 134a5a4af3bSchristos RXO_mvfacmi, 135a5a4af3bSchristos RXO_mvfaclo, 136a5a4af3bSchristos RXO_racw, 137a5a4af3bSchristos 138a5a4af3bSchristos RXO_sat, /* sat(d) */ 139a5a4af3bSchristos RXO_satr, 140a5a4af3bSchristos 141a5a4af3bSchristos RXO_fadd, /* d op= s */ 142a5a4af3bSchristos RXO_fcmp, 143a5a4af3bSchristos RXO_fsub, 144a5a4af3bSchristos RXO_ftoi, 145a5a4af3bSchristos RXO_fmul, 146a5a4af3bSchristos RXO_fdiv, 147a5a4af3bSchristos RXO_round, 148a5a4af3bSchristos RXO_itof, 149a5a4af3bSchristos 150a5a4af3bSchristos RXO_bset, /* d |= (1<<s) */ 151a5a4af3bSchristos RXO_bclr, /* d &= ~(1<<s) */ 152a5a4af3bSchristos RXO_btst, /* s & (1<<s2) */ 153a5a4af3bSchristos RXO_bnot, /* d ^= (1<<s) */ 154a5a4af3bSchristos RXO_bmcc, /* d<s> = cond(s2) */ 155a5a4af3bSchristos 156a5a4af3bSchristos RXO_clrpsw, /* flag index in d */ 157a5a4af3bSchristos RXO_setpsw, /* flag index in d */ 158a5a4af3bSchristos RXO_mvtipl, /* new IPL in s */ 159a5a4af3bSchristos 160a5a4af3bSchristos RXO_rtfi, 161a5a4af3bSchristos RXO_rte, 162a5a4af3bSchristos RXO_rtd, /* undocumented */ 163a5a4af3bSchristos RXO_brk, 164a5a4af3bSchristos RXO_dbt, /* undocumented */ 165a5a4af3bSchristos RXO_int, /* vector id in s */ 166a5a4af3bSchristos RXO_stop, 167a5a4af3bSchristos RXO_wait, 168a5a4af3bSchristos 169a5a4af3bSchristos RXO_sccnd, /* d = cond(s) ? 1 : 0 */ 170e5cb852cSchristos 171e5cb852cSchristos RXO_fsqrt, 172e5cb852cSchristos RXO_ftou, 173e5cb852cSchristos RXO_utof, 174e5cb852cSchristos RXO_movco, 175e5cb852cSchristos RXO_movli, 176e5cb852cSchristos RXO_emaca, 177e5cb852cSchristos RXO_emsba, 178e5cb852cSchristos RXO_emula, 179e5cb852cSchristos RXO_maclh, 180e5cb852cSchristos RXO_msbhi, 181e5cb852cSchristos RXO_msblh, 182e5cb852cSchristos RXO_msblo, 183e5cb852cSchristos RXO_mullh, 184e5cb852cSchristos RXO_mvfacgu, 185e5cb852cSchristos RXO_mvtacgu, 186e5cb852cSchristos RXO_racl, 187e5cb852cSchristos RXO_rdacl, 188e5cb852cSchristos RXO_rdacw, 18947c37bc2Schristos 19047c37bc2Schristos RXO_bfmov, 19147c37bc2Schristos RXO_bfmovz, 19247c37bc2Schristos RXO_rstr, 19347c37bc2Schristos RXO_save, 19447c37bc2Schristos RXO_dmov, 19547c37bc2Schristos RXO_dpopm, 19647c37bc2Schristos RXO_dpushm, 19747c37bc2Schristos RXO_mvfdc, 19847c37bc2Schristos RXO_mvfdr, 19947c37bc2Schristos RXO_mvtdc, 20047c37bc2Schristos RXO_dabs, 20147c37bc2Schristos RXO_dadd, 20247c37bc2Schristos RXO_dcmp, 20347c37bc2Schristos RXO_ddiv, 20447c37bc2Schristos RXO_dmul, 20547c37bc2Schristos RXO_dneg, 20647c37bc2Schristos RXO_dround, 20747c37bc2Schristos RXO_dsqrt, 20847c37bc2Schristos RXO_dsub, 20947c37bc2Schristos RXO_dtoi, 21047c37bc2Schristos RXO_dtof, 21147c37bc2Schristos RXO_dtou, 21247c37bc2Schristos RXO_ftod, 21347c37bc2Schristos RXO_itod, 21447c37bc2Schristos RXO_utod 215a5a4af3bSchristos } RX_Opcode_ID; 216a5a4af3bSchristos 217a5a4af3bSchristos /* Condition bitpatterns, as registers. */ 218a5a4af3bSchristos #define RXC_eq 0 219a5a4af3bSchristos #define RXC_z 0 220a5a4af3bSchristos #define RXC_ne 1 221a5a4af3bSchristos #define RXC_nz 1 222a5a4af3bSchristos #define RXC_c 2 223a5a4af3bSchristos #define RXC_nc 3 224a5a4af3bSchristos #define RXC_gtu 4 225a5a4af3bSchristos #define RXC_leu 5 226a5a4af3bSchristos #define RXC_pz 6 227a5a4af3bSchristos #define RXC_n 7 228a5a4af3bSchristos #define RXC_ge 8 229a5a4af3bSchristos #define RXC_lt 9 230a5a4af3bSchristos #define RXC_gt 10 231a5a4af3bSchristos #define RXC_le 11 232a5a4af3bSchristos #define RXC_o 12 233a5a4af3bSchristos #define RXC_no 13 234a5a4af3bSchristos #define RXC_always 14 235a5a4af3bSchristos #define RXC_never 15 236a5a4af3bSchristos 237a5a4af3bSchristos typedef struct 238a5a4af3bSchristos { 239a5a4af3bSchristos RX_Operand_Type type; 240a5a4af3bSchristos int reg; 241a5a4af3bSchristos int addend; 242a5a4af3bSchristos RX_Size size; 243a5a4af3bSchristos } RX_Opcode_Operand; 244a5a4af3bSchristos 245a5a4af3bSchristos typedef struct 246a5a4af3bSchristos { 247a5a4af3bSchristos RX_Opcode_ID id; 248a5a4af3bSchristos int n_bytes; 249a5a4af3bSchristos int prefix; 250a5a4af3bSchristos char * syntax; 251a5a4af3bSchristos RX_Size size; 252a5a4af3bSchristos /* By convention, these are destination, source1, source2. */ 253a5a4af3bSchristos RX_Opcode_Operand op[3]; 254a5a4af3bSchristos 255a5a4af3bSchristos /* The logic here is: 256a5a4af3bSchristos newflags = (oldflags & ~(int)flags_0) | flags_1 | (op_flags & flags_s) 257a5a4af3bSchristos Only the O, S, Z, and C flags are affected. */ 258a5a4af3bSchristos char flags_0; /* This also clears out flags-to-be-set. */ 259a5a4af3bSchristos char flags_1; 260a5a4af3bSchristos char flags_s; 261a5a4af3bSchristos } RX_Opcode_Decoded; 262a5a4af3bSchristos 263a5a4af3bSchristos /* Within the syntax, %c-style format specifiers are as follows: 264a5a4af3bSchristos 265a5a4af3bSchristos %% = '%' character 266a5a4af3bSchristos %0 = operand[0] (destination) 267a5a4af3bSchristos %1 = operand[1] (source) 268a5a4af3bSchristos %2 = operand[2] (2nd source) 269a5a4af3bSchristos %s = operation size (b/w/l) 270a5a4af3bSchristos %SN = operand size [N] (N=0,1,2) 271a5a4af3bSchristos %aN = op[N] as an address (N=0,1,2) 272a5a4af3bSchristos 273a5a4af3bSchristos Register numbers 0..15 are general registers. 16..31 are control 274a5a4af3bSchristos registers. 32..47 are condition codes. */ 275a5a4af3bSchristos 276a5a4af3bSchristos int rx_decode_opcode (unsigned long, RX_Opcode_Decoded *, int (*)(void *), void *); 277a5a4af3bSchristos 278a5a4af3bSchristos #ifdef __cplusplus 279a5a4af3bSchristos } 280a5a4af3bSchristos #endif 281