216 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
| /* Opcode decoder for the Renesas RX
 | |
|    Copyright 2008, 2009, 2010
 | |
|    Free Software Foundation, Inc.
 | |
|    Written by DJ Delorie <dj@redhat.com>
 | |
| 
 | |
|    This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
 | |
| 
 | |
|    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 3 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, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
 | |
|    02110-1301, USA.  */
 | |
| 
 | |
| /* The RX decoder in libopcodes is used by the simulator, gdb's
 | |
|    analyzer, and the disassembler.  Given an opcode data source,
 | |
|    it decodes the next opcode into the following structures.  */
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
|   RX_AnySize = 0,
 | |
|   RX_Byte, /* undefined extension */
 | |
|   RX_UByte,
 | |
|   RX_SByte,
 | |
|   RX_Word, /* undefined extension */
 | |
|   RX_UWord,
 | |
|   RX_SWord,
 | |
|   RX_3Byte,
 | |
|   RX_Long,
 | |
| } RX_Size;
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
|   RX_Operand_None,
 | |
|   RX_Operand_Immediate,	/* #addend */
 | |
|   RX_Operand_Register,	/* Rn */
 | |
|   RX_Operand_Indirect,	/* [Rn + addend] */
 | |
|   RX_Operand_Postinc,	/* [Rn+] */
 | |
|   RX_Operand_Predec,	/* [-Rn] */
 | |
|   RX_Operand_Condition,	/* eq, gtu, etc */
 | |
|   RX_Operand_Flag,	/* [UIOSZC] */
 | |
|   RX_Operand_TwoReg,	/* [Rn + scale*R2] */
 | |
| } RX_Operand_Type;
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
|   RXO_unknown,
 | |
|   RXO_mov,	/* d = s (signed) */
 | |
|   RXO_movbi,	/* d = [s,s2] (signed) */
 | |
|   RXO_movbir,	/* [s,s2] = d (signed) */
 | |
|   RXO_pushm,	/* s..s2 */
 | |
|   RXO_popm,	/* s..s2 */
 | |
|   RXO_xchg,	/* s <-> d */
 | |
|   RXO_stcc,	/* d = s if cond(s2) */
 | |
|   RXO_rtsd,	/* rtsd, 1=imm, 2-0 = reg if reg type */
 | |
| 
 | |
|   /* These are all either d OP= s or, if s2 is set, d = s OP s2.  Note
 | |
|      that d may be "None".  */
 | |
|   RXO_and,
 | |
|   RXO_or,
 | |
|   RXO_xor,
 | |
|   RXO_add,
 | |
|   RXO_sub,
 | |
|   RXO_mul,
 | |
|   RXO_div,
 | |
|   RXO_divu,
 | |
|   RXO_shll,
 | |
|   RXO_shar,
 | |
|   RXO_shlr,
 | |
| 
 | |
|   RXO_adc,	/* d = d + s + carry */
 | |
|   RXO_sbb,	/* d = d - s - ~carry */
 | |
|   RXO_abs,	/* d = |s| */
 | |
|   RXO_max,	/* d = max(d,s) */
 | |
|   RXO_min,	/* d = min(d,s) */
 | |
|   RXO_emul,	/* d:64 = d:32 * s */
 | |
|   RXO_emulu,	/* d:64 = d:32 * s (unsigned) */
 | |
| 
 | |
|   RXO_rolc,	/* d <<= 1 through carry */
 | |
|   RXO_rorc,	/* d >>= 1 through carry*/
 | |
|   RXO_rotl,	/* d <<= #s without carry */
 | |
|   RXO_rotr,	/* d >>= #s without carry*/
 | |
|   RXO_revw,	/* d = revw(s) */
 | |
|   RXO_revl,	/* d = revl(s) */
 | |
|   RXO_branch,	/* pc = d if cond(s) */
 | |
|   RXO_branchrel,/* pc += d if cond(s) */
 | |
|   RXO_jsr,	/* pc = d */
 | |
|   RXO_jsrrel,	/* pc += d */
 | |
|   RXO_rts,
 | |
|   RXO_nop,
 | |
|   RXO_nop2,
 | |
|   RXO_nop3,
 | |
| 
 | |
|   RXO_scmpu,
 | |
|   RXO_smovu,
 | |
|   RXO_smovb,
 | |
|   RXO_suntil,
 | |
|   RXO_swhile,
 | |
|   RXO_smovf,
 | |
|   RXO_sstr,
 | |
| 
 | |
|   RXO_rmpa,
 | |
|   RXO_mulhi,
 | |
|   RXO_mullo,
 | |
|   RXO_machi,
 | |
|   RXO_maclo,
 | |
|   RXO_mvtachi,
 | |
|   RXO_mvtaclo,
 | |
|   RXO_mvfachi,
 | |
|   RXO_mvfacmi,
 | |
|   RXO_mvfaclo,
 | |
|   RXO_racw,
 | |
| 
 | |
|   RXO_sat,	/* sat(d) */
 | |
|   RXO_satr,
 | |
| 
 | |
|   RXO_fadd,	/* d op= s */
 | |
|   RXO_fcmp,
 | |
|   RXO_fsub,
 | |
|   RXO_ftoi,
 | |
|   RXO_fmul,
 | |
|   RXO_fdiv,
 | |
|   RXO_round,
 | |
|   RXO_itof,
 | |
| 
 | |
|   RXO_bset,	/* d |= (1<<s) */
 | |
|   RXO_bclr,	/* d &= ~(1<<s) */
 | |
|   RXO_btst,	/* s & (1<<s2) */
 | |
|   RXO_bnot,	/* d ^= (1<<s) */
 | |
|   RXO_bmcc,	/* d<s> = cond(s2) */
 | |
| 
 | |
|   RXO_clrpsw,	/* flag index in d */
 | |
|   RXO_setpsw,	/* flag index in d */
 | |
|   RXO_mvtipl,	/* new IPL in s */
 | |
| 
 | |
|   RXO_rtfi,
 | |
|   RXO_rte,
 | |
|   RXO_rtd,	/* undocumented */
 | |
|   RXO_brk,
 | |
|   RXO_dbt,	/* undocumented */
 | |
|   RXO_int,	/* vector id in s */
 | |
|   RXO_stop,
 | |
|   RXO_wait,
 | |
| 
 | |
|   RXO_sccnd,	/* d = cond(s) ? 1 : 0 */
 | |
| } RX_Opcode_ID;
 | |
| 
 | |
| /* Condition bitpatterns, as registers.  */
 | |
| #define RXC_eq		0
 | |
| #define RXC_z		0
 | |
| #define RXC_ne		1
 | |
| #define RXC_nz		1
 | |
| #define RXC_c		2
 | |
| #define RXC_nc		3
 | |
| #define RXC_gtu		4
 | |
| #define RXC_leu		5
 | |
| #define RXC_pz		6
 | |
| #define RXC_n		7
 | |
| #define RXC_ge		8
 | |
| #define RXC_lt		9
 | |
| #define RXC_gt		10
 | |
| #define RXC_le		11
 | |
| #define RXC_o		12
 | |
| #define RXC_no		13
 | |
| #define RXC_always	14
 | |
| #define RXC_never	15
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   RX_Operand_Type  type;
 | |
|   int              reg;
 | |
|   int              addend;
 | |
|   RX_Size          size;
 | |
| } RX_Opcode_Operand;
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   RX_Opcode_ID      id;
 | |
|   int               n_bytes;
 | |
|   int               prefix;
 | |
|   char *            syntax;
 | |
|   RX_Size           size;
 | |
|   /* By convention, these are destination, source1, source2.  */
 | |
|   RX_Opcode_Operand op[3];
 | |
| 
 | |
|   /* The logic here is:
 | |
|      newflags = (oldflags & ~(int)flags_0) | flags_1 | (op_flags & flags_s)
 | |
|      Only the O, S, Z, and C flags are affected.  */
 | |
|   char flags_0; /* This also clears out flags-to-be-set.  */
 | |
|   char flags_1;
 | |
|   char flags_s;
 | |
| } RX_Opcode_Decoded;
 | |
| 
 | |
| /* Within the syntax, %c-style format specifiers are as follows:
 | |
| 
 | |
|    %% = '%' character
 | |
|    %0 = operand[0] (destination)
 | |
|    %1 = operand[1] (source)
 | |
|    %2 = operand[2] (2nd source)
 | |
|    %s = operation size (b/w/l)
 | |
|    %SN = operand size [N] (N=0,1,2)
 | |
|    %aN = op[N] as an address (N=0,1,2)
 | |
| 
 | |
|    Register numbers 0..15 are general registers.  16..31 are control
 | |
|    registers.  32..47 are condition codes.  */
 | |
| 
 | |
| int rx_decode_opcode (unsigned long, RX_Opcode_Decoded *, int (*)(void *), void *);
 |