Copyright 2010, 2011
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"
used in the architecture manuals. */
typedef enum
{
tic6x_field_baseR,
tic6x_field_creg,
tic6x_field_cst,
tic6x_field_csta,
tic6x_field_cstb,
tic6x_field_dst,
tic6x_field_fstgfcyc,
tic6x_field_h,
tic6x_field_mask,
tic6x_field_mode,
tic6x_field_offsetR,
tic6x_field_op,
tic6x_field_p,
tic6x_field_r,
tic6x_field_s,
tic6x_field_sc,
tic6x_field_src,
tic6x_field_src1,
tic6x_field_src2,
tic6x_field_srcdst,
tic6x_field_x,
tic6x_field_y,
tic6x_field_z
} tic6x_insn_field_id;
typedef struct
{
tic6x_insn_field_id field_id;
unsigned short low_pos;
unsigned short width;
} tic6x_insn_field;
#define TIC6X_MAX_INSN_FIELDS 11
typedef struct
{
unsigned int num_bits;
unsigned int cst_bits;
unsigned int mask;
unsigned int num_fields;
tic6x_insn_field fields[TIC6X_MAX_INSN_FIELDS];
} tic6x_insn_format;
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;
extern const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max];
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);
fixed, or constrained to be in a particular range, in a particular
opcode. */
typedef struct
{
tic6x_insn_field_id field_id;
unsigned int min_val;
unsigned int max_val;
} tic6x_fixed_field;
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
#define TIC6X_FLAG_MACRO 0x0001
#define TIC6X_FLAG_FIRST 0x0002
is only a multicycle NOP if n > 1). */
#define TIC6X_FLAG_MCNOP 0x0004
#define TIC6X_FLAG_NO_MCNOP 0x0008
#define TIC6X_FLAG_LOAD 0x0010
#define TIC6X_FLAG_STORE 0x0020
#define TIC6X_FLAG_UNALIGNED 0x0040
#define TIC6X_FLAG_SIDE_B_ONLY 0x0080
#define TIC6X_FLAG_SIDE_T2_ONLY 0x0100
#define TIC6X_FLAG_NO_CROSS 0x0200
#define TIC6X_FLAG_CALL 0x0400
#define TIC6X_FLAG_RETURN 0x0800
#define TIC6X_FLAG_SPLOOP 0x1000
#define TIC6X_FLAG_SPKERNEL 0x2000
although described as having one parameter, the number may be 0 to
8. */
#define TIC6X_FLAG_SPMASK 0x4000
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)
#define TIC6X_NUM_PREFER 2
#define TIC6X_MAX_FIXED_FIELDS 4
opcode. */
#define TIC6X_MAX_OPERANDS 4
opcode (different from the number in the opcode table for SPMASK
and SPMASKR). */
#define TIC6X_MAX_SOURCE_OPERANDS 8
#define TIC6X_MAX_VAR_FIELDS 7
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;
typedef enum
{
tic6x_operand_asm_const,
tic6x_operand_link_const,
selected. */
tic6x_operand_reg,
used. */
tic6x_operand_xreg,
selected. */
tic6x_operand_dreg,
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,
functional unit selected. */
tic6x_operand_retreg,
selected. */
tic6x_operand_regpair,
used. */
tic6x_operand_xregpair,
tic6x_operand_dregpair,
tic6x_operand_irp,
tic6x_operand_nrp,
tic6x_operand_ctrl,
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,
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,
relative to B14 or B15. */
tic6x_operand_mem_long,
further adjustments (*REG), that register being from the side
of the functional unit selected. */
tic6x_operand_mem_deref,
SPMASKR). */
tic6x_operand_func_unit
} tic6x_operand_form;
typedef enum
{
tic6x_rw_none,
tic6x_rw_read,
tic6x_rw_write,
tic6x_rw_read_write
} tic6x_rw;
typedef struct
{
tic6x_operand_form form;
8). Ignored for constant operands. */
unsigned int size;
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;
or the low part for two-register operands, is read or
written. */
unsigned short low_first;
unsigned short low_last;
unsigned short high_first;
unsigned short high_last;
} tic6x_operand_info;
field value. */
typedef enum
{
the field. */
tic6x_coding_ucst,
may be used both for assembly-time constants and for link-time
constants. */
tic6x_coding_scst,
must be strictly positive before the subtraction) and store the
value (which must fit) in the field. */
tic6x_coding_ucst_minus_one,
negation (which must fit) in the field. Used only for
pseudo-operations. */
tic6x_coding_scst_negate,
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,
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,
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,
considered unsigned for disassembly. */
tic6x_coding_lcst_low16,
considered unsigned for disassembly. */
tic6x_coding_lcst_high16,
address of fetch packet containing the current instruction,
counted in words) in the field. */
tic6x_coding_pcrel,
packet. */
tic6x_coding_pcrel_half,
the field. When applied to a memory reference, encode the base
register. */
tic6x_coding_reg,
a memory reference, encode the base register. */
tic6x_coding_areg,
tic6x_coding_crlo,
tic6x_coding_crhi,
right by one bit. */
tic6x_coding_reg_shift,
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,
for a memory reference, but with no scaling applied to the
offset (for nonaligned doubleword operations). */
tic6x_coding_mem_offset_noscale,
tic6x_coding_mem_mode,
tic6x_coding_scaled,
the field. */
tic6x_coding_fstg,
the field. */
tic6x_coding_fcyc,
SPMASK or SPMASKR instruction. */
tic6x_coding_spmask,
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,
A. */
tic6x_coding_fu,
destination for load) is on side B, 0 for side A. */
tic6x_coding_data_fu,
tic6x_coding_xpath
} tic6x_coding_method;
typedef struct
{
tic6x_insn_field_id field_id;
tic6x_coding_method coding_method;
unsigned int operand_num;
} tic6x_coding_field;
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;
typedef struct
{
const char *name;
unsigned short isa_variants;
Some registers use the same address, but different names, for
reading and writing. */
tic6x_rw rw;
unsigned int crlo;
0. 0 is always generated when generating code. */
unsigned int crhi_mask;
} tic6x_ctrl;
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;
extern const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max];
typedef struct
{
const char *name;
tic6x_func_unit_base func_unit;
tic6x_insn_format_id format;
tic6x_pipeline_type type;
unsigned short isa_variants;
unsigned short flags;
for this instruction. */
unsigned int num_fixed_fields;
tic6x_fixed_field fixed_fields[TIC6X_MAX_FIXED_FIELDS];
instruction. */
unsigned int num_operands;
tic6x_operand_info operand_info[TIC6X_MAX_OPERANDS];
instructions explicitly given. */
unsigned int num_variable_fields;
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;
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),
#include "tic6x-opcode-table.h"
#undef INSN
#undef INSNE
tic6x_opcode_max
} tic6x_opcode_id;
extern const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max];
typedef struct tic6x_opcode_list_tag
{
tic6x_opcode_id id;
struct tic6x_opcode_list_tag *next;
} tic6x_opcode_list;
typedef struct
{
unsigned int header;
bfd_boolean word_compact[7];
bfd_boolean prot;
bfd_boolean rs;
unsigned int dsz;
branches. */
bfd_boolean br;
bfd_boolean sat;
bfd_boolean p_bits[14];
} tic6x_fetch_packet_header;
#endif