* tic6x-dis.c: Add support for displaying 16-bit insns. * tic6xc-insn-formats.h (FLD): Add use of bitfield array. Add 16-bit opcodes. * tic6xc-opcode-table.h: Add 16-bit insns. * tic6x.h: Add support for 16-bit insns. * config/tc-tic6x.c (tic6x_try_encode): Add use of bitfields array. * gas/tic6x/insns16-d-unit.s: New test. * gas/tic6x/insns16-d-unit.d: Expected disassembly. * gas/tic6x/insns16-ddec.s: New test. * gas/tic6x/insns16-ddec.d: Expected disassembly. * gas/tic6x/insns16-dinc.s: New test. * gas/tic6x/insns16-dinc.d: Expected disassembly. * gas/tic6x/insns16-dind.s: New test. * gas/tic6x/insns16-dind.d: Expected disassembly. * gas/tic6x/insns16-doff4.s: New test. * gas/tic6x/insns16-doff4.d: Expected disassembly. * gas/tic6x/insns16-l-unit.s: New test. * gas/tic6x/insns16-l-unit.d: Expected disassembly. * gas/tic6x/insns16-lsd-unit.s: New test. * gas/tic6x/insns16-lsd-unit.d: Expected disassembly. * gas/tic6x/insns16-m-unit.s: New test. * gas/tic6x/insns16-m-unit.d: Expected disassembly. * gas/tic6x/insns16-s-unit-pcrel.s: New test. * gas/tic6x/insns16-s-unit-pcrel.d: Expected disassembly. * gas/tic6x/insns16-s-unit: New test. * gas/tic6x/insns16-s-unit.d: Expected disassembly.
		
			
				
	
	
		
			719 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			719 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* TI C6X opcode information.
 | |
|    Copyright 2010-2013 Free Software Foundation, Inc.
 | |
| 
 | |
|    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.  */
 | |
| 
 | |
| #ifndef OPCODE_TIC6X_H
 | |
| #define OPCODE_TIC6X_H
 | |
| 
 | |
| #include "bfd.h"
 | |
| #include "symcat.h"
 | |
| 
 | |
| /* A field in an instruction format.  The names are based on those
 | |
|    used in the architecture manuals.  */
 | |
| typedef enum
 | |
|   {
 | |
|     tic6x_field_baseR,
 | |
|     tic6x_field_cc,
 | |
|     tic6x_field_creg,
 | |
|     tic6x_field_cst,
 | |
|     tic6x_field_csta,
 | |
|     tic6x_field_cstb,
 | |
|     tic6x_field_dst,
 | |
|     tic6x_field_dstms,
 | |
|     tic6x_field_dw,
 | |
|     tic6x_field_fstgfcyc,
 | |
|     tic6x_field_h,
 | |
|     tic6x_field_ii,
 | |
|     tic6x_field_mask,
 | |
|     tic6x_field_mode,
 | |
|     tic6x_field_n,
 | |
|     tic6x_field_na,
 | |
|     tic6x_field_offsetR,
 | |
|     tic6x_field_op,
 | |
|     tic6x_field_p,
 | |
|     tic6x_field_ptr,
 | |
|     tic6x_field_r,
 | |
|     tic6x_field_s,
 | |
|     tic6x_field_sc,
 | |
|     tic6x_field_src,
 | |
|     tic6x_field_src1,
 | |
|     tic6x_field_src2,
 | |
|     tic6x_field_srcdst,
 | |
|     tic6x_field_srcms,
 | |
|     tic6x_field_sn,
 | |
|     tic6x_field_sz,
 | |
|     tic6x_field_unit,
 | |
|     tic6x_field_t,
 | |
|     tic6x_field_x,
 | |
|     tic6x_field_y,
 | |
|     tic6x_field_z
 | |
|   } tic6x_insn_field_id;
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   /* The least-significant bit position in the field.  */
 | |
|   unsigned short low_pos; 
 | |
| 
 | |
|   /* The number of bits in the field.  */
 | |
|   unsigned short width;
 | |
|   /* The position of the bitfield in the field. */
 | |
|   unsigned short pos;
 | |
| } tic6x_bitfield;
 | |
| 
 | |
| /* Maximum number of subfields in composite field.  */
 | |
| #define TIC6X_MAX_BITFIELDS 4
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   /* The name used to reference the field.  */
 | |
|   tic6x_insn_field_id field_id;
 | |
|   unsigned int num_bitfields;
 | |
|   tic6x_bitfield bitfields[TIC6X_MAX_BITFIELDS];
 | |
| } tic6x_insn_field;
 | |
| 
 | |
| /* Maximum number of variable fields in an instruction format.  */
 | |
| #define TIC6X_MAX_INSN_FIELDS 11
 | |
| 
 | |
| /* A particular instruction format.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* How many bits in the instruction.  */
 | |
|   unsigned int num_bits;
 | |
| 
 | |
|   /* Constant bits in the instruction.  */
 | |
|   unsigned int cst_bits;
 | |
| 
 | |
|   /* Mask matching those bits.  */
 | |
|   unsigned int mask;
 | |
| 
 | |
|   /* The number of instruction fields.  */
 | |
|   unsigned int num_fields;
 | |
| 
 | |
|   /* Descriptions of instruction fields.  */
 | |
|   tic6x_insn_field fields[TIC6X_MAX_INSN_FIELDS];
 | |
| } tic6x_insn_format;
 | |
| 
 | |
| /* An index into the table of instruction formats.  */
 | |
| typedef enum
 | |
|   {
 | |
| #define FMT(name, num_bits, cst_bits, mask, fields)	\
 | |
|   CONCAT2(tic6x_insn_format_, name),
 | |
| #include "tic6x-insn-formats.h"
 | |
| #undef FMT
 | |
|     tic6x_insn_format_max
 | |
|   } tic6x_insn_format_id;
 | |
| 
 | |
| /* The table itself.  */
 | |
| extern const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max];
 | |
| 
 | |
| /* If instruction format FMT has a field FIELD, return a pointer to
 | |
|    the description of that field; otherwise return NULL.  */
 | |
| 
 | |
| const tic6x_insn_field *tic6x_field_from_fmt (const tic6x_insn_format *fmt,
 | |
| 					      tic6x_insn_field_id field);
 | |
| 
 | |
| /* Description of a field (in an instruction format) whose value is
 | |
|    fixed, or constrained to be in a particular range, in a particular
 | |
|    opcode.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The name of the field.  */
 | |
|   tic6x_insn_field_id field_id;
 | |
| 
 | |
|   /* The least value of the field in this instruction.  */
 | |
|   unsigned int min_val;
 | |
| 
 | |
|   /* The greatest value of the field in this instruction.  */
 | |
|   unsigned int max_val;
 | |
| } tic6x_fixed_field;
 | |
| 
 | |
| /* Pseudo opcode fields position for compact instructions
 | |
|    If 16 bits instruction detected, the opcode is enriched
 | |
|    [DSZ/3][BR][SAT][opcode] */
 | |
| #define TIC6X_COMPACT_SAT_POS 16
 | |
| #define TIC6X_COMPACT_BR_POS 17
 | |
| #define TIC6X_COMPACT_DSZ_POS 18
 | |
| 
 | |
| /* Bit-masks for defining instructions present on some subset of
 | |
|    processors; each indicates an instruction present on that processor
 | |
|    and those that are supersets of it.  The options passed to the
 | |
|    assembler determine a bit-mask ANDed with the bit-mask indicating
 | |
|    when the instruction was added to determine whether the instruction
 | |
|    is enabled.  */
 | |
| #define TIC6X_INSN_C62X		0x0001
 | |
| #define TIC6X_INSN_C64X		0x0002
 | |
| #define TIC6X_INSN_C64XP	0x0004
 | |
| #define TIC6X_INSN_C67X		0x0008
 | |
| #define TIC6X_INSN_C67XP	0x0010
 | |
| #define TIC6X_INSN_C674X	0x0020
 | |
| 
 | |
| /* Flags with further information about an opcode table entry.  */
 | |
| 
 | |
| /* Only used by the assembler, not the disassembler.  */
 | |
| #define TIC6X_FLAG_MACRO	0x0001
 | |
| 
 | |
| /* Must be first in its execute packet.  */
 | |
| #define TIC6X_FLAG_FIRST	0x0002
 | |
| 
 | |
| /* Multi-cycle NOP (not used for the NOP n instruction itself, which
 | |
|    is only a multicycle NOP if n > 1).  */
 | |
| #define TIC6X_FLAG_MCNOP	0x0004
 | |
| 
 | |
| /* Cannot be in parallel with a multi-cycle NOP.  */
 | |
| #define TIC6X_FLAG_NO_MCNOP	0x0008
 | |
| 
 | |
| /* Load instruction.  */
 | |
| #define TIC6X_FLAG_LOAD		0x0010
 | |
| 
 | |
| /* Store instruction.  */
 | |
| #define TIC6X_FLAG_STORE	0x0020
 | |
| 
 | |
| /* Unaligned memory operation.  */
 | |
| #define TIC6X_FLAG_UNALIGNED	0x0040
 | |
| 
 | |
| /* Only on side B.  */
 | |
| #define TIC6X_FLAG_SIDE_B_ONLY	0x0080
 | |
| 
 | |
| /* Only on data path T2.  */
 | |
| #define TIC6X_FLAG_SIDE_T2_ONLY	0x0100
 | |
| 
 | |
| /* Does not support cross paths.  */
 | |
| #define TIC6X_FLAG_NO_CROSS	0x0200
 | |
| 
 | |
| /* Annotate this branch instruction as a call.  */
 | |
| #define TIC6X_FLAG_CALL		0x0400
 | |
| 
 | |
| /* Annotate this branch instruction as a return.  */
 | |
| #define TIC6X_FLAG_RETURN	0x0800
 | |
| 
 | |
| /* This instruction starts a software pipelined loop.  */
 | |
| #define TIC6X_FLAG_SPLOOP	0x1000
 | |
| 
 | |
| /* This instruction ends a software pipelined loop.  */
 | |
| #define TIC6X_FLAG_SPKERNEL	0x2000
 | |
| 
 | |
| /* This instruction takes a list of functional units as parameters;
 | |
|    although described as having one parameter, the number may be 0 to
 | |
|    8.  */
 | |
| #define TIC6X_FLAG_SPMASK	0x4000
 | |
| 
 | |
| /* When more than one opcode matches the assembly source, prefer the
 | |
|    one with the highest value for this bit-field.  If two opcode table
 | |
|    entries can match the same syntactic form, they must have different
 | |
|    values here.  */
 | |
| #define TIC6X_PREFER_VAL(n)	(((n) & 0x8000) >> 15)
 | |
| #define TIC6X_FLAG_PREFER(n)	((n) << 15)
 | |
| 
 | |
| /* 16 bits opcode is predicated by register a0 (s = 0) or b0 (s = 1) */
 | |
| #define TIC6X_FLAG_INSN16_SPRED      0x00100000
 | |
| /* 16 bits opcode ignores RS bit of fetch packet header */
 | |
| #define TIC6X_FLAG_INSN16_NORS       0x00200000
 | |
| /* 16 bits opcode only on side B */
 | |
| #define TIC6X_FLAG_INSN16_BSIDE      0x00400000
 | |
| /* 16 bits opcode ptr reg is b15 */
 | |
| #define TIC6X_FLAG_INSN16_B15PTR     0x00800000
 | |
| /* 16 bits opcode memory access modes */
 | |
| #define TIC6X_INSN16_MEM_MODE(n)           ((n) << 16)
 | |
| #define TIC6X_INSN16_MEM_MODE_VAL(n) (((n) & 0x000F0000) >> 16)
 | |
| #define TIC6X_MEM_MODE_NEGATIVE      0
 | |
| #define TIC6X_MEM_MODE_POSITIVE      1
 | |
| #define TIC6X_MEM_MODE_REG_NEGATIVE  4
 | |
| #define TIC6X_MEM_MODE_REG_POSITIVE  5
 | |
| #define TIC6X_MEM_MODE_PREDECR       8
 | |
| #define TIC6X_MEM_MODE_PREINCR       9
 | |
| #define TIC6X_MEM_MODE_POSTDECR      10
 | |
| #define TIC6X_MEM_MODE_POSTINCR      11
 | |
| 
 | |
| #define TIC6X_FLAG_INSN16_MEM_MODE(mode) TIC6X_INSN16_MEM_MODE(TIC6X_MEM_MODE_##mode)
 | |
| 
 | |
| #define TIC6X_NUM_PREFER	2
 | |
| 
 | |
| /* Maximum number of fixed fields for a particular opcode.  */
 | |
| #define TIC6X_MAX_FIXED_FIELDS 4
 | |
| 
 | |
| /* Maximum number of operands in the opcode table for a particular
 | |
|    opcode.  */
 | |
| #define TIC6X_MAX_OPERANDS 4
 | |
| 
 | |
| /* Maximum number of operands in the source code for a particular
 | |
|    opcode (different from the number in the opcode table for SPMASK
 | |
|    and SPMASKR).  */
 | |
| #define TIC6X_MAX_SOURCE_OPERANDS 8
 | |
| 
 | |
| /* Maximum number of variable fields for a particular opcode.  */
 | |
| #define TIC6X_MAX_VAR_FIELDS 7
 | |
| 
 | |
| /* Which functional units an opcode uses.  This only describes the
 | |
|    basic choice of D, L, M, S or no functional unit; other fields are
 | |
|    used to describe further restrictions (instructions only operating
 | |
|    on one side), use of cross paths and load/store instructions using
 | |
|    one side for the address and the other side for the source or
 | |
|    destination register.  */
 | |
| typedef enum
 | |
|   {
 | |
|     tic6x_func_unit_d,
 | |
|     tic6x_func_unit_l,
 | |
|     tic6x_func_unit_m,
 | |
|     tic6x_func_unit_s,
 | |
|     tic6x_func_unit_nfu
 | |
|   } tic6x_func_unit_base;
 | |
| 
 | |
| /* Possible forms of source operand.  */
 | |
| typedef enum
 | |
|   {
 | |
|     /* An assembly-time constant.  */
 | |
|     tic6x_operand_asm_const,
 | |
|     /* A link-time constant.  */
 | |
|     tic6x_operand_link_const,
 | |
|     /* A register, from the same side as the functional unit
 | |
|        selected.  */
 | |
|     tic6x_operand_reg,
 | |
|     /* A register, from the same side as the functional unit
 | |
|        selected that ignore RS header bit */
 | |
|     tic6x_operand_reg_nors,
 | |
|     /* A register, from the b side */
 | |
|     tic6x_operand_reg_bside,
 | |
|     /* A register, from the b side and from the low register set */
 | |
|     tic6x_operand_reg_bside_nors,
 | |
|     /* A register, that is from the other side if a cross path is
 | |
|        used.  */
 | |
|     tic6x_operand_xreg,
 | |
|     /* A register, that is from the side of the data path
 | |
|        selected.  */
 | |
|     tic6x_operand_dreg,
 | |
|     /* An address register usable with 15-bit offsets (B14 or B15).
 | |
|        This is from the same side as the functional unit if a cross
 | |
|        path is not used, and the other side if a cross path is
 | |
|        used.  */
 | |
|     tic6x_operand_areg,
 | |
|     /* The B15 register */
 | |
|     tic6x_operand_b15reg,
 | |
|     /* A register coded as an offset from either A16 or B16 depending
 | |
|        on the value of the t bit. */
 | |
|     tic6x_operand_treg,
 | |
|     /* A register (A0 or B0), from the same side as the
 | |
|        functional unit selected.  */
 | |
|     tic6x_operand_zreg,
 | |
|     /* A return address register (A3 or B3), from the same side as the
 | |
|        functional unit selected.  */
 | |
|     tic6x_operand_retreg,
 | |
|     /* A register pair, from the same side as the functional unit
 | |
|        selected.  */
 | |
|     tic6x_operand_regpair,
 | |
|     /* A register pair, that is from the other side if a cross path is
 | |
|        used.  */
 | |
|     tic6x_operand_xregpair,
 | |
|     /* A register pair, from the side of the data path selected.  */
 | |
|     tic6x_operand_dregpair,
 | |
|     /* A register pair coded as an offset from either A16 or B16 depending
 | |
|        on the value of the t bit. */
 | |
|     tic6x_operand_tregpair,
 | |
|     /* The literal string "irp" (case-insensitive).  */
 | |
|     tic6x_operand_irp,
 | |
|     /* The literal string "nrp" (case-insensitive).  */
 | |
|     tic6x_operand_nrp,
 | |
|     /* The literal string "ilc" (case-insensitive).  */
 | |
| 	tic6x_operand_ilc,
 | |
|     /* A control register.  */
 | |
|     tic6x_operand_ctrl,
 | |
|     /* A memory reference (base and offset registers from the side of
 | |
|        the functional unit selected), using either unsigned 5-bit
 | |
|        constant or register offset, if any offset; register offsets
 | |
|        cannot use unscaled () syntax.  */
 | |
|     tic6x_operand_mem_short,
 | |
|     /* A memory reference (base and offset registers from the side of
 | |
|        the functional unit selected), using either unsigned 5-bit
 | |
|        constant or register offset, if any offset; register offsets
 | |
|        can use unscaled () syntax (for LDNDW and STNDW).  */
 | |
|     tic6x_operand_mem_ndw,
 | |
|     /* A memory reference using 15-bit link-time constant offset
 | |
|        relative to B14 or B15.  */
 | |
|     tic6x_operand_mem_long,
 | |
|     /* A memory reference that only dereferences a register with no
 | |
|        further adjustments (*REG), that register being from the side
 | |
|        of the functional unit selected.  */
 | |
|     tic6x_operand_mem_deref,
 | |
|     /* A functional unit name or a list thereof (for SPMASK and
 | |
|        SPMASKR).  */
 | |
|     tic6x_operand_func_unit,
 | |
|     /* Hardwired constant '5' in Sbu8 Scs10 and Sbu8c 16 bits
 | |
|        instruction formats - spru732j.pdf Appendix F.4 */
 | |
|     tic6x_operand_hw_const_minus_1,
 | |
|     tic6x_operand_hw_const_0,
 | |
|     tic6x_operand_hw_const_1,
 | |
|     tic6x_operand_hw_const_5,
 | |
|     tic6x_operand_hw_const_16,
 | |
|     tic6x_operand_hw_const_24,
 | |
|     tic6x_operand_hw_const_31
 | |
|   } tic6x_operand_form;
 | |
| 
 | |
| /* Whether something is, or can be, read or written.  */
 | |
| typedef enum
 | |
|   {
 | |
|     tic6x_rw_none,
 | |
|     tic6x_rw_read,
 | |
|     tic6x_rw_write,
 | |
|     tic6x_rw_read_write
 | |
|   } tic6x_rw;
 | |
| 
 | |
| /* Description of a source operand and how it is used.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The syntactic form of the operand.  */
 | |
|   tic6x_operand_form form;
 | |
| 
 | |
|   /* For non-constant operands, the size in bytes (1, 2, 4, 5 or
 | |
|      8).  Ignored for constant operands.  */
 | |
|   unsigned int size;
 | |
| 
 | |
|   /* Whether the operand is read, written or both.  In addition to the
 | |
|      operations described here, address registers are read on cycle 1
 | |
|      regardless of when the memory operand is read or written, and may
 | |
|      be modified as described by the addressing mode, and control
 | |
|      registers may be implicitly read by some instructions.  There are
 | |
|      also some special cases not fully described by this
 | |
|      structure.
 | |
| 
 | |
|      - For mpydp, the low part of src2 is read on cycles 1 and 3 but
 | |
|        not 2, and the high part on cycles 2 and 4 but not 3.
 | |
| 
 | |
|      - The swap2 pseudo-operation maps to packlh2, reading the first
 | |
|        operand of swap2 twice.  */
 | |
|   tic6x_rw rw;
 | |
| 
 | |
|   /* The first and last cycles (1 for E1, etc.) at which the operand,
 | |
|      or the low part for two-register operands, is read or
 | |
|      written.  */
 | |
|   unsigned short low_first;
 | |
|   unsigned short low_last;
 | |
| 
 | |
|   /* Likewise, for the high part.  */
 | |
|   unsigned short high_first;
 | |
|   unsigned short high_last;
 | |
| } tic6x_operand_info;
 | |
| 
 | |
| /* Ways of converting an operand or functional unit specifier to a
 | |
|    field value.  */
 | |
| typedef enum
 | |
|   {
 | |
|     /* Store an unsigned assembly-time constant (which must fit) in
 | |
|        the field.  */
 | |
|     tic6x_coding_ucst,
 | |
|     /* Store a signed constant (which must fit) in the field.  This
 | |
|        may be used both for assembly-time constants and for link-time
 | |
|        constants.  */
 | |
|     tic6x_coding_scst,
 | |
|     /* Subtract one from an unsigned assembly-time constant (which
 | |
|        must be strictly positive before the subtraction) and store the
 | |
|        value (which must fit) in the field.  */
 | |
|     tic6x_coding_ucst_minus_one,
 | |
|     /* Negate a signed assembly-time constant, and store the result of
 | |
|        negation (which must fit) in the field.  Used only for
 | |
|        pseudo-operations.  */
 | |
|     tic6x_coding_scst_negate,
 | |
|     /* Store an unsigned link-time constant, implicitly DP-relative
 | |
|        and counting in bytes, in the field.  For expression operands,
 | |
|        assembly-time constants are encoded as-is.  For memory
 | |
|        reference operands, the offset is encoded as-is if [] syntax is
 | |
|        used and shifted if () is used.  */
 | |
|     tic6x_coding_ulcst_dpr_byte,
 | |
|     /* Store an unsigned link-time constant, implicitly DP-relative
 | |
|        and counting in half-words, in the field.  For expression
 | |
|        operands, assembly-time constants are encoded as-is.  For
 | |
|        memory reference operands, the offset is encoded as-is if []
 | |
|        syntax is used and shifted if () is used.  */
 | |
|     tic6x_coding_ulcst_dpr_half,
 | |
|     /* Store an unsigned link-time constant, implicitly DP-relative
 | |
|        and counting in words, in the field.  For expression operands,
 | |
|        assembly-time constants are encoded as-is.  For memory
 | |
|        reference operands, the offset is encoded as-is if [] syntax is
 | |
|        used and shifted if () is used.  */
 | |
|     tic6x_coding_ulcst_dpr_word,
 | |
|     /* Store the low 16 bits of a link-time constant in the field;
 | |
|        considered unsigned for disassembly.  */
 | |
|     tic6x_coding_lcst_low16,
 | |
|     /* Store the high 16 bits of a link-time constant in the field;
 | |
|        considered unsigned for disassembly.  */
 | |
|     tic6x_coding_lcst_high16,
 | |
|     /* Store a signed PC-relative value (address of label minus
 | |
|        address of fetch packet containing the current instruction,
 | |
|        counted in words) in the field.  */
 | |
|     tic6x_coding_pcrel,
 | |
|     /* Likewise, but counting in half-words if in a header-based fetch
 | |
|        packet.  */
 | |
|     tic6x_coding_pcrel_half,
 | |
|     /* Store an unsigned PC-relative value used in compact insn */
 | |
|     tic6x_coding_pcrel_half_unsigned,
 | |
|     /* Encode the register number (even number for a register pair) in
 | |
|        the field.  When applied to a memory reference, encode the base
 | |
|        register.  */
 | |
|     tic6x_coding_reg,
 | |
|     /* Encode the register-pair's lsb (even register) for instructions
 | |
|        that use src1 as port for loading lsb of double-precision
 | |
|        operand value (absdp, dpint, dpsp, dptrunc, rcpdp, rsqrdp).  */
 | |
|     tic6x_coding_regpair_lsb,
 | |
|     /* Encode the register-pair's msb (odd register), see above.  */ 
 | |
|     tic6x_coding_regpair_msb,
 | |
|     /* Store 0 for register B14, 1 for register B15.  When applied to
 | |
|        a memory reference, encode the base register.  */
 | |
|     tic6x_coding_areg,
 | |
|     /* Compact instruction offset base register */
 | |
|     tic6x_coding_reg_ptr,
 | |
|     /* Store the low part of a control register address.  */
 | |
|     tic6x_coding_crlo,
 | |
|     /* Store the high part of a control register address.  */
 | |
|     tic6x_coding_crhi,
 | |
|     /* Encode the even register number for a register pair, shifted
 | |
|        right by one bit.  */
 | |
|     tic6x_coding_reg_shift,
 | |
|     /* Store either the offset register or the 5-bit unsigned offset
 | |
|        for a memory reference.  If an offset uses the unscaled ()
 | |
|        form, which is only permitted with constants, it is scaled
 | |
|        according to the access size of the operand before being
 | |
|        stored.  */
 | |
|     tic6x_coding_mem_offset,
 | |
|     /* Store either the offset register or the 5-bit unsigned offset
 | |
|        for a memory reference, but with no scaling applied to the
 | |
|        offset (for nonaligned doubleword operations).  */
 | |
|     tic6x_coding_mem_offset_noscale,
 | |
|     /* Store the addressing mode for a memory reference.  */
 | |
|     tic6x_coding_mem_mode,
 | |
|     /* Store whether a memory reference is scaled.  */
 | |
|     tic6x_coding_scaled,
 | |
|     /* Store the stage in an SPKERNEL instruction in the upper part of
 | |
|        the field.  */
 | |
|     tic6x_coding_fstg,
 | |
|     /* Store the cycle in an SPKERNEL instruction in the lower part of
 | |
|        the field.  */
 | |
|     tic6x_coding_fcyc,
 | |
|     /* Store the mask bits for functional units in the field in an
 | |
|        SPMASK or SPMASKR instruction.  */
 | |
|     tic6x_coding_spmask,
 | |
|     /* Store the number of a register that is unused, or minimally
 | |
|        used, in this execute packet.  The number must be the same for
 | |
|        all uses of this coding in a single instruction, but may be
 | |
|        different for different instructions in the execute packet.
 | |
|        This is for the "zero" pseudo-operation.  This is not safe when
 | |
|        reads may occur from instructions in previous execute packets;
 | |
|        in such cases the programmer or compiler should use explicit
 | |
|        "sub" instructions for those cases of "zero" that cannot be
 | |
|        implemented as "mvk" for the processor specified.  */
 | |
|     tic6x_coding_reg_unused,
 | |
|     /* Store 1 if the functional unit used is on side B, 0 for side
 | |
|        A.  */
 | |
|     tic6x_coding_fu,
 | |
|     /* Store 1 if the data path used (source register for store,
 | |
|        destination for load) is on side B, 0 for side A.  */
 | |
|     tic6x_coding_data_fu,
 | |
|     /* Store 1 if the cross path is being used, 0 otherwise.  */
 | |
|     tic6x_coding_xpath,
 | |
|     /* L3i constant coding */
 | |
|     tic6x_coding_scst_l3i,
 | |
|     /* S3i constant coding */
 | |
|     tic6x_coding_cst_s3i,
 | |
|     /* mem offset minus 1 */
 | |
|     tic6x_coding_mem_offset_minus_one,
 | |
|     /* non aligned mem offset minus 1 */
 | |
|     tic6x_coding_mem_offset_minus_one_noscale,
 | |
|     tic6x_coding_rside
 | |
|   } tic6x_coding_method;
 | |
| 
 | |
| /* How to generate the value of a particular field.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The name of the field.  */
 | |
|   tic6x_insn_field_id field_id;
 | |
| 
 | |
|   /* How it is encoded.  */
 | |
|   tic6x_coding_method coding_method;
 | |
| 
 | |
|   /* Source operand number, if any.  */
 | |
|   unsigned int operand_num;
 | |
| } tic6x_coding_field;
 | |
| 
 | |
| /* Types of instruction for pipeline purposes.  The type determines
 | |
|    functional unit and cross path latency (when the same functional
 | |
|    unit can be used by other instructions, when the same cross path
 | |
|    can be used by other instructions).  */
 | |
| typedef enum
 | |
|   {
 | |
|     tic6x_pipeline_nop,
 | |
|     tic6x_pipeline_1cycle,
 | |
|     tic6x_pipeline_1616_m,
 | |
|     tic6x_pipeline_store,
 | |
|     tic6x_pipeline_mul_ext,
 | |
|     tic6x_pipeline_load,
 | |
|     tic6x_pipeline_branch,
 | |
|     tic6x_pipeline_2cycle_dp,
 | |
|     tic6x_pipeline_4cycle,
 | |
|     tic6x_pipeline_intdp,
 | |
|     tic6x_pipeline_dpcmp,
 | |
|     tic6x_pipeline_addsubdp,
 | |
|     tic6x_pipeline_mpyi,
 | |
|     tic6x_pipeline_mpyid,
 | |
|     tic6x_pipeline_mpydp,
 | |
|     tic6x_pipeline_mpyspdp,
 | |
|     tic6x_pipeline_mpysp2dp
 | |
|   } tic6x_pipeline_type;
 | |
| 
 | |
| /* Description of a control register.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The name of the register.  */
 | |
|   const char *name;
 | |
| 
 | |
|   /* Which ISA variants include this control register.  */
 | |
|   unsigned short isa_variants;
 | |
| 
 | |
|   /* Whether it can be read, written or both (in supervisor mode).
 | |
|      Some registers use the same address, but different names, for
 | |
|      reading and writing.  */
 | |
|   tic6x_rw rw;
 | |
| 
 | |
|   /* crlo value for this register.  */
 | |
|   unsigned int crlo;
 | |
| 
 | |
|   /* Mask that, ANDed with the crhi value in the instruction, must be
 | |
|      0.  0 is always generated when generating code.  */
 | |
|   unsigned int crhi_mask;
 | |
| } tic6x_ctrl;
 | |
| 
 | |
| /* An index into the table of control registers.  */
 | |
| typedef enum
 | |
|   {
 | |
| #define CTRL(name, isa, rw, crlo, crhi_mask)	\
 | |
|     CONCAT2(tic6x_ctrl_,name),
 | |
| #include "tic6x-control-registers.h"
 | |
| #undef CTRL
 | |
|     tic6x_ctrl_max
 | |
|   } tic6x_ctrl_id;
 | |
| 
 | |
| /* The table itself.  */
 | |
| extern const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max];
 | |
| 
 | |
| /* An entry in the opcode table.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The name of the instruction.  */
 | |
|   const char *name;
 | |
| 
 | |
|   /* Functional unit used by this instruction (basic information).  */
 | |
|   tic6x_func_unit_base func_unit;
 | |
| 
 | |
|   /* The format of this instruction.  */
 | |
|   tic6x_insn_format_id format;
 | |
| 
 | |
|   /* The pipeline type of this instruction.  */
 | |
|   tic6x_pipeline_type type;
 | |
| 
 | |
|   /* Which ISA variants include this instruction.  */
 | |
|   unsigned short isa_variants;
 | |
| 
 | |
|   /* Flags for this instruction.  */
 | |
|   unsigned int flags;
 | |
| 
 | |
|   /* Number of fixed fields, or fields with restricted value ranges,
 | |
|      for this instruction.  */
 | |
|   unsigned int num_fixed_fields;
 | |
| 
 | |
|   /* Values of fields fixed for this instruction.  */
 | |
|   tic6x_fixed_field fixed_fields[TIC6X_MAX_FIXED_FIELDS];
 | |
| 
 | |
|   /* The number of operands in the source form of this
 | |
|      instruction.  */
 | |
|   unsigned int num_operands;
 | |
| 
 | |
|   /* Information about individual operands.  */
 | |
|   tic6x_operand_info operand_info[TIC6X_MAX_OPERANDS];
 | |
| 
 | |
|   /* The number of variable fields for this instruction with encoding
 | |
|      instructions explicitly given.  */
 | |
|   unsigned int num_variable_fields;
 | |
| 
 | |
|   /* How fields (other than ones with fixed value) are computed from
 | |
|      the source operands and functional unit specifiers.  In addition
 | |
|      to fields specified here:
 | |
| 
 | |
|      - creg, if present, is set from the predicate, along with z which
 | |
|        must be present if creg is present.
 | |
| 
 | |
|      - p, if present (on all non-compact instructions), is set from
 | |
|        the parallel bars.
 | |
|   */
 | |
|   tic6x_coding_field variable_fields[TIC6X_MAX_VAR_FIELDS];
 | |
| } tic6x_opcode;
 | |
| 
 | |
| /* An index into the table of opcodes.  */
 | |
| typedef enum
 | |
|   {
 | |
| #define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
 | |
|     CONCAT6(tic6x_opcode_,name,_,func_unit,_,format),
 | |
| #define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
 | |
|     CONCAT4(tic6x_opcode_,name,_,e),
 | |
| #define INSNU(name, func_unit, format, type, isa, flags, fixed, ops, var) \
 | |
|     CONCAT6(tic6x_opcode_,name,_,func_unit,_,format),
 | |
| #define INSNUE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
 | |
|     CONCAT6(tic6x_opcode_,name,_,func_unit,_,e),
 | |
| #include "tic6x-opcode-table.h"
 | |
| #undef INSN
 | |
| #undef INSNE
 | |
| #undef INSNU
 | |
| #undef INSNUE
 | |
|     tic6x_opcode_max
 | |
|   } tic6x_opcode_id;
 | |
| 
 | |
| /* The table itself.  */
 | |
| extern const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max];
 | |
| 
 | |
| /* A linked list of opcodes.  */
 | |
| typedef struct tic6x_opcode_list_tag
 | |
| {
 | |
|   tic6x_opcode_id id;
 | |
|   struct tic6x_opcode_list_tag *next;
 | |
| } tic6x_opcode_list;
 | |
| 
 | |
| /* The information from a fetch packet header.  */
 | |
| typedef struct
 | |
| {
 | |
|   /* The header itself.  */
 | |
|   unsigned int header;
 | |
| 
 | |
|   /* Whether each word uses compact instructions.  */
 | |
|   bfd_boolean word_compact[7];
 | |
| 
 | |
|   /* Whether loads are protected.  */
 | |
|   bfd_boolean prot;
 | |
| 
 | |
|   /* Whether instructions use the high register set.  */
 | |
|   bfd_boolean rs;
 | |
| 
 | |
|   /* Data size.  */
 | |
|   unsigned int dsz;
 | |
| 
 | |
|   /* Whether compact instructions in the S unit are decoded as
 | |
|      branches.  */
 | |
|   bfd_boolean br;
 | |
| 
 | |
|   /* Whether compact instructions saturate.  */
 | |
|   bfd_boolean sat;
 | |
| 
 | |
|   /* P-bits.  */
 | |
|   bfd_boolean p_bits[14];
 | |
| } tic6x_fetch_packet_header;
 | |
| 
 | |
| #endif /* OPCODE_TIC6X_H */
 |