| /* s12z-dis.h -- Header file for s12z-dis.c and s12z-decode.c | 
 |    Copyright (C) 2019-2024 Free Software Foundation, Inc. | 
 |  | 
 |    This file is part of the GNU opcodes library. | 
 |  | 
 |    This library 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, or (at your option) | 
 |    any later version. | 
 |  | 
 |    It 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; see the file COPYING3. If not, | 
 |    see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #ifndef S12Z_OPC_H | 
 | #define S12Z_OPC_H | 
 |  | 
 | #include <stdbool.h> | 
 |  | 
 | #ifdef __cplusplus | 
 | extern "C" | 
 | { | 
 | #endif | 
 |  | 
 | /* An abstraction used to read machine code from a source.  */ | 
 | struct mem_read_abstraction_base | 
 | { | 
 |   int (*read) (struct mem_read_abstraction_base *, int, size_t, bfd_byte *); | 
 |   void (*advance) (struct mem_read_abstraction_base *); | 
 |   bfd_vma (*posn) (struct mem_read_abstraction_base *); | 
 | }; | 
 |  | 
 |  | 
 | /* Machine code operators. | 
 |    These *roughly* correspond to opcodes. | 
 |    But describe their purpose rather than their form.  */ | 
 | enum optr | 
 |   { | 
 |     OP_INVALID = 0, | 
 |  | 
 |     OP_push, | 
 |     OP_pull, | 
 |     /* Test and branch.  */ | 
 |     OP_tbNE, OP_tbEQ, OP_tbPL, OP_tbMI, OP_tbGT, OP_tbLE, | 
 |     /* Decrement and branch.  */ | 
 |     OP_dbNE, OP_dbEQ, OP_dbPL, OP_dbMI, OP_dbGT, OP_dbLE, | 
 |  | 
 |     /* Note: sex and exg are the same opcode. | 
 |        They are mnemonic changes according to the operands.  */ | 
 |     OP_sex, | 
 |     OP_exg, | 
 |  | 
 |     /* Shifters.  */ | 
 |     OP_lsl, OP_lsr, | 
 |     OP_asl, OP_asr, | 
 |     OP_rol, OP_ror, | 
 |     /* Bit field operations.  */ | 
 |     OP_bfins, OP_bfext, | 
 |     OP_trap, | 
 |  | 
 |     OP_ld, | 
 |     OP_st, | 
 |     OP_cmp, | 
 |  | 
 |     OP_stop, | 
 |     OP_wai, | 
 |     OP_sys, | 
 |  | 
 |     OP_minu, | 
 |     OP_mins, | 
 |     OP_maxu, | 
 |     OP_maxs, | 
 |  | 
 |     OP_abs, | 
 |     OP_adc, | 
 |     OP_bit, | 
 |     OP_sbc, | 
 |     OP_rti, | 
 |     OP_clb, | 
 |     OP_eor, | 
 |  | 
 |     OP_sat, | 
 |  | 
 |     OP_nop, | 
 |     OP_bgnd, | 
 |     OP_brclr, | 
 |     OP_brset, | 
 |     OP_rts, | 
 |     OP_lea, | 
 |     OP_mov, | 
 |  | 
 |     OP_bra, | 
 |     OP_bsr, | 
 |     OP_bhi, | 
 |     OP_bls, | 
 |     OP_bcc, | 
 |     OP_bcs, | 
 |     OP_bne, | 
 |     OP_beq, | 
 |     OP_bvc, | 
 |     OP_bvs, | 
 |     OP_bpl, | 
 |     OP_bmi, | 
 |     OP_bge, | 
 |     OP_blt, | 
 |     OP_bgt, | 
 |     OP_ble, | 
 |     OP_inc, | 
 |     OP_clr, | 
 |     OP_dec, | 
 |  | 
 |     OP_add, | 
 |     OP_sub, | 
 |     OP_and, | 
 |     OP_or, | 
 |  | 
 |     OP_tfr, | 
 |     OP_jmp, | 
 |     OP_jsr, | 
 |     OP_com, | 
 |     OP_andcc, | 
 |     OP_neg, | 
 |     OP_orcc, | 
 |     OP_bclr, | 
 |     OP_bset, | 
 |     OP_btgl, | 
 |     OP_swi, | 
 |  | 
 |     OP_mulu, | 
 |     OP_divu, | 
 |     OP_modu, | 
 |     OP_macu, | 
 |     OP_qmulu, | 
 |  | 
 |     OP_muls, | 
 |     OP_divs, | 
 |     OP_mods, | 
 |     OP_macs, | 
 |     OP_qmuls, | 
 |  | 
 |     OPBASE_mul = 0x4000, | 
 |     OPBASE_div, | 
 |     OPBASE_mod, | 
 |     OPBASE_mac, | 
 |     OPBASE_qmul, | 
 |  | 
 |     n_OPS | 
 |   }; | 
 |  | 
 |  | 
 | /* Used for operands which mutate their index/base registers. | 
 |    Eg  ld d0, (s+).  */ | 
 | enum op_reg_mutation | 
 |   { | 
 |     OPND_RM_NONE, | 
 |     OPND_RM_PRE_DEC, | 
 |     OPND_RM_PRE_INC, | 
 |     OPND_RM_POST_DEC, | 
 |     OPND_RM_POST_INC | 
 |   }; | 
 |  | 
 | /* The class of an operand.  */ | 
 | enum opnd_class | 
 |   { | 
 |     OPND_CL_IMMEDIATE, | 
 |     OPND_CL_MEMORY, | 
 |     OPND_CL_REGISTER, | 
 |     OPND_CL_REGISTER_ALL,   /* Used only for psh/pul.  */ | 
 |     OPND_CL_REGISTER_ALL16, /* Used only for psh/pul.  */ | 
 |     OPND_CL_SIMPLE_MEMORY, | 
 |     OPND_CL_BIT_FIELD | 
 |   }; | 
 |  | 
 |  | 
 | /* Base structure of all operands.  */ | 
 | struct operand | 
 | { | 
 |   enum opnd_class cl; | 
 |  | 
 |   /* OSIZE determines the size of memory access for | 
 |      the  operation in which the operand participates. | 
 |      It may be -1 which indicates either unknown | 
 |      (must be determined by other operands) or if | 
 |      it is not applicable for this operation.  */ | 
 |   int osize; | 
 | }; | 
 |  | 
 | /* Immediate operands.  Eg: #23  */ | 
 | struct immediate_operand | 
 | { | 
 |   struct operand parent; | 
 |   int value; | 
 | }; | 
 |  | 
 | /* Bitfield operands.   Used only in bfext and bfins | 
 |    instructions.  */ | 
 | struct bitfield_operand | 
 | { | 
 |   struct operand parent; | 
 |   int width; | 
 |   int offset; | 
 | }; | 
 |  | 
 | /* Register operands.  */ | 
 | struct register_operand | 
 | { | 
 |   struct operand parent; | 
 |   int reg; | 
 | }; | 
 |  | 
 |  | 
 | /* Simple memory operands.  ie, direct memory, | 
 |    no index, no pre/post inc/dec.  May be either relative or absolute. | 
 |    Eg st d0, 0x123456  */ | 
 | struct simple_memory_operand | 
 | { | 
 |   struct operand parent; | 
 |  | 
 |   bfd_vma addr; | 
 |   bfd_vma base; | 
 |   bool relative; | 
 | }; | 
 |  | 
 |  | 
 | /* Memory operands.    Should be able to represent all memory | 
 |    operands in the S12Z instruction set which are not simple | 
 |    memory operands.  */ | 
 | struct memory_operand | 
 | { | 
 |   struct operand parent; | 
 |  | 
 |   /* True for indirect operands: eg [0x123456]   */ | 
 |   bool indirect; | 
 |  | 
 |   /* The value of any offset.  eg 45 in (45,d7) */ | 
 |     int base_offset; | 
 |  | 
 |   /* Does this operand increment or decrement | 
 |      its participating registers.  Eg (-s) */ | 
 |   enum op_reg_mutation mutation; | 
 |  | 
 |   /* The number of registers participating in this operand. | 
 |      For S12Z this is always in the range [0, 6] (but for most | 
 |      instructions it's <= 2).  */ | 
 |   int n_regs; | 
 |  | 
 |   /* The participating registers.  */ | 
 |   int regs[6]; | 
 | }; | 
 |  | 
 |  | 
 | /* Decode a single instruction. | 
 |    OPERATOR, OSIZE, N_OPERANDS and OPERANDS are pointers to | 
 |    variables which must be provided by the caller. | 
 |    N_OPERANDS will be incremented by the number of operands read, so | 
 |    you should assign it to something before calling this function. | 
 |    OPERANDS must be large enough to contain all operands read | 
 |    (which may be up to 6). | 
 |    It is the responsibility of the caller to free all operands | 
 |    when they are no longer needed. | 
 |    Returns the number of bytes read.  */ | 
 | int decode_s12z (enum optr *myoperator, short *osize, | 
 | 		 int *n_operands, struct operand **operands, | 
 | 		 struct mem_read_abstraction_base *); | 
 | #ifdef __cplusplus | 
 | } | 
 | #endif | 
 |  | 
 | #endif /* S12Z_OPC_H  */ |