198b9484cSchristos /* Opcode decoder for the Renesas RX 2*aab831ceSchristos Copyright (C) 2008-2024 Free Software Foundation, Inc. 398b9484cSchristos Written by DJ Delorie <dj@redhat.com> 498b9484cSchristos 598b9484cSchristos This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler. 698b9484cSchristos 798b9484cSchristos This program is free software; you can redistribute it and/or modify 898b9484cSchristos it under the terms of the GNU General Public License as published by 998b9484cSchristos the Free Software Foundation; either version 3 of the License, or 1098b9484cSchristos (at your option) any later version. 1198b9484cSchristos 1298b9484cSchristos This program is distributed in the hope that it will be useful, 1398b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1498b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598b9484cSchristos GNU General Public License for more details. 1698b9484cSchristos 1798b9484cSchristos You should have received a copy of the GNU General Public License 1898b9484cSchristos along with this program; if not, write to the Free Software 1998b9484cSchristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 2098b9484cSchristos 02110-1301, USA. */ 2198b9484cSchristos 2298b9484cSchristos /* The RX decoder in libopcodes is used by the simulator, gdb's 2398b9484cSchristos analyzer, and the disassembler. Given an opcode data source, 2498b9484cSchristos it decodes the next opcode into the following structures. */ 2598b9484cSchristos 26212397c6Schristos #ifdef __cplusplus 27212397c6Schristos extern "C" { 28212397c6Schristos #endif 29212397c6Schristos 3098b9484cSchristos typedef enum 3198b9484cSchristos { 3298b9484cSchristos RX_AnySize = 0, 3398b9484cSchristos RX_Byte, /* undefined extension */ 3498b9484cSchristos RX_UByte, 3598b9484cSchristos RX_SByte, 3698b9484cSchristos RX_Word, /* undefined extension */ 3798b9484cSchristos RX_UWord, 3898b9484cSchristos RX_SWord, 3998b9484cSchristos RX_3Byte, 4098b9484cSchristos RX_Long, 414559860eSchristos RX_Double, 42ba340e45Schristos RX_Bad_Size, 43ba340e45Schristos RX_MAX_SIZE 4498b9484cSchristos } RX_Size; 4598b9484cSchristos 4698b9484cSchristos typedef enum 4798b9484cSchristos { 4898b9484cSchristos RX_Operand_None, 4998b9484cSchristos RX_Operand_Immediate, /* #addend */ 5098b9484cSchristos RX_Operand_Register, /* Rn */ 5198b9484cSchristos RX_Operand_Indirect, /* [Rn + addend] */ 52ba340e45Schristos RX_Operand_Zero_Indirect,/* [Rn] */ 5398b9484cSchristos RX_Operand_Postinc, /* [Rn+] */ 5498b9484cSchristos RX_Operand_Predec, /* [-Rn] */ 5598b9484cSchristos RX_Operand_Condition, /* eq, gtu, etc */ 5698b9484cSchristos RX_Operand_Flag, /* [UIOSZC] */ 5798b9484cSchristos RX_Operand_TwoReg, /* [Rn + scale*R2] */ 584559860eSchristos RX_Operand_DoubleReg, /* DRn */ 594559860eSchristos RX_Operand_DoubleRegH,/* DRHn */ 604559860eSchristos RX_Operand_DoubleRegL,/* DRLn */ 614559860eSchristos RX_Operand_DoubleCReg,/* DCRxx */ 624559860eSchristos RX_Operand_DoubleCond,/* UN/EQ/LE/LT */ 6398b9484cSchristos } RX_Operand_Type; 6498b9484cSchristos 6598b9484cSchristos typedef enum 6698b9484cSchristos { 6798b9484cSchristos RXO_unknown, 6898b9484cSchristos RXO_mov, /* d = s (signed) */ 6998b9484cSchristos RXO_movbi, /* d = [s,s2] (signed) */ 7098b9484cSchristos RXO_movbir, /* [s,s2] = d (signed) */ 7198b9484cSchristos RXO_pushm, /* s..s2 */ 7298b9484cSchristos RXO_popm, /* s..s2 */ 7398b9484cSchristos RXO_xchg, /* s <-> d */ 7498b9484cSchristos RXO_stcc, /* d = s if cond(s2) */ 7598b9484cSchristos RXO_rtsd, /* rtsd, 1=imm, 2-0 = reg if reg type */ 7698b9484cSchristos 7798b9484cSchristos /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note 7898b9484cSchristos that d may be "None". */ 7998b9484cSchristos RXO_and, 8098b9484cSchristos RXO_or, 8198b9484cSchristos RXO_xor, 8298b9484cSchristos RXO_add, 8398b9484cSchristos RXO_sub, 8498b9484cSchristos RXO_mul, 8598b9484cSchristos RXO_div, 8698b9484cSchristos RXO_divu, 8798b9484cSchristos RXO_shll, 8898b9484cSchristos RXO_shar, 8998b9484cSchristos RXO_shlr, 9098b9484cSchristos 9198b9484cSchristos RXO_adc, /* d = d + s + carry */ 9298b9484cSchristos RXO_sbb, /* d = d - s - ~carry */ 9398b9484cSchristos RXO_abs, /* d = |s| */ 9498b9484cSchristos RXO_max, /* d = max(d,s) */ 9598b9484cSchristos RXO_min, /* d = min(d,s) */ 9698b9484cSchristos RXO_emul, /* d:64 = d:32 * s */ 9798b9484cSchristos RXO_emulu, /* d:64 = d:32 * s (unsigned) */ 9898b9484cSchristos 9998b9484cSchristos RXO_rolc, /* d <<= 1 through carry */ 10098b9484cSchristos RXO_rorc, /* d >>= 1 through carry*/ 10198b9484cSchristos RXO_rotl, /* d <<= #s without carry */ 10298b9484cSchristos RXO_rotr, /* d >>= #s without carry*/ 10398b9484cSchristos RXO_revw, /* d = revw(s) */ 10498b9484cSchristos RXO_revl, /* d = revl(s) */ 10598b9484cSchristos RXO_branch, /* pc = d if cond(s) */ 10698b9484cSchristos RXO_branchrel,/* pc += d if cond(s) */ 10798b9484cSchristos RXO_jsr, /* pc = d */ 10898b9484cSchristos RXO_jsrrel, /* pc += d */ 10998b9484cSchristos RXO_rts, 11098b9484cSchristos RXO_nop, 11198b9484cSchristos RXO_nop2, 11298b9484cSchristos RXO_nop3, 113ba340e45Schristos RXO_nop4, 114ba340e45Schristos RXO_nop5, 115ba340e45Schristos RXO_nop6, 116ba340e45Schristos RXO_nop7, 11798b9484cSchristos 11898b9484cSchristos RXO_scmpu, 11998b9484cSchristos RXO_smovu, 12098b9484cSchristos RXO_smovb, 12198b9484cSchristos RXO_suntil, 12298b9484cSchristos RXO_swhile, 12398b9484cSchristos RXO_smovf, 12498b9484cSchristos RXO_sstr, 12598b9484cSchristos 12698b9484cSchristos RXO_rmpa, 12798b9484cSchristos RXO_mulhi, 12898b9484cSchristos RXO_mullo, 12998b9484cSchristos RXO_machi, 13098b9484cSchristos RXO_maclo, 13198b9484cSchristos RXO_mvtachi, 13298b9484cSchristos RXO_mvtaclo, 13398b9484cSchristos RXO_mvfachi, 13498b9484cSchristos RXO_mvfacmi, 13598b9484cSchristos RXO_mvfaclo, 13698b9484cSchristos RXO_racw, 13798b9484cSchristos 13898b9484cSchristos RXO_sat, /* sat(d) */ 13998b9484cSchristos RXO_satr, 14098b9484cSchristos 14198b9484cSchristos RXO_fadd, /* d op= s */ 14298b9484cSchristos RXO_fcmp, 14398b9484cSchristos RXO_fsub, 14498b9484cSchristos RXO_ftoi, 14598b9484cSchristos RXO_fmul, 14698b9484cSchristos RXO_fdiv, 14798b9484cSchristos RXO_round, 14898b9484cSchristos RXO_itof, 14998b9484cSchristos 15098b9484cSchristos RXO_bset, /* d |= (1<<s) */ 15198b9484cSchristos RXO_bclr, /* d &= ~(1<<s) */ 15298b9484cSchristos RXO_btst, /* s & (1<<s2) */ 15398b9484cSchristos RXO_bnot, /* d ^= (1<<s) */ 15498b9484cSchristos RXO_bmcc, /* d<s> = cond(s2) */ 15598b9484cSchristos 15698b9484cSchristos RXO_clrpsw, /* flag index in d */ 15798b9484cSchristos RXO_setpsw, /* flag index in d */ 15898b9484cSchristos RXO_mvtipl, /* new IPL in s */ 15998b9484cSchristos 16098b9484cSchristos RXO_rtfi, 16198b9484cSchristos RXO_rte, 16298b9484cSchristos RXO_rtd, /* undocumented */ 16398b9484cSchristos RXO_brk, 16498b9484cSchristos RXO_dbt, /* undocumented */ 16598b9484cSchristos RXO_int, /* vector id in s */ 16698b9484cSchristos RXO_stop, 16798b9484cSchristos RXO_wait, 16898b9484cSchristos 16998b9484cSchristos RXO_sccnd, /* d = cond(s) ? 1 : 0 */ 170ba340e45Schristos 171ba340e45Schristos RXO_fsqrt, 172ba340e45Schristos RXO_ftou, 173ba340e45Schristos RXO_utof, 174ba340e45Schristos RXO_movco, 175ba340e45Schristos RXO_movli, 176ba340e45Schristos RXO_emaca, 177ba340e45Schristos RXO_emsba, 178ba340e45Schristos RXO_emula, 179ba340e45Schristos RXO_maclh, 180ba340e45Schristos RXO_msbhi, 181ba340e45Schristos RXO_msblh, 182ba340e45Schristos RXO_msblo, 183ba340e45Schristos RXO_mullh, 184ba340e45Schristos RXO_mvfacgu, 185ba340e45Schristos RXO_mvtacgu, 186ba340e45Schristos RXO_racl, 187ba340e45Schristos RXO_rdacl, 188ba340e45Schristos RXO_rdacw, 1894559860eSchristos 1904559860eSchristos RXO_bfmov, 1914559860eSchristos RXO_bfmovz, 1924559860eSchristos RXO_rstr, 1934559860eSchristos RXO_save, 1944559860eSchristos RXO_dmov, 1954559860eSchristos RXO_dpopm, 1964559860eSchristos RXO_dpushm, 1974559860eSchristos RXO_mvfdc, 1984559860eSchristos RXO_mvfdr, 1994559860eSchristos RXO_mvtdc, 2004559860eSchristos RXO_dabs, 2014559860eSchristos RXO_dadd, 2024559860eSchristos RXO_dcmp, 2034559860eSchristos RXO_ddiv, 2044559860eSchristos RXO_dmul, 2054559860eSchristos RXO_dneg, 2064559860eSchristos RXO_dround, 2074559860eSchristos RXO_dsqrt, 2084559860eSchristos RXO_dsub, 2094559860eSchristos RXO_dtoi, 2104559860eSchristos RXO_dtof, 2114559860eSchristos RXO_dtou, 2124559860eSchristos RXO_ftod, 2134559860eSchristos RXO_itod, 2144559860eSchristos RXO_utod 21598b9484cSchristos } RX_Opcode_ID; 21698b9484cSchristos 21798b9484cSchristos /* Condition bitpatterns, as registers. */ 21898b9484cSchristos #define RXC_eq 0 21998b9484cSchristos #define RXC_z 0 22098b9484cSchristos #define RXC_ne 1 22198b9484cSchristos #define RXC_nz 1 22298b9484cSchristos #define RXC_c 2 22398b9484cSchristos #define RXC_nc 3 22498b9484cSchristos #define RXC_gtu 4 22598b9484cSchristos #define RXC_leu 5 22698b9484cSchristos #define RXC_pz 6 22798b9484cSchristos #define RXC_n 7 22898b9484cSchristos #define RXC_ge 8 22998b9484cSchristos #define RXC_lt 9 23098b9484cSchristos #define RXC_gt 10 23198b9484cSchristos #define RXC_le 11 23298b9484cSchristos #define RXC_o 12 23398b9484cSchristos #define RXC_no 13 23498b9484cSchristos #define RXC_always 14 23598b9484cSchristos #define RXC_never 15 23698b9484cSchristos 23798b9484cSchristos typedef struct 23898b9484cSchristos { 23998b9484cSchristos RX_Operand_Type type; 24098b9484cSchristos int reg; 24198b9484cSchristos int addend; 24298b9484cSchristos RX_Size size; 24398b9484cSchristos } RX_Opcode_Operand; 24498b9484cSchristos 24598b9484cSchristos typedef struct 24698b9484cSchristos { 24798b9484cSchristos RX_Opcode_ID id; 24898b9484cSchristos int n_bytes; 24998b9484cSchristos int prefix; 25098b9484cSchristos char * syntax; 25198b9484cSchristos RX_Size size; 25298b9484cSchristos /* By convention, these are destination, source1, source2. */ 25398b9484cSchristos RX_Opcode_Operand op[3]; 25498b9484cSchristos 25598b9484cSchristos /* The logic here is: 25698b9484cSchristos newflags = (oldflags & ~(int)flags_0) | flags_1 | (op_flags & flags_s) 25798b9484cSchristos Only the O, S, Z, and C flags are affected. */ 25898b9484cSchristos char flags_0; /* This also clears out flags-to-be-set. */ 25998b9484cSchristos char flags_1; 26098b9484cSchristos char flags_s; 26198b9484cSchristos } RX_Opcode_Decoded; 26298b9484cSchristos 26398b9484cSchristos /* Within the syntax, %c-style format specifiers are as follows: 26498b9484cSchristos 26598b9484cSchristos %% = '%' character 26698b9484cSchristos %0 = operand[0] (destination) 26798b9484cSchristos %1 = operand[1] (source) 26898b9484cSchristos %2 = operand[2] (2nd source) 26998b9484cSchristos %s = operation size (b/w/l) 27098b9484cSchristos %SN = operand size [N] (N=0,1,2) 27198b9484cSchristos %aN = op[N] as an address (N=0,1,2) 27298b9484cSchristos 27398b9484cSchristos Register numbers 0..15 are general registers. 16..31 are control 27498b9484cSchristos registers. 32..47 are condition codes. */ 27598b9484cSchristos 27698b9484cSchristos int rx_decode_opcode (unsigned long, RX_Opcode_Decoded *, int (*)(void *), void *); 277212397c6Schristos 278212397c6Schristos #ifdef __cplusplus 279212397c6Schristos } 280212397c6Schristos #endif 281