11573Srgrimes/* Opcode decoder for the Renesas RL78
21573Srgrimes   Copyright (C) 2011-2022 Free Software Foundation, Inc.
31573Srgrimes   Written by DJ Delorie <dj@redhat.com>
41573Srgrimes
51573Srgrimes   This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
61573Srgrimes
71573Srgrimes   This program is free software; you can redistribute it and/or modify
81573Srgrimes   it under the terms of the GNU General Public License as published by
91573Srgrimes   the Free Software Foundation; either version 3 of the License, or
101573Srgrimes   (at your option) any later version.
111573Srgrimes
121573Srgrimes   This program is distributed in the hope that it will be useful,
131573Srgrimes   but WITHOUT ANY WARRANTY; without even the implied warranty of
141573Srgrimes   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151573Srgrimes   GNU General Public License for more details.
161573Srgrimes
171573Srgrimes   You should have received a copy of the GNU General Public License
181573Srgrimes   along with this program; if not, write to the Free Software
191573Srgrimes   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
201573Srgrimes   02110-1301, USA.  */
211573Srgrimes
221573Srgrimes/* The RL78 decoder in libopcodes is used by the simulator, gdb's
231573Srgrimes   analyzer, and the disassembler.  Given an opcode data source, it
241573Srgrimes   decodes the next opcode into the following structures.  */
251573Srgrimes
261573Srgrimes#ifndef RL78_OPCODES_H_INCLUDED
271573Srgrimes#define RL78_OPCODES_H_INCLUDED
281573Srgrimes
291573Srgrimes#ifdef __cplusplus
301573Srgrimesextern "C" {
311573Srgrimes#endif
321573Srgrimes
331573Srgrimestypedef enum {
341573Srgrimes  RL78_ISA_DEFAULT,
351573Srgrimes  RL78_ISA_G10,
361573Srgrimes  RL78_ISA_G13,
371573Srgrimes  RL78_ISA_G14,
381573Srgrimes} RL78_Dis_Isa;
391573Srgrimes
4092986Sobrien/* For the purposes of these structures, the RL78 registers are as
4192986Sobrien   follows, despite most of these being memory-mapped and
421573Srgrimes   bank-switched:  */
431573Srgrimestypedef enum {
441573Srgrimes  RL78_Reg_None,
451573Srgrimes  /* The order of these matches the encodings.  */
461573Srgrimes  RL78_Reg_X,
471573Srgrimes  RL78_Reg_A,
481573Srgrimes  RL78_Reg_C,
4971579Sdeischen  RL78_Reg_B,
501573Srgrimes  RL78_Reg_E,
511573Srgrimes  RL78_Reg_D,
5287113Sfenner  RL78_Reg_L,
531573Srgrimes  RL78_Reg_H,
5487490Sphantom  /* The order of these matches the encodings.  */
5587113Sfenner  RL78_Reg_AX,
5687113Sfenner  RL78_Reg_BC,
571573Srgrimes  RL78_Reg_DE,
581573Srgrimes  RL78_Reg_HL,
591573Srgrimes  /* Unordered.  */
60103633Stjr  RL78_Reg_SP,
611573Srgrimes  RL78_Reg_PSW,
621573Srgrimes  RL78_Reg_CS,
6371579Sdeischen  RL78_Reg_ES,
641573Srgrimes  RL78_Reg_PMC,
6571579Sdeischen  RL78_Reg_MEM
661573Srgrimes} RL78_Register;
671573Srgrimes
681573Srgrimestypedef enum
691573Srgrimes{
701573Srgrimes  RL78_Byte = 0,
711573Srgrimes  RL78_Word
7284922Sdfr} RL78_Size;
7384962Sbde
7484962Sbdetypedef enum {
7584962Sbde  RL78_Condition_T,
7684962Sbde  RL78_Condition_F,
7787113Sfenner  RL78_Condition_C,
7887113Sfenner  RL78_Condition_NC,
7987113Sfenner  RL78_Condition_H,
8087113Sfenner  RL78_Condition_NH,
8187113Sfenner  RL78_Condition_Z,
8287113Sfenner  RL78_Condition_NZ
8384962Sbde} RL78_Condition;
8484962Sbde
8587113Sfennertypedef enum {
8684962Sbde  RL78_Operand_None = 0,
8784962Sbde  RL78_Operand_Immediate,	/* #addend */
8884962Sbde  RL78_Operand_Register,	/* reg */
8987113Sfenner  RL78_Operand_Indirect,	/* [reg + reg2 + addend] */
9087113Sfenner  RL78_Operand_Bit,		/* reg.bit */
9187113Sfenner  RL78_Operand_BitIndirect,	/* [reg+reg2+addend].bit */
9287113Sfenner  RL78_Operand_PreDec,		/* [--reg] = push */
9384922Sdfr  RL78_Operand_PostInc		/* [reg++] = pop */
9484962Sbde} RL78_Operand_Type;
9584962Sbde
9684922Sdfrtypedef enum
97103633Stjr{
98103633Stjr  RLO_unknown,
9984922Sdfr  RLO_add,			/* d += s */
10084922Sdfr  RLO_addc,			/* d += s + CY */
10187113Sfenner  RLO_and,			/* d &= s (byte, word, bit) */
10287113Sfenner  RLO_branch,			/* pc = d */
10387113Sfenner  RLO_branch_cond,		/* pc = d if cond(src) */
10487113Sfenner  RLO_branch_cond_clear,	/* pc = d if cond(src), and clear(src) */
10587113Sfenner  RLO_break,			/* BRK */
10687113Sfenner  RLO_call,			/* call */
10787113Sfenner  RLO_cmp,			/* cmp d, s */
10887113Sfenner  RLO_divhu,			/* DIVHU */
109103633Stjr  RLO_divwu,			/* DIVWU */
11087113Sfenner  RLO_halt,			/* HALT */
11187113Sfenner  RLO_mov,			/* d = s */
11292905Sobrien  RLO_mach,			/* MACH */
11392941Sobrien  RLO_machu,			/* MACHU */
11492941Sobrien  RLO_mulu,			/* MULU */
11592941Sobrien  RLO_mulh,			/* MULH */
11692941Sobrien  RLO_mulhu,			/* MULHU */
11792941Sobrien  RLO_nop,			/* NOP */
118103633Stjr  RLO_or,			/* d |= s */
11992905Sobrien  RLO_ret,			/* RET */
12092905Sobrien  RLO_reti,			/* RETI */
12116586Sjraynard  RLO_rol,			/* d <<= s, MSB to LSB and CY */
1221573Srgrimes  RLO_rolc,			/* d <<= s, MSB to CY, CY, to LSB */
1231573Srgrimes  RLO_ror,			/* d >>= s, LSB to MSB and CY */
1241573Srgrimes  RLO_rorc,			/* d >>= s, LSB to CY, CY, to MSB */
1251573Srgrimes  RLO_sar,			/* d >>= s, signed */
1261573Srgrimes  RLO_sel,			/* rb = s */
12771579Sdeischen  RLO_shr,			/* d >>= s, unsigned */
1281573Srgrimes  RLO_shl,			/* d <<= s */
12971579Sdeischen  RLO_skip,			/* skip next insn is cond(s) */
1301573Srgrimes  RLO_stop,			/* STOP */
1311573Srgrimes  RLO_sub,			/* d -= s */
1321573Srgrimes  RLO_subc,			/* d -= s - CY */
1331573Srgrimes  RLO_xch,			/* swap d, s  */
1341573Srgrimes  RLO_xor,			/* d ^= s */
1351573Srgrimes} RL78_Opcode_ID;
1361573Srgrimes
1371573Srgrimestypedef struct {
1381573Srgrimes  RL78_Operand_Type  type;
1391573Srgrimes  int              addend;
1401573Srgrimes  RL78_Register	   reg : 8;
1411573Srgrimes  RL78_Register	   reg2 : 8;
1421573Srgrimes  unsigned char	   bit_number : 4;
1431573Srgrimes  unsigned char	   condition : 3;
1441573Srgrimes  unsigned char	   use_es : 1;
1451573Srgrimes} RL78_Opcode_Operand;
1461573Srgrimes
14771579Sdeischen/* PSW flag bits */
1481573Srgrimes#define RL78_PSW_IE	0x80
1491573Srgrimes#define RL78_PSW_Z	0x40
1501573Srgrimes#define RL78_PSW_RBS1	0x20
1511573Srgrimes#define RL78_PSW_AC	0x10
1521573Srgrimes#define	RL78_PSW_RBS0	0x08
1531573Srgrimes#define	RL78_PSW_ISP1	0x04
1541573Srgrimes#define	RL78_PSW_ISP0	0x02
1551573Srgrimes#define RL78_PSW_CY	0x01
1561573Srgrimes
1571573Srgrimes#define	RL78_SFR_SP	0xffff8
158101776Stjr#define	RL78_SFR_PSW	0xffffa
1591573Srgrimes#define	RL78_SFR_CS	0xffffc
1601573Srgrimes#define	RL78_SFR_ES	0xffffd
1611573Srgrimes#define	RL78_SFR_PMC	0xffffe
1621573Srgrimes#define	RL78_SFR_MEM	0xfffff
1631573Srgrimes
1641573Srgrimestypedef struct
1651573Srgrimes{
16671579Sdeischen  int lineno;
16771579Sdeischen  RL78_Opcode_ID	id:24;
1681573Srgrimes  unsigned		flags:8; /* PSW mask, for side effects only */
1691573Srgrimes  int			n_bytes;
1701573Srgrimes  char *		syntax;
1711573Srgrimes  RL78_Size		size;
1721573Srgrimes  /* By convention, these are destination, source.  */
1731573Srgrimes  RL78_Opcode_Operand	op[2];
1741573Srgrimes} RL78_Opcode_Decoded;
1751573Srgrimes
1761573Srgrimesint rl78_decode_opcode (unsigned long, RL78_Opcode_Decoded *, int (*)(void *), void *, RL78_Dis_Isa);
1771573Srgrimes
1781573Srgrimes#ifdef __cplusplus
1791573Srgrimes}
1801573Srgrimes#endif
1811573Srgrimes
1821573Srgrimes#endif
1831573Srgrimes