* Makefile.am (ALL_MACHINES): Add cpu-tic6x.lo.
	(ALL_MACHINES_CFILES): Add cpu-tic6x.c.
	(BFD32_BACKENDS): Add elf32-tic6x.lo.
	(BFD32_BACKENDS_CFILES): Add elf32-tic6x.c.
	* Makefile.in: Regenerate.
	* archures.c (bfd_arch_tic6x, bfd_tic6x_arch): New.
	(bfd_archures_list): Update.
	* config.bfd (tic6x-*-elf): New.
	* configure.in (bfd_elf32_tic6x_be_vec, bfd_elf32_tic6x_le_vec):
	New.
	* configure: Regenerate.
	* cpu-tic6x.c, elf32-tic6x.c: New.
	* reloc.c (BFD_RELOC_C6000_PCR_S21, BFD_RELOC_C6000_PCR_S12,
	BFD_RELOC_C6000_PCR_S10, BFD_RELOC_C6000_PCR_S7,
	BFD_RELOC_C6000_ABS_S16, BFD_RELOC_C6000_ABS_L16,
	BFD_RELOC_C6000_ABS_H16, BFD_RELOC_C6000_SBR_U15_B,
	BFD_RELOC_C6000_SBR_U15_H, BFD_RELOC_C6000_SBR_U15_W,
	BFD_RELOC_C6000_SBR_S16, BFD_RELOC_C6000_SBR_L16_B,
	BFD_RELOC_C6000_SBR_L16_H, BFD_RELOC_C6000_SBR_L16_W,
	BFD_RELOC_C6000_SBR_H16_B, BFD_RELOC_C6000_SBR_H16_H,
	BFD_RELOC_C6000_SBR_H16_W, BFD_RELOC_C6000_SBR_GOT_U15_W,
	BFD_RELOC_C6000_SBR_GOT_L16_W, BFD_RELOC_C6000_SBR_GOT_H16_W,
	BFD_RELOC_C6000_DSBT_INDEX, BFD_RELOC_C6000_PREL31,
	BFD_RELOC_C6000_COPY, BFD_RELOC_C6000_ALIGN,
	BFD_RELOC_C6000_FPHEAD, BFD_RELOC_C6000_NOCMP): New.
	* targets.c (bfd_elf32_tic6x_be_vec, bfd_elf32_tic6x_le_vec): New.
	(_bfd_target_vector): Update.
	* bfd-in2.h, libbfd.h: Regenerate.

binutils:
	* MAINTAINERS: Add self as TI C6X maintainer.
	* NEWS: Add news entry for TI C6X support.
	* readelf.c: Include elf/tic6x.h.
	(guess_is_rela): Handle EM_TI_C6000.
	(dump_relocations): Likewise.
	(get_tic6x_dynamic_type): New.
	(get_dynamic_type): Call it.
	(get_machine_flags): Handle EF_C6000_REL.
	(get_osabi_name): Handle machine-specific values only for relevant
	machines.  Handle C6X values.
	(get_tic6x_segment_type): New.
	(get_segment_type): Call it.
	(get_tic6x_section_type_name): New.
	(get_section_type_name): Call it.
	(is_32bit_abs_reloc, is_16bit_abs_reloc, is_none_reloc): Handle
	EM_TI_C6000.

gas:
	* Makefile.am (TARGET_CPU_CFILES): Add config/tc-tic6x.c.
	(TARGET_CPU_HFILES): Add config/tc-tic6x.h.
	* Makefile.in: Regenerate.
	* NEWS: Add news entry for TI C6X support.
	* app.c (do_scrub_chars): Handle "||^" for TI C6X.  Handle
	TC_PREDICATE_START_CHAR and TC_PREDICATE_END_CHAR.  Keep spaces in
	operands if TC_KEEP_OPERAND_SPACES.
	* configure.tgt (tic6x-*-*): New.
	* config/tc-ia64.h (TC_PREDICATE_START_CHAR,
	TC_PREDICATE_END_CHAR): Define.
	* config/tc-tic6x.c, config/tc-tic6x.h: New.
	* doc/Makefile.am (CPU_DOCS): Add c-tic6x.texi.
	* doc/Makefile.in: Regenerate.
	* doc/all.texi (TIC6X): Define.
	* doc/as.texinfo: Add TI C6X documentation.  Include c-tic6x.texi.
	* doc/c-tic6x.texi: New.

gas/testsuite:
	* gas/tic6x: New directory and testcases.

include:
	* dis-asm.h (print_insn_tic6x): Declare.

include/elf:
	* common.h (ELFOSABI_C6000_ELFABI, ELFOSABI_C6000_LINUX): Define.
	* tic6x.h: New.

include/opcode:
	* tic6x-control-registers.h, tic6x-insn-formats.h,
	tic6x-opcode-table.h, tic6x.h: New.

ld:
	* Makefile.am (ALL_EMULATIONS): Add eelf32_tic6x_be.o and
	eelf32_tic6x_le.o.
	(eelf32_tic6x_be.c, eelf32_tic6x_le.c): New.
	* NEWS: Add news entry for TI C6X support.
	* configure.tgt (tic6x-*-*): New.
	* emulparams/elf32_tic6x_be.sh, emulparams/elf32_tic6x_le.sh: New.

ld/testsuite:
	* ld-elf/flags1.d, ld-elf/merge.d: XFAIL for tic6x-*-*.
	* ld-elf/sec-to-seg.exp: Set B_test_same_seg to 0 for tic6x-*-*.
	* ld-tic6x: New directory and testcases.

opcodes:
	* Makefile.am (TARGET_LIBOPCODES_CFILES): Add tic6x-dis.c.
	* Makefile.in: Regenerate.
	* configure.in (bfd_tic6x_arch): New.
	* configure: Regenerate.
	* disassemble.c (ARCH_tic6x): Define if ARCH_all.
	(disassembler): Handle TI C6X.
	* tic6x-dis.c: New.
This commit is contained in:
Joseph Myers 2010-03-25 21:12:32 +00:00
parent ca8d80165f
commit 86a58929ba
10 changed files with 3561 additions and 1 deletions

View File

@ -1,3 +1,7 @@
2010-03-25 Joseph Myers <joseph@codesourcery.com>
* dis-asm.h (print_insn_tic6x): Declare.
2010-03-23 Joseph Myers <joseph@codesourcery.com>
* symcat.h (CONCAT5, CONCAT6, XCONCAT5, XCONCAT6): Define.

View File

@ -1,6 +1,6 @@
/* Interface between the opcode library and its callers.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@ -286,6 +286,7 @@ extern int print_insn_spu (bfd_vma, disassemble_info *);
extern int print_insn_tic30 (bfd_vma, disassemble_info *);
extern int print_insn_tic4x (bfd_vma, disassemble_info *);
extern int print_insn_tic54x (bfd_vma, disassemble_info *);
extern int print_insn_tic6x (bfd_vma, disassemble_info *);
extern int print_insn_tic80 (bfd_vma, disassemble_info *);
extern int print_insn_v850 (bfd_vma, disassemble_info *);
extern int print_insn_vax (bfd_vma, disassemble_info *);

View File

@ -1,3 +1,8 @@
2010-03-25 Joseph Myers <joseph@codesourcery.com>
* common.h (ELFOSABI_C6000_ELFABI, ELFOSABI_C6000_LINUX): Define.
* tic6x.h: New.
2010-03-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* common.h (VER_FLG_*): Document.

View File

@ -75,6 +75,8 @@
#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
#define ELFOSABI_AROS 15 /* AROS */
#define ELFOSABI_FENIXOS 16 /* FenixOS */
#define ELFOSABI_C6000_ELFABI 64 /* Bare-metal TMS320C6000 */
#define ELFOSABI_C6000_LINUX 65 /* Linux TMS320C6000 */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */

128
include/elf/tic6x.h Normal file
View File

@ -0,0 +1,128 @@
/* TI C6X ELF support for BFD.
Copyright 2010
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
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 _ELF_TIC6X_H
#define _ELF_TIC6X_H
#include "elf/reloc-macros.h"
/* Relocation types. */
START_RELOC_NUMBERS (elf_tic6x_reloc_type)
RELOC_NUMBER (R_C6000_NONE, 0)
RELOC_NUMBER (R_C6000_ABS32, 1)
RELOC_NUMBER (R_C6000_ABS16, 2)
RELOC_NUMBER (R_C6000_ABS8, 3)
RELOC_NUMBER (R_C6000_PCR_S21, 4)
RELOC_NUMBER (R_C6000_PCR_S12, 5)
RELOC_NUMBER (R_C6000_PCR_S10, 6)
RELOC_NUMBER (R_C6000_PCR_S7, 7)
RELOC_NUMBER (R_C6000_ABS_S16, 8)
RELOC_NUMBER (R_C6000_ABS_L16, 9)
RELOC_NUMBER (R_C6000_ABS_H16, 10)
RELOC_NUMBER (R_C6000_SBR_U15_B, 11)
RELOC_NUMBER (R_C6000_SBR_U15_H, 12)
RELOC_NUMBER (R_C6000_SBR_U15_W, 13)
RELOC_NUMBER (R_C6000_SBR_S16, 14)
RELOC_NUMBER (R_C6000_SBR_L16_B, 15)
RELOC_NUMBER (R_C6000_SBR_L16_H, 16)
RELOC_NUMBER (R_C6000_SBR_L16_W, 17)
RELOC_NUMBER (R_C6000_SBR_H16_B, 18)
RELOC_NUMBER (R_C6000_SBR_H16_H, 19)
RELOC_NUMBER (R_C6000_SBR_H16_W, 20)
RELOC_NUMBER (R_C6000_SBR_GOT_U15_W, 21)
RELOC_NUMBER (R_C6000_SBR_GOT_L16_W, 22)
RELOC_NUMBER (R_C6000_SBR_GOT_H16_W, 23)
RELOC_NUMBER (R_C6000_DSBT_INDEX, 24)
RELOC_NUMBER (R_C6000_PREL31, 25)
RELOC_NUMBER (R_C6000_COPY, 26)
RELOC_NUMBER (R_C6000_ALIGN, 253)
RELOC_NUMBER (R_C6000_FPHEAD, 254)
RELOC_NUMBER (R_C6000_NOCMP, 255)
END_RELOC_NUMBERS (R_TIC6X_max)
/* Processor-specific flags. */
/* File contains static relocation information. */
#define EF_C6000_REL 0x1
/* Processor-specific section types. */
/* Unwind function table for stack unwinding. */
#define SHT_C6000_UNWIND 0x70000001
/* DLL dynamic linking pre-emption map. */
#define SHT_C6000_PREEMPTMAP 0x70000002
/* Object file compatibility attributes. */
#define SHT_C6000_ATTRIBUTES 0x70000003
/* Intermediate code for link-time optimization. */
#define SHT_TI_ICODE 0x7F000000
/* Symbolic cross reference information. */
#define SHT_TI_XREF 0x7F000001
/* Reserved. */
#define SHT_TI_HANDLER 0x7F000002
/* Compressed data for initializing C variables. */
#define SHT_TI_INITINFO 0x7F000003
/* Extended program header attributes. */
#define SHT_TI_PHATTRS 0x7F000004
/* Processor-specific segment types. */
/* Extended Segment Attributes. */
#define PT_C6000_PHATTR 0x70000000
/* Processor-specific dynamic tags. */
/* Undocumented. */
#define DT_C6000_GSYM_OFFSET 0x6000000D
/* Undocumented. */
#define DT_C6000_GSTR_OFFSET 0x6000000F
/* Statically linked base address of data segment. */
#define DT_C6000_DSBT_BASE 0x70000000
/* Number of entries in this module's DSBT. */
#define DT_C6000_DSBT_SIZE 0x70000001
/* Undocumented. */
#define DT_C6000_PREEMPTMAP 0x70000002
/* The hard-coded DSBT index for this module, if any. */
#define DT_C6000_DSBT_INDEX 0x70000003
/* Extended program header attributes. */
/* Terminate a segment. */
#define PHA_NULL 0x0
/* Segment's address bound to the final address. */
#define PHA_BOUND 0x1
/* Segment cannot be further relocated. */
#define PHA_READONLY 0x2
#endif /* _ELF_TIC6X_H */

View File

@ -1,3 +1,8 @@
2010-03-25 Joseph Myers <joseph@codesourcery.com>
* tic6x-control-registers.h, tic6x-insn-formats.h,
tic6x-opcode-table.h, tic6x.h: New.
2010-02-25 Wu Zhangjin <wuzhangjin@gmail.com>
* mips.h: (LOONGSON2F_NOP_INSN): New macro.

View File

@ -0,0 +1,54 @@
/* TI C6X control register information.
Copyright 2010
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. */
/* Define the CTRL macro before including this file; it takes as
arguments the fields from tic6x_ctrl (defined in tic6x.h). The
control register name is given as an identifier; the isa_variants
field without the leading TIC6X_INSN_; the rw field without the
leading tic6x_rw_. */
CTRL(amr, C62X, read_write, 0x0, 0x10)
CTRL(csr, C62X, read_write, 0x1, 0x10)
CTRL(dnum, C64XP, read, 0x11, 0x1f)
CTRL(ecr, C64XP, write, 0x1d, 0x1f)
CTRL(efr, C64XP, read, 0x1d, 0x1f)
CTRL(fadcr, C67X, read_write, 0x12, 0x1f)
CTRL(faucr, C67X, read_write, 0x13, 0x1f)
CTRL(fmcr, C67X, read_write, 0x14, 0x1f)
CTRL(gfpgfr, C64X, read_write, 0x18, 0x1f)
CTRL(gplya, C64XP, read_write, 0x16, 0x1f)
CTRL(gplyb, C64XP, read_write, 0x17, 0x1f)
CTRL(icr, C62X, write, 0x3, 0x10)
CTRL(ier, C62X, read_write, 0x4, 0x10)
CTRL(ierr, C64XP, read_write, 0x1f, 0x1f)
CTRL(ifr, C62X, read, 0x2, 0x1d)
CTRL(ilc, C64XP, read_write, 0xd, 0x1f)
CTRL(irp, C62X, read_write, 0x6, 0x10)
CTRL(isr, C62X, write, 0x2, 0x10)
CTRL(istp, C62X, read_write, 0x5, 0x10)
CTRL(itsr, C64XP, read_write, 0x1b, 0x1f)
CTRL(nrp, C62X, read_write, 0x7, 0x10)
CTRL(ntsr, C64XP, read_write, 0x1c, 0x1f)
CTRL(pce1, C62X, read, 0x10, 0xf)
CTRL(rep, C64XP, read_write, 0xf, 0x1f)
CTRL(rilc, C64XP, read_write, 0xe, 0x1f)
CTRL(ssr, C64XP, read_write, 0x15, 0x1f)
CTRL(tsch, C64XP, read, 0xb, 0x1f)
CTRL(tscl, C64XP, read, 0xa, 0x1f)
CTRL(tsr, C64XP, read_write, 0x1a, 0x1f)

View File

@ -0,0 +1,198 @@
/* TI C6X instruction format information.
Copyright 2010
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. */
/* Define the FMT macro before including this file; it takes a name
and the fields from tic6x_insn_format (defined in tic6x.h). */
#define FLD(name, pos, width) { CONCAT2(tic6x_field_,name), (pos), (width) }
#define CFLDS FLD(p, 0, 1), FLD(creg, 29, 3), FLD(z, 28, 1)
#define CFLDS2(a, b) 5, { CFLDS, a, b }
#define CFLDS3(a, b, c) 6, { CFLDS, a, b, c }
#define CFLDS4(a, b, c, d) 7, { CFLDS, a, b, c, d }
#define CFLDS5(a, b, c, d, e) 8, { CFLDS, a, b, c, d, e }
#define CFLDS6(a, b, c, d, e, f) 9, { CFLDS, a, b, c, d, e, f }
#define CFLDS7(a, b, c, d, e, f, g) 10, { CFLDS, a, b, c, d, e, f, g }
#define CFLDS8(a, b, c, d, e, f, g, h) 11, { CFLDS, a, b, c, d, e, f, g, h }
#define NFLDS FLD(p, 0, 1)
#define NFLDS1(a) 2, { NFLDS, a }
#define NFLDS2(a, b) 3, { NFLDS, a, b }
#define NFLDS3(a, b, c) 4, { NFLDS, a, b, c }
#define NFLDS5(a, b, c, d, e) 6, { NFLDS, a, b, c, d, e }
#define NFLDS6(a, b, c, d, e, f) 7, { NFLDS, a, b, c, d, e, f }
#define NFLDS7(a, b, c, d, e, f, g) 8, { NFLDS, a, b, c, d, e, f, g }
/* These are in the order from SPRUFE8, appendices C-H. */
/* Appendix C 32-bit formats. */
FMT(d_1_or_2_src, 32, 0x40, 0x7c,
CFLDS5(FLD(s, 1, 1), FLD(op, 7, 6), FLD(src1, 13, 5), FLD(src2, 18, 5),
FLD(dst, 23, 5)))
FMT(d_ext_1_or_2_src, 32, 0x830, 0xc3c,
CFLDS6(FLD(s, 1, 1), FLD(op, 6, 4), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
FMT(d_load_store, 32, 0x4, 0xc,
CFLDS8(FLD(s, 1, 1), FLD(op, 4, 3), FLD(y, 7, 1), FLD(r, 8, 1),
FLD(mode, 9, 4), FLD(offsetR, 13, 5), FLD(baseR, 18, 5),
FLD(srcdst, 23, 5)))
/* The nonaligned loads and stores have the formats shown in the
individual instruction descriptions; the appendix is incorrect. */
FMT(d_load_nonaligned, 32, 0x124, 0x17c,
CFLDS7(FLD(s, 1, 1), FLD(y, 7, 1), FLD(mode, 9, 4), FLD(offsetR, 13, 5),
FLD(baseR, 18, 5), FLD(sc, 23, 1), FLD(dst, 24, 4)))
FMT(d_store_nonaligned, 32, 0x174, 0x17c,
CFLDS7(FLD(s, 1, 1), FLD(y, 7, 1), FLD(mode, 9, 4), FLD(offsetR, 13, 5),
FLD(baseR, 18, 5), FLD(sc, 23, 1), FLD(src, 24, 4)))
FMT(d_load_store_long, 32, 0xc, 0xc,
CFLDS5(FLD(s, 1, 1), FLD(op, 4, 3), FLD(y, 7, 1), FLD(offsetR, 8, 15),
FLD(dst, 23, 5)))
FMT(d_adda_long, 32, 0x1000000c, 0xf000000c,
NFLDS5(FLD(s, 1, 1), FLD(op, 4, 3), FLD(y, 7, 1), FLD(offsetR, 8, 15),
FLD(dst, 23, 5)))
/* Appendix C 16-bit formats will go here. */
/* Appendix D 32-bit formats. */
FMT(l_1_or_2_src, 32, 0x18, 0x1c,
CFLDS6(FLD(s, 1, 1), FLD(op, 5, 7), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
FMT(l_1_or_2_src_noncond, 32, 0x10000018, 0xf000001c,
NFLDS6(FLD(s, 1, 1), FLD(op, 5, 7), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
FMT(l_unary, 32, 0x358, 0xffc,
CFLDS5(FLD(s, 1, 1), FLD(x, 12, 1), FLD(op, 13, 5), FLD(src2, 18, 5),
FLD(dst, 23, 5)))
/* Appendix D 16-bit formats will go here. */
/* Appendix E 32-bit formats. */
FMT(m_compound, 32, 0x30, 0x83c,
CFLDS6(FLD(s, 1, 1), FLD(op, 6, 5), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
FMT(m_1_or_2_src, 32, 0x10000030, 0xf000083c,
NFLDS6(FLD(s, 1, 1), FLD(op, 6, 5), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
/* Contrary to SPRUFE8, this does have predicate fields. */
FMT(m_unary, 32, 0xf0, 0xffc,
CFLDS5(FLD(s, 1, 1), FLD(x, 12, 1), FLD(op, 13, 5), FLD(src2, 18, 5),
FLD(dst, 23, 5)))
/* M-unit formats missing from Appendix E. */
FMT(m_mpy, 32, 0x0, 0x7c,
CFLDS6(FLD(s, 1, 1), FLD(op, 7, 5), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
/* Appendix E 16-bit formats will go here. */
/* Appendix F 32-bit formats. */
FMT(s_1_or_2_src, 32, 0x20, 0x3c,
CFLDS6(FLD(s, 1, 1), FLD(op, 6, 6), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23 ,5)))
FMT(s_ext_1_or_2_src, 32, 0xc30, 0xc3c,
CFLDS6(FLD(s, 1, 1), FLD(op, 6, 4), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
FMT(s_ext_1_or_2_src_noncond, 32, 0xc30, 0xe0000c3c,
NFLDS7(FLD(s, 1, 1), FLD(op, 6, 4), FLD(x, 12, 1), FLD(src1, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5), FLD(z, 28, 1)))
FMT(s_unary, 32, 0xf20, 0xffc,
CFLDS5(FLD(s, 1, 1), FLD(x, 12, 1), FLD(op, 13, 5), FLD(src2, 18, 5),
FLD(dst, 23, 5)))
FMT(s_ext_branch_cond_imm, 32, 0x10, 0x7c,
CFLDS2(FLD(s, 1, 1), FLD(cst, 7, 21)))
FMT(s_call_imm_nop, 32, 0x10, 0xe000007c,
NFLDS3(FLD(s, 1, 1), FLD(cst, 7, 21), FLD(z, 28, 1)))
FMT(s_branch_nop_cst, 32, 0x120, 0x1ffc,
CFLDS3(FLD(s, 1, 1), FLD(src1, 13, 3), FLD(src2, 16, 12)))
FMT(s_branch_nop_reg, 32, 0x800360, 0xf830ffc,
CFLDS4(FLD(s, 1, 1), FLD(x, 12, 1), FLD(src1, 13, 3), FLD(src2, 18, 5)))
FMT(s_branch, 32, 0x360, 0xf8feffc,
CFLDS3(FLD(s, 1, 1), FLD(x, 12, 1), FLD(src2, 18, 5)))
FMT(s_mvk, 32, 0x28, 0x3c,
CFLDS4(FLD(s, 1, 1), FLD(h, 6, 1), FLD(cst, 7, 16), FLD(dst, 23, 5)))
FMT(s_field, 32, 0x8, 0x3c,
CFLDS6(FLD(s, 1, 1), FLD(op, 6, 2), FLD(cstb, 8, 5), FLD(csta, 13, 5),
FLD(src2, 18, 5), FLD(dst, 23, 5)))
/* S-unit formats missing from Appendix F. */
FMT(s_addk, 32, 0x50, 0x7c,
CFLDS3(FLD(s, 1, 1), FLD(cst, 7, 16), FLD(dst, 23, 5)))
FMT(s_addkpc, 32, 0x160, 0x1ffc,
CFLDS4(FLD(s, 1, 1), FLD(src2, 13, 3), FLD(src1, 16, 7), FLD(dst, 23, 5)))
FMT(s_b_irp, 32, 0x1800e0, 0x7feffc,
CFLDS3(FLD(s, 1, 1), FLD(x, 12, 1), FLD(dst, 23, 5)))
FMT(s_b_nrp, 32, 0x1c00e0, 0x7feffc,
CFLDS3(FLD(s, 1, 1), FLD(x, 12, 1), FLD(dst, 23, 5)))
FMT(s_bdec, 32, 0x1020, 0x1ffc,
CFLDS3(FLD(s, 1, 1), FLD(src, 13, 10), FLD(dst, 23, 5)))
FMT(s_bpos, 32, 0x20, 0x1ffc,
CFLDS3(FLD(s, 1, 1), FLD(src, 13, 10), FLD(dst, 23, 5)))
/* Appendix F 16-bit formats will go here. */
/* Appendix G 16-bit formats will go here. */
/* Appendix H 32-bit formats. */
FMT(nfu_loop_buffer, 32, 0x00020000, 0x00021ffc,
CFLDS4(FLD(s, 1, 1), FLD(op, 13, 4), FLD(csta, 18, 5), FLD(cstb, 23, 5)))
/* Corrected relative to Appendix H. */
FMT(nfu_nop_idle, 32, 0x00000000, 0xfffe1ffc,
NFLDS2(FLD(s, 1, 1), FLD(op, 13, 4)))
/* No-unit formats missing from Appendix H (given the NOP and IDLE
correction). */
FMT(nfu_dint, 32, 0x10004000, 0xfffffffc,
NFLDS1(FLD(s, 1, 1)))
FMT(nfu_rint, 32, 0x10006000, 0xfffffffc,
NFLDS1(FLD(s, 1, 1)))
FMT(nfu_swe, 32, 0x10000000, 0xfffffffc,
NFLDS1(FLD(s, 1, 1)))
FMT(nfu_swenr, 32, 0x10002000, 0xfffffffc,
NFLDS1(FLD(s, 1, 1)))
/* Although formally covered by the loop buffer format, the fields in
that format are not useful for all such instructions and not all
instructions can be predicated. */
FMT(nfu_spkernel, 32, 0x00034000, 0xf03ffffc,
NFLDS2(FLD(s, 1, 1), FLD(fstgfcyc, 22, 6)))
FMT(nfu_spkernelr, 32, 0x00036000, 0xfffffffc,
NFLDS1(FLD(s, 1, 1)))
FMT(nfu_spmask, 32, 0x00020000, 0xfc021ffc,
NFLDS3(FLD(s, 1, 1), FLD(op, 13, 4), FLD(mask, 18, 8)))
/* Appendix H 16-bit formats will go here. */
#undef FLD
#undef CFLDS
#undef CFLDS2
#undef CFLDS3
#undef CFLDS4
#undef CFLDS5
#undef CFLDS6
#undef CFLDS7
#undef CFLDS8
#undef NFLDS
#undef NFLDS1
#undef NFLDS2
#undef NFLDS3
#undef NFLDS5
#undef NFLDS6
#undef NFLDS7

File diff suppressed because it is too large Load Diff

614
include/opcode/tic6x.h Normal file
View File

@ -0,0 +1,614 @@
/* TI C6X opcode information.
Copyright 2010
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_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
{
/* The name used to reference the field. */
tic6x_insn_field_id field_id;
/* The least-significant bit position in the field. */
unsigned short low_pos;
/* The number of bits in the field. */
unsigned short width;
} 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;
/* 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
#define TIC6X_INSN_ATOMIC 0x0040
/* 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)
#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, 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,
/* 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,
/* The literal string "irp" (case-insensitive). */
tic6x_operand_irp,
/* The literal string "nrp" (case-insensitive). */
tic6x_operand_nrp,
/* 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
} 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,
/* 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,
/* Store 0 for register B14, 1 for register B15. When applied to
a memory reference, encode the base register. */
tic6x_coding_areg,
/* 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
} 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 short 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),
#include "tic6x-opcode-table.h"
#undef INSN
#undef INSNE
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 */