summaryrefslogtreecommitdiff
path: root/opcodes/s12z-opc.h
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/s12z-opc.h')
-rw-r--r--opcodes/s12z-opc.h267
1 files changed, 267 insertions, 0 deletions
diff --git a/opcodes/s12z-opc.h b/opcodes/s12z-opc.h
new file mode 100644
index 00000000000..186a7f29c3f
--- /dev/null
+++ b/opcodes/s12z-opc.h
@@ -0,0 +1,267 @@
+/* s12z-dis.h -- Header file for s12z-dis.c and s12z-decode.c
+ Copyright (C) 2019 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>
+
+/* 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 operator
+ {
+ 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 operator *myoperator, short *osize,
+ int *n_operands, struct operand **operands,
+ struct mem_read_abstraction_base *);
+
+
+#endif /* S12Z_OPC_H */