From f6c1a2d592af15d02c7fc93390af3c803e74c4d9 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 3 May 2012 13:12:08 +0000 Subject: [PATCH] Add support for Motorola XGATE embedded CPU --- bfd/ChangeLog | 20 + bfd/bfd-in2.h | 55 +- bfd/config.bfd | 8 +- bfd/configure | 1 + bfd/configure.in | 1 + bfd/elf-bfd.h | 1 + bfd/libbfd.h | 12 + bfd/reloc.c | 64 +- bfd/targets.c | 2 + binutils/ChangeLog | 4 + binutils/readelf.c | 19 +- gas/ChangeLog | 15 + gas/Makefile.am | 2 + gas/Makefile.in | 18 + gas/NEWS | 2 + gas/config/tc-xgate.c | 1416 +++++++++++++++++++++ gas/config/tc-xgate.h | 111 ++ gas/configure.tgt | 3 + gas/doc/Makefile.am | 1 + gas/doc/Makefile.in | 2 + gas/doc/all.texi | 1 + gas/doc/as.texinfo | 7 + gas/doc/c-xgate.texi | 209 +++ gas/testsuite/ChangeLog | 15 + gas/testsuite/gas/all/gas.exp | 4 +- gas/testsuite/gas/xgate/abi-xgate-16-32.d | 8 + gas/testsuite/gas/xgate/abi-xgate-16-64.d | 7 + gas/testsuite/gas/xgate/abi-xgate-32-32.d | 7 + gas/testsuite/gas/xgate/abi-xgate-32-64.d | 7 + gas/testsuite/gas/xgate/abi.s | 4 + gas/testsuite/gas/xgate/all_insns.d | 130 ++ gas/testsuite/gas/xgate/all_insns.s | 111 ++ gas/testsuite/gas/xgate/insns-dwarf2.d | 84 ++ gas/testsuite/gas/xgate/insns.d | 45 + gas/testsuite/gas/xgate/insns.s | 43 + gas/testsuite/gas/xgate/xgate.exp | 19 + include/ChangeLog | 6 + include/dis-asm.h | 1 + include/elf/ChangeLog | 4 + include/elf/xgate.h | 77 ++ include/opcode/ChangeLog | 4 + include/opcode/xgate.h | 120 ++ ld/ChangeLog | 10 + ld/Makefile.am | 5 + ld/Makefile.in | 6 + ld/NEWS | 2 + ld/configure.tgt | 2 + ld/emulparams/xgateelf.sh | 18 + ld/scripttempl/elfxgate.sc | 463 +++++++ opcodes/ChangeLog | 11 + opcodes/Makefile.am | 2 + opcodes/Makefile.in | 4 + opcodes/configure | 3 +- opcodes/configure.in | 3 +- opcodes/disassemble.c | 6 + opcodes/xgate-dis.c | 403 ++++++ opcodes/xgate-opc.c | 203 +++ 57 files changed, 3798 insertions(+), 13 deletions(-) create mode 100644 gas/config/tc-xgate.c create mode 100644 gas/config/tc-xgate.h create mode 100644 gas/doc/c-xgate.texi create mode 100644 gas/testsuite/gas/xgate/abi-xgate-16-32.d create mode 100644 gas/testsuite/gas/xgate/abi-xgate-16-64.d create mode 100644 gas/testsuite/gas/xgate/abi-xgate-32-32.d create mode 100644 gas/testsuite/gas/xgate/abi-xgate-32-64.d create mode 100644 gas/testsuite/gas/xgate/abi.s create mode 100644 gas/testsuite/gas/xgate/all_insns.d create mode 100644 gas/testsuite/gas/xgate/all_insns.s create mode 100644 gas/testsuite/gas/xgate/insns-dwarf2.d create mode 100644 gas/testsuite/gas/xgate/insns.d create mode 100644 gas/testsuite/gas/xgate/insns.s create mode 100644 gas/testsuite/gas/xgate/xgate.exp create mode 100644 include/elf/xgate.h create mode 100644 include/opcode/xgate.h create mode 100644 ld/emulparams/xgateelf.sh create mode 100644 ld/scripttempl/elfxgate.sc create mode 100644 opcodes/xgate-dis.c create mode 100644 opcodes/xgate-opc.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4167a0df57..733c5462e7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,23 @@ +2012-05-03 Sean Keys + + * cpu-xgate.c: New file. Added XGATE support. + * archures.c (bfd_architecture): Add XGATE architecture. + (bfd_archures_list): Add reference to XGATE architecture info. + * elf-bfd.h (prep_headers): Handle bfd_arch_xgate. + * reloc.c: Add various XGATE relocation enums. + * targets.c (bfd_elf32_xgate_vec): Declare and add to target vector + list. + * Makefile.am: Add support for XGATE elf. + * configure.in: Ditto. + * config.bfd: Ditto. + * Makefile.in: Regenerate. + * configure: Ditto. + * bfd-in2.h: Ditto. + * libbfd.h: Ditto. + Added files for XGATE relocations. + * elf32-xgate.c: Created minimal relocation file. + * elf32-xgate.h: Created minimal header file for elf32-xgate. + 2012-05-03 Tristan Gingold * dwarf2.c (decode_line_info): Ignore diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 17dbbe1353..6b94f7246a 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2141,7 +2141,9 @@ enum bfd_architecture bfd_arch_xc16x, /* Infineon's XC16X Series. */ #define bfd_mach_xc16x 1 #define bfd_mach_xc16xl 2 -#define bfd_mach_xc16xs 3 +#define bfd_mach_xc16xs 3 + bfd_arch_xgate, /* Freescale XGATE */ +#define bfd_mach_xgate 1 bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ #define bfd_mach_xtensa 1 bfd_arch_z80, @@ -4472,6 +4474,57 @@ to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ This is the 5 bits of a value. */ BFD_RELOC_M68HC12_5B, +/* Freescale XGATE reloc. +This reloc marks the beginning of a bra/jal instruction. */ + BFD_RELOC_XGATE_RL_JUMP, + +/* Freescale XGATE reloc. +This reloc marks a group of several instructions that gcc generates +and for which the linker relaxation pass can modify and/or remove +some of them. */ + BFD_RELOC_XGATE_RL_GROUP, + +/* Freescale XGATE reloc. +This is the 16-bit lower part of an address. It is used for the '16-bit' +instructions. */ + BFD_RELOC_XGATE_LO16, + +/* Freescale XGATE reloc. */ + BFD_RELOC_XGATE_GPAGE, + +/* Freescale XGATE reloc. */ + BFD_RELOC_XGATE_24, + +/* Freescale XGATE reloc. +This is a 9-bit pc-relative reloc. */ + BFD_RELOC_XGATE_PCREL_9, + +/* Freescale XGATE reloc. +This is a 10-bit pc-relative reloc. */ + BFD_RELOC_XGATE_PCREL_10, + +/* Freescale XGATE reloc. +This is the 16-bit lower part of an address. It is used for the '16-bit' +instructions. */ + BFD_RELOC_XGATE_IMM8_LO, + +/* Freescale XGATE reloc. +This is the 16-bit higher part of an address. It is used for the '16-bit' +instructions. */ + BFD_RELOC_XGATE_IMM8_HI, + +/* Freescale XGATE reloc. +This is a 3-bit pc-relative reloc. */ + BFD_RELOC_XGATE_IMM3, + +/* Freescale XGATE reloc. +This is a 4-bit pc-relative reloc. */ + BFD_RELOC_XGATE_IMM4, + +/* Freescale XGATE reloc. +This is a 5-bit pc-relative reloc. */ + BFD_RELOC_XGATE_IMM5, + /* NS CR16C Relocations. */ BFD_RELOC_16C_NUM08, BFD_RELOC_16C_NUM08_C, diff --git a/bfd/config.bfd b/bfd/config.bfd index ab72cf3c48..3f758c0bde 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -105,6 +105,7 @@ tilepro*) targ_archs=bfd_tilepro_arch ;; v850*) targ_archs=bfd_v850_arch ;; x86_64*) targ_archs=bfd_i386_arch ;; xtensa*) targ_archs=bfd_xtensa_arch ;; +xgate) targ_archs=bfd_xgate_arch ;; z80|r800) targ_archs=bfd_z80_arch ;; z8k*) targ_archs=bfd_z8k_arch ;; *) targ_archs=bfd_${targ_cpu}_arch ;; @@ -1576,7 +1577,12 @@ case "${targ}" in w65-*-*) targ_defvec=w65_vec ;; - + + xgate-*-*) + targ_defvec=bfd_elf32_xgate_vec + targ_selvecs="bfd_elf32_xgate_vec" + ;; + xstormy16-*-elf) targ_defvec=bfd_elf32_xstormy16_vec ;; diff --git a/bfd/configure b/bfd/configure index fc5c9ad6af..7c5247847f 100755 --- a/bfd/configure +++ b/bfd/configure @@ -15332,6 +15332,7 @@ do bfd_elf32_vax_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;; bfd_elf32_xstormy16_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;; bfd_elf32_xc16x_vec) tb="$tb elf32-xc16x.lo elf32.lo $elf" ;; + bfd_elf32_xgate_vec) tb="$tb elf32-xgate.lo elf32.lo $elf" ;; bfd_elf32_xtensa_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;; bfd_elf32_xtensa_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;; bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; diff --git a/bfd/configure.in b/bfd/configure.in index 3cb4b70e25..47631cc8cc 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -818,6 +818,7 @@ do bfd_elf32_vax_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;; bfd_elf32_xstormy16_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;; bfd_elf32_xc16x_vec) tb="$tb elf32-xc16x.lo elf32.lo $elf" ;; + bfd_elf32_xgate_vec) tb="$tb elf32-xgate.lo elf32.lo $elf" ;; bfd_elf32_xtensa_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;; bfd_elf32_xtensa_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;; bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 4821eafa09..5af924c4c6 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -428,6 +428,7 @@ enum elf_target_id TIC6X_ELF_DATA, X86_64_ELF_DATA, XTENSA_ELF_DATA, + XGATE_ELF_DATA, TILEGX_ELF_DATA, TILEPRO_ELF_DATA, GENERIC_ELF_DATA diff --git a/bfd/libbfd.h b/bfd/libbfd.h index ab3c897de0..e4acdb0cfa 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2093,6 +2093,18 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_M68HC11_PAGE", "BFD_RELOC_M68HC11_24", "BFD_RELOC_M68HC12_5B", + "BFD_RELOC_XGATE_RL_JUMP", + "BFD_RELOC_XGATE_RL_GROUP", + "BFD_RELOC_XGATE_LO16", + "BFD_RELOC_XGATE_GPAGE", + "BFD_RELOC_XGATE_24", + "BFD_RELOC_XGATE_PCREL_9", + "BFD_RELOC_XGATE_PCREL_10", + "BFD_RELOC_XGATE_IMM8_LO", + "BFD_RELOC_XGATE_IMM8_HI", + "BFD_RELOC_XGATE_IMM3", + "BFD_RELOC_XGATE_IMM4", + "BFD_RELOC_XGATE_IMM5", "BFD_RELOC_16C_NUM08", "BFD_RELOC_16C_NUM08_C", "BFD_RELOC_16C_NUM16", diff --git a/bfd/reloc.c b/bfd/reloc.c index 7aa9f96712..0ec1b610ab 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -4979,7 +4979,69 @@ ENUM ENUMDOC Motorola 68HC12 reloc. This is the 5 bits of a value. - +ENUM + BFD_RELOC_XGATE_RL_JUMP +ENUMDOC + Freescale XGATE reloc. + This reloc marks the beginning of a bra/jal instruction. +ENUM + BFD_RELOC_XGATE_RL_GROUP +ENUMDOC + Freescale XGATE reloc. + This reloc marks a group of several instructions that gcc generates + and for which the linker relaxation pass can modify and/or remove + some of them. +ENUM + BFD_RELOC_XGATE_LO16 +ENUMDOC + Freescale XGATE reloc. + This is the 16-bit lower part of an address. It is used for the '16-bit' + instructions. +ENUM + BFD_RELOC_XGATE_GPAGE +ENUMDOC + Freescale XGATE reloc. +ENUM + BFD_RELOC_XGATE_24 +ENUMDOC + Freescale XGATE reloc. +ENUM + BFD_RELOC_XGATE_PCREL_9 +ENUMDOC + Freescale XGATE reloc. + This is a 9-bit pc-relative reloc. +ENUM + BFD_RELOC_XGATE_PCREL_10 +ENUMDOC + Freescale XGATE reloc. + This is a 10-bit pc-relative reloc. +ENUM + BFD_RELOC_XGATE_IMM8_LO +ENUMDOC + Freescale XGATE reloc. + This is the 16-bit lower part of an address. It is used for the '16-bit' + instructions. +ENUM + BFD_RELOC_XGATE_IMM8_HI +ENUMDOC + Freescale XGATE reloc. + This is the 16-bit higher part of an address. It is used for the '16-bit' + instructions. +ENUM + BFD_RELOC_XGATE_IMM3 +ENUMDOC + Freescale XGATE reloc. + This is a 3-bit pc-relative reloc. +ENUM + BFD_RELOC_XGATE_IMM4 +ENUMDOC + Freescale XGATE reloc. + This is a 4-bit pc-relative reloc. +ENUM + BFD_RELOC_XGATE_IMM5 +ENUMDOC + Freescale XGATE reloc. + This is a 5-bit pc-relative reloc. ENUM BFD_RELOC_16C_NUM08 ENUMX diff --git a/bfd/targets.c b/bfd/targets.c index 78b42888de..f94fed527d 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -717,6 +717,7 @@ extern const bfd_target bfd_elf32_us_cris_vec; extern const bfd_target bfd_elf32_v850_vec; extern const bfd_target bfd_elf32_vax_vec; extern const bfd_target bfd_elf32_xc16x_vec; +extern const bfd_target bfd_elf32_xgate_vec; extern const bfd_target bfd_elf32_xstormy16_vec; extern const bfd_target bfd_elf32_xtensa_be_vec; extern const bfd_target bfd_elf32_xtensa_le_vec; @@ -1090,6 +1091,7 @@ static const bfd_target * const _bfd_target_vector[] = &bfd_elf32_v850_vec, &bfd_elf32_vax_vec, &bfd_elf32_xc16x_vec, + &bfd_elf32_xgate_vec, &bfd_elf32_xstormy16_vec, &bfd_elf32_xtensa_be_vec, &bfd_elf32_xtensa_le_vec, diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 69c849a459..693b100009 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2012-05-03 Sean Keys + + * readelf.c: Add support for XGATE. + 2012-05-02 Nick Clifton * po/vi.po: Updated Vietnamese translation. diff --git a/binutils/readelf.c b/binutils/readelf.c index f42039e762..937cac18a8 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -146,6 +146,7 @@ #include "elf/vax.h" #include "elf/x86-64.h" #include "elf/xc16x.h" +#include "elf/xgate.h" #include "elf/xstormy16.h" #include "elf/xtensa.h" @@ -547,6 +548,7 @@ guess_is_rela (unsigned int e_machine) case EM_OPENRISC: case EM_OR32: case EM_SCORE: + case EM_XGATE: return FALSE; /* Targets that use RELA relocations. */ @@ -559,7 +561,6 @@ guess_is_rela (unsigned int e_machine) case EM_AVR_OLD: case EM_BLACKFIN: case EM_CR16: - case EM_CR16_OLD: case EM_CRIS: case EM_CRX: case EM_D30V: @@ -1210,7 +1211,6 @@ dump_relocations (FILE * file, break; case EM_CR16: - case EM_CR16_OLD: rtype = elf_cr16_reloc_type (type); break; @@ -1243,6 +1243,10 @@ dump_relocations (FILE * file, case EM_TILEPRO: rtype = elf_tilepro_reloc_type (type); break; + + case EM_XGATE: + rtype = elf_xgate_reloc_type (type); + break; } if (rtype == NULL) @@ -1869,7 +1873,7 @@ get_machine_name (unsigned e_machine) case EM_CYGNUS_M32R: case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)"; case EM_CYGNUS_V850: - case EM_V850: return "Renesas v850"; + case EM_V850: return "Renesas V850"; case EM_CYGNUS_MN10300: case EM_MN10300: return "mn10300"; case EM_CYGNUS_MN10200: @@ -1979,8 +1983,7 @@ get_machine_name (unsigned e_machine) case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture"; case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine"; case EM_CR16: - case EM_CR16_OLD: return "National Semiconductor's CR16"; - case EM_MICROBLAZE: return "Xilinx MicroBlaze"; + case EM_MICROBLAZE: case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze"; case EM_RL78: return "Renesas RL78"; case EM_RX: return "Renesas RX"; @@ -1995,6 +1998,7 @@ get_machine_name (unsigned e_machine) case EM_TILEPRO: return "Tilera TILEPro multicore architecture family"; case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family"; case EM_CUDA: return "NVIDIA CUDA architecture"; + case EM_XGATE: return "Motorola XGATE embedded processor"; default: snprintf (buff, sizeof (buff), _(": 0x%x"), e_machine); return buff; @@ -9778,7 +9782,6 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_CRIS: return reloc_type == 3; /* R_CRIS_32. */ case EM_CR16: - case EM_CR16_OLD: return reloc_type == 3; /* R_CR16_NUM32. */ case EM_CRX: return reloc_type == 15; /* R_CRX_NUM32. */ @@ -9890,6 +9893,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_XC16X: case EM_C166: return reloc_type == 3; /* R_XC16C_ABS_32. */ + case EM_XGATE: + return reloc_type == 4; /* R_XGATE_32. */ case EM_XSTORMY16: return reloc_type == 1; /* R_XSTROMY16_32. */ case EM_XTENSA_OLD: @@ -10087,6 +10092,8 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_CYGNUS_MN10300: case EM_MN10300: return reloc_type == 2; /* R_MN10300_16. */ + case EM_XGATE: + return reloc_type == 3; /* R_XGATE_16. */ default: return FALSE; } diff --git a/gas/ChangeLog b/gas/ChangeLog index dfbdb28588..e04a49f7ce 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2012-05-03 Sean Keys + + * configure, Makefile.in: Regenerate. + * Makefile.am (CPU_TYPES, TARGET_CPU_CFILES, TARGET_CPU_HFILES): + * configure.tgt: Added cpu type. + Added files for XGATE assembler. + * config/tc-xgate.c: Assembler for XGATE. + * config/tc-xgate.h: Header definition for assembler + Added files for XGATE testsuite. + * doc/Makefile.am (CPU_DOCS): Added XGATE file. + * doc/c-xgate.texi: Document XGATE and XGATE port. + * doc/as.texinfo: Ditto. + * doc/all.texi: Ditto + * NEWS: Mention the new support. + 2012-04-30 DJ Delorie * config/rx-parse.y (rx_intop): Add parameter for operation size. diff --git a/gas/Makefile.am b/gas/Makefile.am index 8f7b7cd60e..80a2fd0d6f 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -169,6 +169,7 @@ TARGET_CPU_CFILES = \ config/tc-v850.c \ config/tc-xstormy16.c \ config/tc-xc16x.c \ + config/tc-xgate.c \ config/tc-xtensa.c \ config/tc-z80.c \ config/tc-z8k.c \ @@ -236,6 +237,7 @@ TARGET_CPU_HFILES = \ config/tc-v850.h \ config/tc-xstormy16.h \ config/tc-xc16x.h \ + config/tc-xgate.h \ config/tc-xtensa.h \ config/tc-z80.h \ config/tc-z8k.h \ diff --git a/gas/Makefile.in b/gas/Makefile.in index 39af3e8c14..672de79dd6 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -53,6 +53,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/gettext-sister.m4 \ $(top_srcdir)/../config/largefile.m4 \ + $(top_srcdir)/../config/lcmessage.m4 \ $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/nls.m4 \ $(top_srcdir)/../config/override.m4 \ @@ -436,6 +437,7 @@ TARGET_CPU_CFILES = \ config/tc-v850.c \ config/tc-xstormy16.c \ config/tc-xc16x.c \ + config/tc-xgate.c \ config/tc-xtensa.c \ config/tc-z80.c \ config/tc-z8k.c \ @@ -503,6 +505,7 @@ TARGET_CPU_HFILES = \ config/tc-v850.h \ config/tc-xstormy16.h \ config/tc-xc16x.h \ + config/tc-xgate.h \ config/tc-xtensa.h \ config/tc-z80.h \ config/tc-z8k.h \ @@ -851,6 +854,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-v850.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-vax.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xc16x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xgate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xstormy16.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xtensa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-z80.Po@am__quote@ @@ -1748,6 +1752,20 @@ tc-xc16x.obj: config/tc-xc16x.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-xc16x.obj `if test -f 'config/tc-xc16x.c'; then $(CYGPATH_W) 'config/tc-xc16x.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xc16x.c'; fi` +tc-xgate.o: config/tc-xgate.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xgate.o -MD -MP -MF $(DEPDIR)/tc-xgate.Tpo -c -o tc-xgate.o `test -f 'config/tc-xgate.c' || echo '$(srcdir)/'`config/tc-xgate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-xgate.Tpo $(DEPDIR)/tc-xgate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-xgate.c' object='tc-xgate.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-xgate.o `test -f 'config/tc-xgate.c' || echo '$(srcdir)/'`config/tc-xgate.c + +tc-xgate.obj: config/tc-xgate.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xgate.obj -MD -MP -MF $(DEPDIR)/tc-xgate.Tpo -c -o tc-xgate.obj `if test -f 'config/tc-xgate.c'; then $(CYGPATH_W) 'config/tc-xgate.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xgate.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-xgate.Tpo $(DEPDIR)/tc-xgate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-xgate.c' object='tc-xgate.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-xgate.obj `if test -f 'config/tc-xgate.c'; then $(CYGPATH_W) 'config/tc-xgate.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xgate.c'; fi` + tc-xtensa.o: config/tc-xtensa.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xtensa.o -MD -MP -MF $(DEPDIR)/tc-xtensa.Tpo -c -o tc-xtensa.o `test -f 'config/tc-xtensa.c' || echo '$(srcdir)/'`config/tc-xtensa.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-xtensa.Tpo $(DEPDIR)/tc-xtensa.Po diff --git a/gas/NEWS b/gas/NEWS index 6e2abffc2d..e8dcf507d5 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for the Freescale XGATE architecture. + * Add support for .bundle_align_mode, .bundle_lock, and .bundle_unlock directives. These are currently available only for x86 and ARM targets. diff --git a/gas/config/tc-xgate.c b/gas/config/tc-xgate.c new file mode 100644 index 0000000000..954acdc367 --- /dev/null +++ b/gas/config/tc-xgate.c @@ -0,0 +1,1416 @@ +/* tc-xgate.c -- Assembler code for Freescale XGATE + Copyright 2010, 2011, 2012 + Free Software Foundation, Inc. + Contributed by Sean Keys + + This file is part of GAS, the GNU Assembler. + + GAS 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. + + GAS 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 GAS; see the file COPYING. If not, write to + the Free Software Foundation, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "opcode/xgate.h" +#include "dwarf2dbg.h" +#include "elf/xgate.h" + +const char comment_chars[] = ";!"; +const char line_comment_chars[] = "#*"; +const char line_separator_chars[] = ""; +const char EXP_CHARS[] = "eE"; +const char FLT_CHARS[] = "dD"; + +#define SIXTEENTH_BIT 0x8000 +#define N_BITS_IN_WORD 16 + +/* #define STATE_CONDITIONAL_BRANCH (1) */ +#define STATE_PC_RELATIVE (2) +#define REGISTER_P(ptr) (ptr == 'r') +#define INCREMENT 01 +#define DECREMENT 02 +#define MAXREGISTER 07 +#define MINREGISTER 00 + +#define OPTION_MMCU 'm' + +/* This macro has no side-effects. */ +#define ENCODE_RELAX(what,length) (((what) << 2) + (length)) + +/* what this is */ +struct xgate_opcode_handle +{ + int number_of_modes; + char *name; + struct xgate_opcode *opc0[MAX_OPCODES]; +}; + +/* LOCAL FUNCTIONS */ +static char * +xgate_parse_exp (char *, expressionS *); +static inline char * +skip_whitespace (char *); +static void +get_default_target (void); +static char * +extract_word (char *, char *, int); +static char * +xgate_new_instruction (int size); +unsigned short +xgate_apply_operand (unsigned short, unsigned short *, unsigned short, + unsigned char); +void +xgate_operands (struct xgate_opcode *, char **); +static unsigned int +xgate_operand (struct xgate_opcode *, int *, int where, char **, char **); +static struct xgate_opcode * +xgate_find_match (struct xgate_opcode_handle *, int, unsigned int); +static int +cmp_opcode (struct xgate_opcode *, struct xgate_opcode *); +unsigned int +xgate_detect_format (char *); +void +xgate_print_syntax (char *); +void +xgate_print_table (void); + +/* LOCAL DATA */ +static struct hash_control *xgate_hash; + +/* Previous opcode. */ +static unsigned int prev = 0; + +static unsigned char fixup_required = 0; + +/* Used to enable clipping of 16 bit operands into 8 bit constraints. */ +static unsigned char macroClipping = 0; + +static char oper_check; +static char flag_print_insn_syntax = 0; +static char flag_print_opcodes = 0; + +static int current_architecture; +static const char *default_cpu; + +/* ELF flags to set in the output file header. */ +static int elf_flags = E_XGATE_F64; + +/* This table describes how you change sizes for the various types of variable + size expressions. This version only supports two kinds. */ + +/* The fields are: + How far Forward this mode will reach. + How far Backward this mode will reach. + How many bytes this mode will add to the size of the frag. + Which mode to go to if the offset won't fit in this one. */ + +relax_typeS md_relax_table[] = +{ + {1, 1, 0, 0}, /* First entries aren't used. */ + {1, 1, 0, 0}, /* For no good reason except. */ + {1, 1, 0, 0}, /* that the VAX doesn't either. */ + {1, 1, 0, 0}, + /* XGATE 9 and 10 bit pc rel todo complete and test */ +/*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, + {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */ + {0, 0, 0, 0} +}; + +/* XGATE's registers all are 16-bit general purpose. They are numbered according to the specifications. */ +typedef enum register_id +{ + REG_NONE = -1, + REG_R0 = 0, + REG_R1 = 1, + REG_R2 = 2, + REG_R3 = 3, + REG_R4 = 4, + REG_R5 = 5, + REG_R6 = 6, + REG_R7 = 7, + REG_PC = 8, + REG_CCR = 9 +} register_id; + +/* This table describes all the machine specific pseudo-ops the assembler + has to support. The fields are: pseudo-op name without dot function to + call to execute this pseudo-op Integer arg to pass to the function. */ +const pseudo_typeS md_pseudo_table[] = +{ + /* The following pseudo-ops are supported for MRI compatibility. */ + {0, 0, 0} +}; + +const char *md_shortopts = "m:"; + +struct option md_longopts[] = +{ +#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0) + { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX }, + +#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1) + { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES }, + +#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2) + { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE }, + +#define OPTION_MSHORT (OPTION_MD_BASE + 3) + { "mshort", no_argument, NULL, OPTION_MSHORT }, + +#define OPTION_MLONG (OPTION_MD_BASE + 4) + { "mlong", no_argument, NULL, OPTION_MLONG }, + +#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5) + { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE }, + +#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6) + { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE }, + + { NULL, no_argument, NULL, 0 } +}; + +size_t md_longopts_size = sizeof(md_longopts); + +char * +md_atof (int type, char *litP, int *sizeP) +{ + return ieee_md_atof (type, litP, sizeP, TRUE); +} + +int +md_parse_option (int c, char *arg) +{ + switch (c) + { + case OPTION_MMCU: + if (strcasecmp (arg, "v1") == 0) + current_architecture = XGATE_V1; + else if (strcasecmp (arg, "v2") == 0) + current_architecture = XGATE_V2; + else if (strcasecmp (arg, "v3") == 0) + current_architecture = XGATE_V3; + else + as_bad (_(" architecture variant invalid")); + break; + + case OPTION_PRINT_INSN_SYNTAX: + flag_print_insn_syntax = 1; + break; + + case OPTION_PRINT_OPCODES: + flag_print_opcodes = 1; + break; + + case OPTION_GENERATE_EXAMPLE: + flag_print_opcodes = 2; + break; + + case OPTION_MSHORT: + elf_flags &= ~E_XGATE_I32; + break; + + case OPTION_MLONG: + elf_flags |= E_XGATE_I32; + break; + + case OPTION_MSHORT_DOUBLE: + elf_flags &= ~E_XGATE_F64; + break; + + case OPTION_MLONG_DOUBLE: + elf_flags |= E_XGATE_F64; + break; + + default: + return 0; + } + return 1; +} + +const char * +xgate_arch_format (void) +{ + get_default_target (); + + if (current_architecture & cpuxgate) + return "elf32-xgate"; + + return "error"; +} + +static void +get_default_target (void) +{ + const bfd_target *target; + bfd abfd; + + if (current_architecture != 0) + return; + + default_cpu = "unknown"; + target = bfd_find_target (0, &abfd); + + if (target && target->name) + { + if (strcmp (target->name, "elf32-xgate") == 0) + { + current_architecture = cpuxgate; + default_cpu = "XGATE V1"; + return; + } + + as_bad (_("Default target `%s' is not supported."), target->name); + } +} + +void +md_begin (void) +{ + struct xgate_opcode *xgate_opcode_ptr = NULL; + struct xgate_opcode *xgate_op_table = NULL; + struct xgate_opcode_handle *op_handles = 0; + char *prev_op_name = 0; + int handle_enum = 0; + unsigned int number_of_handle_rows = 0; + int i, j = 0; + + /* Create a local copy of our opcode table + including an extra line for NULL termination. */ + xgate_op_table = (struct xgate_opcode *) + xmalloc ((xgate_num_opcodes + 1) * sizeof (struct xgate_opcode)); + + memset (xgate_op_table, 0, + sizeof(struct xgate_opcode) * (xgate_num_opcodes + 1)); + + for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0; + i < xgate_num_opcodes; i++) + xgate_op_table[i] = xgate_opcode_ptr[i]; + + qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode), + (int (*)(const void *, const void *)) cmp_opcode); + + /* Calculate number of handles since this will be + smaller than the raw number of opcodes in the table. */ + for (xgate_opcode_ptr = xgate_op_table; xgate_opcode_ptr->name; + xgate_opcode_ptr++) + { + if (prev_op_name != 0) + { + if (strcmp (prev_op_name, xgate_opcode_ptr->name)) + number_of_handle_rows++; + } + prev_op_name = xgate_opcode_ptr->name; + } + + op_handles = (struct xgate_opcode_handle *) + xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_handle_rows + 1)); + + /* Insert opcode names into hash table, aliasing duplicates. */ + xgate_hash = hash_new (); + + for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes; + i++, xgate_opcode_ptr++) + { + if (strcmp (prev_op_name, xgate_opcode_ptr->name) || i == 0) + { + handle_enum = 0; + if (i) + j++; + + op_handles[j].name = xgate_opcode_ptr->name; + op_handles[j].opc0[0] = xgate_opcode_ptr; + } + else + { + handle_enum++; + op_handles[j].opc0[handle_enum] = xgate_opcode_ptr; + } + op_handles[j].number_of_modes = handle_enum; + prev_op_name = op_handles[j].name; + } + + while (op_handles->name) + { + hash_insert (xgate_hash, op_handles->name, (char *) op_handles); + op_handles++; + } + + if (flag_print_opcodes == 1) + xgate_print_table (); +} + +void +xgate_init_after_args (void) +{ +} + +void +md_show_usage (FILE * stream) +{ + get_default_target (); + + fprintf ( + stream, + _("\ + Freescale XGATE co-processor options:\n \ + -mshort use 16-bit int ABI (default)\n \ + -mlong use 32-bit int ABI\n \ + -mshort-double use 32-bit double ABI\n \ + -mlong-double use 64-bit double ABI (default)\n\ + --mxgate specify the processor variant[default %s]\n\ + --print-insn-syntax print the syntax of instruction in case of error\n\ + --print-opcodes print the list of instructions with syntax\n\ + --generate-example generate an example of each instruction"), + default_cpu); +} + +enum bfd_architecture +xgate_arch (void) +{ + get_default_target (); + return bfd_arch_xgate; +} + +int +xgate_mach (void) +{ + return 0; +} + +void +xgate_print_syntax (char *name) +{ + int i; + + for (i = 0; i < xgate_num_opcodes; i++) + { + if (!strcmp (xgate_opcodes[i].name, name)) + { + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR)) + printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n", + xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH)) + printf ("\tFormat is %s\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI)) + printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA)) + printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA_MON) + || !strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON)) + printf ("\tFormat is %s\tRx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3)) + printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4)) + printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8)) + printf ("\tFormat is %s\tRx, <8-bit value>\n", + xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16)) + printf ("\tFormat is %s\tRx, <16-bit value>\n", + xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C)) + printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R)) + printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P)) + printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW)) + printf ("\tFormat is %s\tRx, <16-bit value>\n", + xgate_opcodes[i].name); + } + } +} + +void +xgate_print_table (void) +{ + int i; + + for (i = 0; i < xgate_num_opcodes; i++) + xgate_print_syntax (xgate_opcodes[i].name); + + return; +} + +const char * +xgate_listing_header (void) +{ + if (current_architecture & cpuxgate) + return "XGATE GAS "; + + return "ERROR MC9S12X GAS "; +} + +symbolS * +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) +{ + return 0; +} + +/* GAS will call this function for each section at the end of the assembly, + to permit the CPU backend to adjust the alignment of a section. */ + +valueT +md_section_align (asection * seg, valueT addr) +{ + int align = bfd_get_section_alignment (stdoutput, seg); + return ((addr + (1 << align) - 1) & (-1 << align)); +} + +void +md_assemble (char *input_line) +{ + struct xgate_opcode *opcode = 0; + struct xgate_opcode *macro_opcode = 0; + struct xgate_opcode_handle *opcode_handle = 0; + /* Caller expects it to be returned as it was passed. */ + char *saved_input_line = input_line; + char op_name[9] = { 0 }; + unsigned int sh_format = 0; + char *p = 0; + + fixup_required = 0; + oper_check = 0; /* set error flags */ + input_line = extract_word (input_line, op_name, sizeof(op_name)); + + /* Check to make sure we are not reading a bogus line. */ + if (!op_name[0]) + as_bad (_("opcode missing or not found on input line")); + + if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash, + op_name))) + { + as_bad (_("opcode %s not found in opcode hash table"), op_name); + } + else + { + /* Detect operand format so we can pull the proper opcode bin. */ + sh_format = xgate_detect_format (input_line); + + opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes, + sh_format); + + if (!opcode) + { + as_bad (_("matching operands to opcode ")); + xgate_print_syntax (opcode_handle->opc0[0]->name); + } + else if (opcode->size == 2) + { + /* Size is one word - assemble that native insn. */ + xgate_operands (opcode, &input_line); + } + else + { + /* Insn is a simplified instruction - expand it out. */ + macroClipping = 1; + unsigned int i; + + /* skip past our ';' separator. */ + for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0; + i--, p++) + { + if (*p == ';') + { + p++; + break; + } + } + input_line = skip_whitespace (input_line); + char *macro_inline = input_line; + + /* Loop though the macro's opcode list and apply operands to each real opcode. */ + for (i = 0; *p && i < (opcode->size / 2); i++) + { + /* Loop though macro operand list. */ + input_line = macro_inline; /* Rewind. */ + p = extract_word (p, op_name, 10); + + if (!(opcode_handle = (struct xgate_opcode_handle *) + hash_find (xgate_hash, op_name))) + { + as_bad ( + _(": processing macro, real opcode handle not found in hash")); + break; + } + else + { + sh_format = xgate_detect_format (input_line); + macro_opcode = xgate_find_match (opcode_handle, + opcode_handle->number_of_modes, sh_format); + xgate_operands (macro_opcode, &input_line); + } + } + } + } + macroClipping = 0; + input_line = saved_input_line; +} + +/* Force truly undefined symbols to their maximum size, and generally set up + the frag list to be relaxed. */ + +int +md_estimate_size_before_relax (fragS *fragp, asection *seg) +{ + /* If symbol is undefined or located in a different section, + select the largest supported relocation. */ + relax_substateT subtype; + relax_substateT rlx_state[] = + { 0, 2 }; + + for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2) + { + if (fragp->fr_subtype == rlx_state[subtype] + && (!S_IS_DEFINED (fragp->fr_symbol) + || seg != S_GET_SEGMENT (fragp->fr_symbol))) + { + fragp->fr_subtype = rlx_state[subtype + 1]; + break; + } + } + + if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table)) + abort (); + + return md_relax_table[fragp->fr_subtype].rlx_length; +} + + +/* Relocation, relaxation and frag conversions. */ + +/* PC-relative offsets are relative to the start of the + next instruction. That is, the address of the offset, plus its + size, since the offset is always the last part of the insn. */ + +long +md_pcrel_from (fixS * fixP) +{ + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* If while processing a fixup, a reloc really needs to be created + then it is done here. */ + +arelent * +tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) +{ + arelent * reloc; + + reloc = (arelent *) xmalloc (sizeof(arelent)); + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + + if (fixp->fx_r_type == 0) + { + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); + } + else + { + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); + } + + if (reloc->howto == (reloc_howto_type *) NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, _ + ("Relocation %d is not supported by object file format."), + (int) fixp->fx_r_type); + return NULL; + } + + /* Since we use Rel instead of Rela, encode the vtable entry to be + used in the relocation's section offset. */ + if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->address = fixp->fx_offset; + reloc->addend = 0; + return reloc; +} + +/* Patch the instruction with the resolved operand. Elf relocation + info will also be generated to take care of linker/loader fixups. + The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary + for the support of --gstabs. */ + +void +md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED) +{ + char *where; + long value = *valP; + int opcode = 0; + ldiv_t result; + + /* If the fixup is done mark it done so no further symbol resolution will take place. */ + if (fixP->fx_addsy == (symbolS *) NULL) + { + fixP->fx_done = 1; + } + + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex.")); + + where = fixP->fx_frag->fr_literal + fixP->fx_where; + opcode = bfd_getl16 (where); + int mask = 0; + + switch (fixP->fx_r_type) + { + case R_XGATE_PCREL_9: + if (value < -512 || value > 511) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value %ld too large for 9-bit PC-relative branch."), value); + result = ldiv (value, 2); /* from bytes to words */ + value = result.quot; + if (result.rem) + as_bad_where (fixP->fx_file, fixP->fx_line, _ + ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value); + mask = 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */ + value &= mask; + number_to_chars_bigendian (where, (opcode | value), 2); + break; + case R_XGATE_PCREL_10: + if (value < -1024 || value > 1023) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value %ld too large for 10-bit PC-relative branch."), value); + result = ldiv (value, 2); /* from bytes to words */ + value = result.quot; + if (result.rem) + as_bad_where (fixP->fx_file, fixP->fx_line, _ + ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value); + mask = 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */ + value &= mask; + number_to_chars_bigendian (where, (opcode | value), 2); + break; + case BFD_RELOC_XGATE_IMM8_HI: + if (value < -65537 || value > 65535) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 16-bit range.")); + value >>= 8; + value &= 0x00ff; + bfd_putb16 ((bfd_vma) value | opcode, (void *) where); + break; + case BFD_RELOC_XGATE_24: + case BFD_RELOC_XGATE_IMM8_LO: + if (value < -65537 || value > 65535) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 16-bit range.")); + value &= 0x00ff; + bfd_putb16 ((bfd_vma) value | opcode, (void *) where); + break; + case BFD_RELOC_XGATE_IMM3: + if (value < 0 || value > 7) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 3-bit range.")); + value <<= 8; /* make big endian */ + number_to_chars_bigendian (where, (opcode | value), 2); + break; + case BFD_RELOC_XGATE_IMM4: + if (value < 0 || value > 15) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 4-bit range.")); + value <<= 4; /* align the operand bits */ + number_to_chars_bigendian (where, (opcode | value), 2); + break; + case BFD_RELOC_XGATE_IMM5: + if (value < 0 || value > 31) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Value out of 5-bit range.")); + value <<= 5; /* align the operand bits */ + number_to_chars_bigendian (where, (opcode | value), 2); + break; + case BFD_RELOC_8: + ((bfd_byte *) where)[0] = (bfd_byte) value; + break; + case BFD_RELOC_32: + bfd_putb32 ((bfd_vma) value, (unsigned char *) where); + /* todo figure out how to make BFD_RELOC_16 the default */ + break; + case BFD_RELOC_16: + bfd_putb16 ((bfd_vma) value, (unsigned char *) where); + break; + default: + as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line, + fixP->fx_r_type); + break; + } +} + +/* See whether we need to force a relocation into the output file. */ + +int +tc_xgate_force_relocation (fixS * fixP) +{ + if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP) + return 1; + return generic_force_reloc (fixP); +} + +/* Here we decide which fixups can be adjusted to make them relative + to the beginning of the section instead of the symbol. Basically + we need to make sure that the linker relaxation is done + correctly, so in some cases we force the original symbol to be + used. */ + +int +tc_xgate_fix_adjustable (fixS * fixP) +{ + switch (fixP->fx_r_type) + { + /* For the linker relaxation to work correctly, these relocs + need to be on the symbol itself. */ + case BFD_RELOC_16: + case BFD_RELOC_XGATE_RL_JUMP: + case BFD_RELOC_XGATE_RL_GROUP: + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + case BFD_RELOC_32: + return 0; + default: + return 1; + } +} + +void +md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, + asection * sec ATTRIBUTE_UNUSED, + fragS * fragP ATTRIBUTE_UNUSED) +{ + as_bad (("md_convert_frag not implemented yet")); + abort (); +} + +/* Set the ELF specific flags. */ + +void +xgate_elf_final_processing (void) +{ + elf_flags |= EF_XGATE_MACH; + elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI; + elf_elfheader (stdoutput)->e_flags |= elf_flags; +} + +static inline char * +skip_whitespace (char *s) +{ + while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')') + s++; + + return s; +} + +/* Extract a word (continuous alpha-numeric chars) from the input line. */ + +static char * +extract_word (char *from, char *to, int limit) +{ + char *op_end; + int size = 0; + + /* Drop leading whitespace. */ + from = skip_whitespace (from); + *to = 0; + /* Find the op code end. */ + for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);) + { + to[size++] = *op_end++; + if (size + 1 >= limit) + break; + } + to[size] = 0; + return op_end; +} + +static char * +xgate_new_instruction (int size) +{ + char *f = frag_more (size); + dwarf2_emit_insn (size); + return f; +} + +unsigned short +xgate_apply_operand (unsigned short new_mask, + unsigned short *availiable_mask_bits, + unsigned short mask, + unsigned char n_bits) +{ + unsigned short n_shifts; + unsigned int n_drop_bits; + + /* Shift until you find an available operand bit "1" and record the number of shifts. */ + for (n_shifts = 0; + !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16; + n_shifts++) + *availiable_mask_bits <<= 1; + + /* Shift for the number of bits your operand requires while bits are available. */ + for (n_drop_bits = n_bits; + n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT); + --n_drop_bits) + *availiable_mask_bits <<= 1; + + if (n_drop_bits) + as_bad (_(":operand has too many bits")); + *availiable_mask_bits >>= n_shifts + n_bits; + if ((n_drop_bits == 0) && (*availiable_mask_bits == 0)) + { + oper_check = 1; /* flag operand check as good */ + } + new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits); + mask |= new_mask; + return mask; +} + +/* Parse ordinary expression. */ + +static char * +xgate_parse_exp (char *s, expressionS * op) +{ + input_line_pointer = s; + expression(op); + if (op->X_op == O_absent) + as_bad (_("missing operand")); + return input_line_pointer; +} + +/* For testing. Comment out to prevent defined but not used warning + +static unsigned int +xgate_get_constant(char *str, int max) +{ + expressionS ex; + + str = skip_whitespace(str); + input_line_pointer = str; + expression (& ex); + + if (ex.X_op != O_constant) + as_bad(_("constant value required")); + + if (ex.X_add_number > max || ex.X_add_number < 0) + as_bad(_("number must be positive and less than %d"), max + 1); + + return ex.X_add_number; +} +*/ + +static int +cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2) +{ + return strcmp (op1->name, op2->name); +} + +/* Parse instruction operands. */ + +void +xgate_operands (struct xgate_opcode *opcode, char **line) +{ + char *frag = xgate_new_instruction (opcode->size); + int where = frag - frag_now->fr_literal; + char *op = opcode->constraints; + unsigned int bin = (int) opcode->bin_opcode; + char *str = *line; + unsigned short oper_mask = 0; + int operand_bit_length = 0; + unsigned int operand = 0; + char n_operand_bits = 0; + char first_operand_equals_second = 0; + int i = 0; + char c = 0; + + /* Generate available operand bits mask. */ + for (i = 0; (c = opcode->format[i]); i++) + { + if (ISDIGIT (c) || (c == 's')) + { + oper_mask <<= 1; + } + else + { + oper_mask <<= 1; + oper_mask += 1; + n_operand_bits++; + } + } + + /* Opcode has operands. */ + /* Parse first operand. */ + if (*op) + { + if (*op == '=') + { + first_operand_equals_second = 1; + ++op; + } + operand = xgate_operand (opcode, &operand_bit_length, where, &op, &str); + ++op; + bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length); + /* Parse second operand. */ + if (*op) + { + if (*op == ',') + ++op; + str = skip_whitespace (str); + if (*str++ != ',') + { + if (first_operand_equals_second) + { + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + ++op; + } + else + { + as_bad (_("`,' required before second operand")); + } + } + else + { + str = skip_whitespace (str); + operand = xgate_operand (opcode, &operand_bit_length, where, &op, + &str); + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + ++op; + } + } + + /* Parse the third register. */ + if (*op) + { + if (*op == ',') + ++op; + str = skip_whitespace (str); + if (*str++ != ',') + as_bad (_("`,' required before third operand")); + str = skip_whitespace (str); + operand = xgate_operand (opcode, &operand_bit_length, where, &op, + &str); + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + } + } + if (opcode->size == 2 && fixup_required) + { + bfd_putl16 (bin, frag); + } + else if ((opcode->sh_format & XG_PCREL)) + { + /* Write our data to a frag for further processing. */ + bfd_putl16 (opcode->bin_opcode, frag); + } + else + { + /* Apply operand mask(s)to bin opcode and write the output. */ + /* Since we are done write this frag in xgate BE format. */ + number_to_chars_bigendian (frag, bin, opcode->size); + } + prev = bin; + *line = str; + return; +} + +static unsigned int +xgate_operand (struct xgate_opcode *opcode, + int *bit_width, + int where, + char **op_con, + char **line) +{ + expressionS op_expr; + fixS *fixp = 0; + char *op_constraint = *op_con; + unsigned int op_mask = 0; + char *str = skip_whitespace (*line); + char r_name[20] = + { 0 }; + unsigned int pp_fix = 0; + unsigned short max_size = 0; + int i; + + *bit_width = 0; + /* Reset. */ + + switch (*op_constraint) + { + case '+': /* Indexed register operand +/- or plain r. */ + /* TODO should be able to combine with with case R. */ + + /* Default to neither inc or dec. */ + pp_fix = 0; + *bit_width = 5; + str = skip_whitespace (str); + while (*str != ' ' && *str != '\t') + { + if (*str == '-') + pp_fix = DECREMENT; + else if (*str == '+') + pp_fix = INCREMENT; + else if (*str == 'r' || *str == 'R') + { + str = extract_word (str, r_name, sizeof(r_name)); + if (ISDIGIT (r_name[1])) + { + if (r_name[2] == '\0' && (r_name[1] - '0' < 8)) + op_mask = r_name[1] - '0'; + if (r_name[2] != '\0' && (r_name[1] - '0' > 7)) + as_bad (_(": expected register name r0-r7 read %s"), r_name); + continue; + } + } + str++; + } + op_mask <<= 2; + op_mask |= pp_fix; + break; + + case 'r': /* Register operand. */ + if (*str == 'r' || *str == 'R') + { + *bit_width = 3; + str = extract_word (str, r_name, sizeof(r_name)); + op_mask = 0xff; + if (ISDIGIT (r_name[1])) + { + if (r_name[2] == '\0') + op_mask = r_name[1] - '0'; + else if (r_name[1] != '0' && ISDIGIT (r_name[2]) + && r_name[3] == '\0') + op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0'; + if (op_mask > MAXREGISTER) + as_bad (_(": expected register name r0-r7 read %s "), r_name); + } + } + else + { + as_bad (_(": expected register name r0-r7 read %s "), r_name); + } + break; + + case 'i': /* Immediate value or expression expected. */ + /* Advance the original format pointer. */ + (*op_con)++; + op_constraint++; + if (ISDIGIT (*op_constraint)) + { + *bit_width = (int) *op_constraint - '0'; + } + else if (*op_constraint == 'a') + { + *bit_width = 0x0A; + } + else if (*op_constraint == 'f') + { + *bit_width = 0x0F; + } + /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */ + if (*str == '#') + str++; + str = xgate_parse_exp (str, &op_expr); + if (op_expr.X_op == O_constant) + { + if (!ISDIGIT (*op_constraint)) + as_bad ( + _(":expected bit length with constraint type i(# immediate) read %c"), + *op_constraint); + op_mask = op_expr.X_add_number; + if ((opcode->name[strlen (opcode->name) - 1] == 'l') && macroClipping) + { + op_mask &= 0x00FF; + } + else if ((opcode->name[strlen (opcode->name) - 1]) == 'h' + && macroClipping) + { + op_mask >>= 8; + } + + /* Make sure it fits. */ + for (i = *bit_width; i; i--) + { + max_size <<= 1; + max_size += 1; + } + if (op_mask > max_size) + as_bad (_(":operand value(%d) too big for constraint"), op_mask); + } + else + { + fixup_required = 1; + if (*op_constraint == '8') + { + if ((opcode->name[strlen (opcode->name) - 1] == 'l') + && macroClipping) + { + fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE, + BFD_RELOC_XGATE_24); + /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix. */ + fixp->fx_pcrel_adjust = 0; + } + if ((opcode->name[strlen (opcode->name) - 1]) == 'h' + && macroClipping) + { + fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE, + BFD_RELOC_XGATE_IMM8_HI); + fixp->fx_pcrel_adjust = 0; + } + if (!fixp) + as_bad (_(":unknown relocation")); + } + else if (*op_constraint == '5') + { + fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE, + BFD_RELOC_XGATE_IMM5); + fixp->fx_pcrel_adjust = 0; + } + else if (*op_constraint == '4') + { + fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE, + BFD_RELOC_XGATE_IMM4); + fixp->fx_pcrel_adjust = 0; + } + else if (*op_constraint == '3') + { + fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE, + BFD_RELOC_XGATE_IMM3); + fixp->fx_pcrel_adjust = 0; + } + else + { + as_bad (_(":unknown relocation constraint size")); + } + } + break; + + case 'c': /* CCR register expected. */ + if (*str == 'c' || *str == 'C') + { + *bit_width = 0; + str = extract_word (str, r_name, sizeof(r_name)); + if (!(strcmp (r_name, "ccr") || strcmp (r_name, "CCR"))) + as_bad (_(": expected register name ccr read %s "), r_name); + } + else + { + as_bad (_(": expected character c or C read %c"), *str); + } + break; + + case 'p': /* PC register expected. */ + if (*str == 'p' || *str == 'P') + { + *bit_width = 0; + str = extract_word (str, r_name, sizeof(r_name)); + if (!(strcmp (r_name, "pc") || strcmp (r_name, "PC"))) + as_bad (_(": expected register name pc read %s "), r_name); + } + else + { + as_bad (_(": expected character p or P read %c "), *str); + } + break; + + case 'b': /* Branch expected. */ + str = xgate_parse_exp (str, &op_expr); + (*op_con)++; + op_constraint++; + if (op_expr.X_op != O_register) + { + if (*op_constraint == '9') + { + /* mode == M68XG_OP_REL9 */ + fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE, + R_XGATE_PCREL_9); + fixp->fx_pcrel_adjust = 1; + } + else if (*op_constraint == 'a') + { /* mode == M68XG_OP_REL10 */ + fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE, + R_XGATE_PCREL_10); + fixp->fx_pcrel_adjust = 1; + } + } + else + { + as_fatal (_("Operand `%x' not recognized in fixup8."), op_expr.X_op); + } + break; + + case '?': + break; + + default: + as_bad (_("unknown constraint `%c'"), *op_constraint); + break; + } + *line = str; + return op_mask; +} + +unsigned int +xgate_detect_format (char *line_in) +{ + char num_operands = 0; + char *str = skip_whitespace (line_in); + int i = 0; + int j = 0; + char c = 0; + unsigned int stripped_length = 0; + char sh_format[10] = + { 0 }; /* Shorthand format. */ + char operands_stripped[3][20] = + { + { 0 } + }; + /* Strings. TODO maybe structure this. */ + char *i_string = + { "i" }; + char *r_string = + { "r" }; + char *r_r_string = + { "r,r" }; + char *r_r_r_string = + { "r,r,r" }; + char *r_i_string = + { "r,i" }; + char *r_c_string = + { "r,c" }; + char *c_r_string = + { "c,r" }; + char *r_p_string = + { "r,p" }; + char *r_r_i_string = + { "r,r,i" }; + + /* If the length is zero this is an inherent instruction. */ + if (strlen (str) == 0) + return XG_INH; + + for (i = 0, j = 0, num_operands = 1; (c = TOLOWER (*str)) != 0; str++) + { + if (c == ' ' || c == '\t' || c == '(' || c == ')' || c == '-' || c == '+') + continue; + + if (c == ',') + { + j++; + num_operands++; + i = 0; + continue; + } + + if (i > MAX_DETECT_CHARS) + continue; + + operands_stripped[j][i++] = c; + } + + /* Process our substrings to see what we have. */ + for (i = 0, j = 0; num_operands > i; i++) + { + stripped_length = strlen (&operands_stripped[i][0]); + + /* Add separator if we have more than one operand. */ + if (i > 0) + sh_format[j++] = ','; + + /* Try to process by length first. */ + if (stripped_length > 3) + { + sh_format[j++] = 'i'; + } + else if (stripped_length == 1) + { + sh_format[j++] = 'i'; + } + else if (stripped_length == 2) + { + if (operands_stripped[i][0] + == 'r' && ISDIGIT (operands_stripped[i][1])) + { + sh_format[j++] = 'r'; + } + else if (operands_stripped[i][0] == 'p' + && operands_stripped[i][1] == 'c') + { + sh_format[j++] = 'p'; + } + else + { + sh_format[j++] = 'i'; + } + } + else if (stripped_length == 3) + { + if (operands_stripped[i][0] == 'c' + && (operands_stripped[i][1] == 'c' + && operands_stripped[i][2] == 'r')) + { + sh_format[j++] = 'c'; + } + else if (operands_stripped[i][0] == '#') + { + sh_format[j++] = 'i'; + } + else + { + sh_format[j++] = 'i'; + } + } + else /* default to immediate */ + { + sh_format[j++] = 'i'; + } + } + + /* See if we have a match. */ + if (!strcmp (i_string, sh_format) && num_operands == 1) + return XG_I; + if (!strcmp (r_i_string, sh_format) && num_operands == 2) + return XG_R_I; + if (!strcmp (r_r_r_string, sh_format) && num_operands == 3) + return XG_R_R_R; + if (!strcmp (r_r_string, sh_format) && num_operands == 2) + return XG_R_R; + if (!strcmp (r_string, sh_format) && num_operands == 1) + return XG_R; + if (!strcmp (r_c_string, sh_format) && num_operands == 2) + return XG_R_C; + if (!strcmp (c_r_string, sh_format) && num_operands == 2) + return XG_C_R; + if (!strcmp (r_p_string, sh_format) && num_operands == 2) + return XG_R_P; + if (!strcmp (r_r_i_string, sh_format) && num_operands == 3) + return XG_R_R_I; + + return 0; +} + +static struct xgate_opcode * +xgate_find_match (struct xgate_opcode_handle *opcode_handle, + int numberOfModes, + unsigned int sh_format) +{ + int i; + + if (numberOfModes == 0) + return opcode_handle->opc0[0]; + + for (i = 0; i <= numberOfModes; i++) + if (opcode_handle->opc0[i]->sh_format & sh_format) + return opcode_handle->opc0[i]; + + return NULL; +} diff --git a/gas/config/tc-xgate.h b/gas/config/tc-xgate.h new file mode 100644 index 0000000000..7f414e5831 --- /dev/null +++ b/gas/config/tc-xgate.h @@ -0,0 +1,111 @@ +/* tc-xgate.h -- Header file for tc-xgate.c. + Copyright 2010, 2011, 2012 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS 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. + + GAS 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 GAS; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#define TC_XGATE +#define cpuxgate 1 + +struct fix; + +/* Define TC_M68K so that we can use the MRI mode. */ +#define TC_M68K + +#define TARGET_BYTES_BIG_ENDIAN 1 + +/* Motorola assembler specs does not require '.' before pseudo-ops. */ +#define NO_PSEUDO_DOT 1 + +/* The target BFD architecture. */ +#define TARGET_ARCH (xgate_arch ()) +extern enum bfd_architecture xgate_arch (void); + +#define TARGET_MACH (xgate_mach ()) +extern int xgate_mach (void); + +#define TARGET_FORMAT (xgate_arch_format ()) +extern const char *xgate_arch_format (void); + +#define LISTING_WORD_SIZE 1 /* A word is 1 bytes. */ +#define LISTING_LHS_WIDTH 4 /* One word on the first line. */ +#define LISTING_LHS_WIDTH_SECOND 4 /* One word on the second line. */ +#define LISTING_LHS_CONT_LINES 4 /* And 4 lines max. */ +#define LISTING_HEADER xgate_listing_header () +extern const char *xgate_listing_header (void); + +/* Permit temporary numeric labels. */ +#define LOCAL_LABELS_FB 1 + +#define tc_init_after_args xgate_init_after_args +extern void xgate_init_after_args (void); + +#define md_parse_long_option xgate_parse_long_option +extern int xgate_parse_long_option (char *); + +#define DWARF2_LINE_MIN_INSN_LENGTH 1 + +/* Use 32-bit address to represent a symbol address so that we can + represent them with their page number. */ +#define DWARF2_ADDR_SIZE(bfd) 4 + +/* We don't need to handle .word strangely. */ +#define WORKING_DOT_WORD + +#define md_number_to_chars number_to_chars_bigendian + +/* Relax table to translate short relative branches (-128..127) into + absolute branches. */ +#define TC_GENERIC_RELAX_TABLE md_relax_table +extern struct relax_type md_relax_table[]; + +/* GAS only handles relaxations for pc-relative data targeting addresses + in the same segment, we have to encode all other cases */ +/* FIXME: impliment this. */ +/* #define md_relax_frag(SEG, FRAGP, STRETCH) \ + ((FRAGP)->fr_symbol != NULL \ + && S_GET_SEGMENT ((FRAGP)->fr_symbol) == (SEG) \ + ? relax_frag (SEG, FRAGP, STRETCH) \ + : xgate_relax_frag (SEG, FRAGP, STRETCH)) +extern long xgate_relax_frag (segT, fragS*, long); */ + +#define TC_HANDLES_FX_DONE + +#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ + +/* Values passed to md_apply_fix don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +#define TC_FORCE_RELOCATION(fix) tc_xgate_force_relocation (fix) +extern int tc_xgate_force_relocation (struct fix *); + +#define tc_fix_adjustable(X) tc_xgate_fix_adjustable(X) +extern int tc_xgate_fix_adjustable (struct fix *); + +#define md_operand(x) + +#define elf_tc_final_processing xgate_elf_final_processing +extern void xgate_elf_final_processing (void); + +#if 0 +#define tc_print_statistics(FILE) xgate_print_statistics (FILE) +extern void xgate_print_statistics (FILE *); +#endif diff --git a/gas/configure.tgt b/gas/configure.tgt index 781cc9dd02..99de3d74c4 100644 --- a/gas/configure.tgt +++ b/gas/configure.tgt @@ -86,6 +86,7 @@ case ${cpu} in tilegx*) cpu_type=tilegx endian=little ;; v850*) cpu_type=v850 ;; x86_64*) cpu_type=i386 arch=x86_64;; + xgate) cpu_type=xgate ;; xtensa*) cpu_type=xtensa arch=xtensa ;; *) cpu_type=${cpu} ;; esac @@ -418,6 +419,8 @@ case ${generic_target} in vax-*-linux-*) fmt=elf em=linux ;; xstormy16-*-*) fmt=elf ;; + + xgate-*-*) fmt=elf ;; xtensa*-*-*) fmt=elf ;; diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am index 34ccae5c5a..1fd3e1b4fe 100644 --- a/gas/doc/Makefile.am +++ b/gas/doc/Makefile.am @@ -72,6 +72,7 @@ CPU_DOCS = \ c-tilepro.texi \ c-vax.texi \ c-v850.texi \ + c-xgate.texi \ c-xstormy16.texi \ c-xtensa.texi \ c-z80.texi \ diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in index e9edb0ea6f..375e513bbd 100644 --- a/gas/doc/Makefile.in +++ b/gas/doc/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/gettext-sister.m4 \ $(top_srcdir)/../config/largefile.m4 \ + $(top_srcdir)/../config/lcmessage.m4 \ $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/nls.m4 \ $(top_srcdir)/../config/override.m4 \ @@ -312,6 +313,7 @@ CPU_DOCS = \ c-tilepro.texi \ c-vax.texi \ c-v850.texi \ + c-xgate.texi \ c-xstormy16.texi \ c-xtensa.texi \ c-z80.texi \ diff --git a/gas/doc/all.texi b/gas/doc/all.texi index 63282f2390..9a55441cb3 100644 --- a/gas/doc/all.texi +++ b/gas/doc/all.texi @@ -72,6 +72,7 @@ @set TILEPRO @set V850 @set VAX +@set XGATE @set XSTORMY16 @set XTENSA @set Z80 diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index a648f094a2..034cc92fe4 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -7029,6 +7029,9 @@ subject, see the hardware manufacturer's manual. @ifset V850 * V850-Dependent:: V850 Dependent Features @end ifset +@ifset XGATE +* XGATE-Dependent:: XGATE Features +@end ifset @ifset XSTORMY16 * XSTORMY16-Dependent:: XStormy16 Dependent Features @end ifset @@ -7256,6 +7259,10 @@ family. @include c-v850.texi @end ifset +@ifset XGATE +@include c-xgate.texi +@end ifset + @ifset XSTORMY16 @include c-xstormy16.texi @end ifset diff --git a/gas/doc/c-xgate.texi b/gas/doc/c-xgate.texi new file mode 100644 index 0000000000..dc802a01f7 --- /dev/null +++ b/gas/doc/c-xgate.texi @@ -0,0 +1,209 @@ +@c Copyright 2012 +@c Free Software Foundation, Inc. +@c This is part of the GAS manual. +@c For copying conditions, see the file as.texinfo. +@ifset GENERIC +@page +@node XGATE-Dependent +@chapter XGATE Dependent Features +@end ifset +@ifclear GENERIC +@node Machine Dependencies +@chapter XGATE Dependent Features +@end ifclear + +@cindex XGATE support +@menu +* XGATE-Opts:: XGATE Options +* XGATE-Syntax:: Syntax +* XGATE-Directives:: Assembler Directives +* XGATE-Float:: Floating Point +* XGATE-opcodes:: Opcodes +@end menu + +@node XGATE-Opts +@section XGATE Options + +@cindex options, XGATE +@cindex XGATE options +The Freescale XGATE version of @code{@value{AS}} has a few machine +dependent options. + +@table @code + +@cindex @samp{-mshort} +@item -mshort +This option controls the ABI and indicates to use a 16-bit integer ABI. +It has no effect on the assembled instructions. +This is the default. + +@cindex @samp{-mlong} +@item -mlong +This option controls the ABI and indicates to use a 32-bit integer ABI. + +@cindex @samp{-mshort-double} +@item -mshort-double +This option controls the ABI and indicates to use a 32-bit float ABI. +This is the default. + +@cindex @samp{-mlong-double} +@item -mlong-double +This option controls the ABI and indicates to use a 64-bit float ABI. + +@cindex @samp{--print-insn-syntax} +@item --print-insn-syntax +You can use the @samp{--print-insn-syntax} option to obtain the +syntax description of the instruction when an error is detected. + +@cindex @samp{--print-opcodes} +@item --print-opcodes +The @samp{--print-opcodes} option prints the list of all the +instructions with their syntax. Once the list is printed +@code{@value{AS}} exits. + +@end table + +@node XGATE-Syntax +@section Syntax + +@cindex XGATE syntax +@cindex syntax, XGATE + +In XGATE RISC syntax, the instruction name comes first and it may +be followed by up to three operands. Operands are separated by commas +(@samp{,}). @code{@value{AS}} will complain if too many operands are specified +for a given instruction. The same will happen if you specified too few + operands. + +@smallexample +nop +ldl #23 +CMP R1, R2 +@end smallexample + +@cindex line comment character, XGATE +@cindex XGATE line comment character +The presence of a @samp{;} character or a @samp{!} character anywhere +on a line indicates the start of a comment that extends to the end of +that line. + +A @samp{*} or a @samp{#} character at the start of a line also +introduces a line comment, but these characters do not work elsewhere +on the line. If the first character of the line is a @samp{#} then as +well as starting a comment, the line could also be logical line number +directive (@pxref{Comments}) or a preprocessor control command +(@pxref{Preprocessing}). + +@cindex line separator, XGATE +@cindex statement separator, XGATE +@cindex XGATE line separator +The XGATE assembler does not currently support a line separator +character. + +@cindex XGATE addressing modes +@cindex addressing modes, XGATE +The following addressing modes are understood for XGATE: +@table @dfn +@item Inherent +@samp{} + +@item Immediate 3 Bit Wide +@samp{#@var{number}} + +@item Immediate 4 Bit Wide +@samp{#@var{number}} + +@item Immediate 8 Bit Wide +@samp{#@var{number}} + +@item Monadic Addressing +@samp{@var{reg}} + +@item Dyadic Addressing +@samp{@var{reg}, @var{reg}} + +@item Triadic Addressing +@samp{@var{reg}, @var{reg}, @var{reg}} + +@item Relative Addressing 9 Bit Wide +@samp{*@var{symbol}} + +@item Relative Addressing 10 Bit Wide +@samp{*@var{symbol}} + +@item Index Register plus Immediate Offset +@samp{@var{reg}, (@var{reg}, #@var{number})} + +@item Index Register plus Register Offset +@samp{@var{reg}, @var{reg}, @var{reg}} + +@item Index Register plus Register Offset with Post-increment +@samp{@var{reg}, @var{reg}, @var{reg}+} + +@item Index Register plus Register Offset with Pre-decrement +@samp{@var{reg}, @var{reg}, -@var{reg}} + +The register can be either @samp{R0}, @samp{R1}, @samp{R2}, @samp{R3}, +@samp{R4}, @samp{R5}, @samp{R6} or @samp{R7}. + +@end table + +Convience macro opcodes to deal with 16-bit values have been added. + +@table @dfn + +@item Immediate 16 Bit Wide +@samp{#@var{number}}, or @samp{*@var{symbol}} + +For example: + +@smallexample +ldw R1, #1024 +ldw R3, timer +ldw R1, (R1, #0) +COM R1 +stw R2, (R1, #0) +@end smallexample +@end table + +@node XGATE-Directives +@section Assembler Directives + +@cindex assembler directives, XGATE +@cindex XGATE assembler directives + +The XGATE version of @code{@value{AS}} have the following +specific assembler directives: + +@node XGATE-Float +@section Floating Point + +@cindex floating point, XGATE +@cindex XGATE floating point +Packed decimal (P) format floating literals are not supported(yet). + +The floating point formats generated by directives are these. + +@table @code +@cindex @code{float} directive, XGATE +@item .float +@code{Single} precision floating point constants. + +@cindex @code{double} directive, XGATE +@item .double +@code{Double} precision floating point constants. + +@cindex @code{extend} directive XGATE +@cindex @code{ldouble} directive XGATE +@item .extend +@itemx .ldouble +@code{Extended} precision (@code{long double}) floating point constants. +@end table + +@need 2000 +@node XGATE-opcodes +@section Opcodes + +@cindex XGATE opcodes +@cindex instruction set, XGATE + diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 76f3dc1ee0..9d394a3da1 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2012-05-03 Sean Keys + + * gas/all/gas.exp: Added xgate tex entry. + * gas/xgate/abi-xgate-16-32.d: Simple ABI flag test. + * gas/xgate/abi-xgate-16-64.d: Ditto + * gas/xgate/abi-xgate-32-32.d: Ditto + * gas/xgate/abi-xgate-32-64.d: Ditto + * gas/xgate/abi.s: Source file for ABI tests. + * gas/xgate/all_insns.d: Dump file for all instructions test. + * gas/xgate/all_insns.s: Source file for all instructions test. + * gas/xgate/insns-dwarf2.d: Dump file for dwarf2 test. + * gas/xgate/insns.d: Dump file for instructions test. + * gas/xgate/insns.s: Source file for instructions test. + * gas/xgate/xgate.exp: XGATE tests file. + 2012-04-27 David S. Miller * gas/sparc/sparc.exp: Run cfr test. diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp index 7026811e84..2cef5ddd59 100644 --- a/gas/testsuite/gas/all/gas.exp +++ b/gas/testsuite/gas/all/gas.exp @@ -133,10 +133,10 @@ case $target_triplet in { # These targets fail redef2 because they disallow redefined # symbols on relocs. setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" - setup_xfail "rx-*-*" "vax*-*-*" "z8k-*-*" + setup_xfail "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*" run_dump_test redef2 setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*" - setup_xfail "rx-*-*" "vax*-*-*" "z8k-*-*" + setup_xfail "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*" # rs6000-aix disallows redefinition via .comm. setup_xfail "*-*-aix*" # SOM uses a different syntax for .comm diff --git a/gas/testsuite/gas/xgate/abi-xgate-16-32.d b/gas/testsuite/gas/xgate/abi-xgate-16-32.d new file mode 100644 index 0000000000..a2368d8704 --- /dev/null +++ b/gas/testsuite/gas/xgate/abi-xgate-16-32.d @@ -0,0 +1,8 @@ +#objdump: -p +#as: -mshort-double +#name: Elf flags XGATE 16-bit int, 32-bit double +#source: abi.s + +.*: +file format elf32\-xgate +private flags = 80:\[abi=16-bit int, 32-bit double, cpu=XGATE\] + diff --git a/gas/testsuite/gas/xgate/abi-xgate-16-64.d b/gas/testsuite/gas/xgate/abi-xgate-16-64.d new file mode 100644 index 0000000000..185cb6b472 --- /dev/null +++ b/gas/testsuite/gas/xgate/abi-xgate-16-64.d @@ -0,0 +1,7 @@ +#objdump: -p +#as: +#name: Elf flags XGATE 16-bit int, 64-bit double +#source: abi.s + +.*: +file format elf32\-xgate +private flags = 82:\[abi=16-bit int, 64-bit double, cpu=XGATE\] diff --git a/gas/testsuite/gas/xgate/abi-xgate-32-32.d b/gas/testsuite/gas/xgate/abi-xgate-32-32.d new file mode 100644 index 0000000000..5ba4b650d9 --- /dev/null +++ b/gas/testsuite/gas/xgate/abi-xgate-32-32.d @@ -0,0 +1,7 @@ +#objdump: -p +#as: -mlong -mshort-double +#name: Elf flags XGATE 32-bit int, 32-bit double +#source: abi.s + +.*: +file format elf32\-xgate +private flags = 81:\[abi=32-bit int, 32-bit double, cpu=XGATE\] diff --git a/gas/testsuite/gas/xgate/abi-xgate-32-64.d b/gas/testsuite/gas/xgate/abi-xgate-32-64.d new file mode 100644 index 0000000000..e454c219e3 --- /dev/null +++ b/gas/testsuite/gas/xgate/abi-xgate-32-64.d @@ -0,0 +1,7 @@ +#objdump: -p +#as: -mlong +#name: Elf flags XGATE 32-bit int, 64-bit double +#source: abi.s + +.*: +file format elf32\-xgate +private flags = 83:\[abi=32-bit int, 64-bit double, cpu=XGATE\] diff --git a/gas/testsuite/gas/xgate/abi.s b/gas/testsuite/gas/xgate/abi.s new file mode 100644 index 0000000000..a5016ebe63 --- /dev/null +++ b/gas/testsuite/gas/xgate/abi.s @@ -0,0 +1,4 @@ + .sect .text + .globl L1 +L1: + rts diff --git a/gas/testsuite/gas/xgate/all_insns.d b/gas/testsuite/gas/xgate/all_insns.d new file mode 100644 index 0000000000..94690de93b --- /dev/null +++ b/gas/testsuite/gas/xgate/all_insns.d @@ -0,0 +1,130 @@ +#objdump: -d --prefix-addresses --reloc +#as: +#name: all_insns + +# Test handling of basic instructions. + +.*: +file format elf32\-xgate + +Disassembly of section .text: +0+0000 adc R1, R2, R3 +0+0002 bcc \*228 Abs\* 0x000000e6 +0+0004 add R4, R5, R6 +0+0006 addl R7, #0xe1 +0+0008 addh R7, #0x00 Abs\* 0x000000e1 +0+000a addh R1, #0xff +0+000c addl R2, #0xff Abs\* 0x0000ffff +0+000e addl R4, #0x44 +0+0010 addh R4, #0x1f Abs\* 0x00001f44 +0+0012 and R3, R4, R5 +0+0014 andl R1, #0x04 +0+0016 andh R1, #0x80 Abs\* 0x00008004 +0+0018 addl R5, #0xe6 + 18: R_XGATE_IMM8_LO .text +0+001a addh R5, #0x00 Abs\* 0x000000e6 + 1a: R_XGATE_IMM8_HI .text +0+001c andl R7, #0xe6 + 1c: R_XGATE_IMM8_LO .text +0+001e andh R7, #0x00 Abs\* 0x000000e6 + 1e: R_XGATE_IMM8_HI .text +0+0020 andl R4, #0x01 +0+0022 andh R4, #0xff Abs\* 0x0000ff01 +0+0024 andl R3, #0x01 +0+0026 andh R6, #0xff Abs\* 0x0000ff01 +0+0028 asr R0, #0x03 +0+002a asr R1, R2 +0+002c bcc \*186 Abs\* 0x000000e6 +0+002e bcs \*184 Abs\* 0x000000e6 +0+0030 beq \*182 Abs\* 0x000000e6 +0+0032 bfext R3, R4, R5 +0+0034 bffo R6, R7 +0+0036 bfins R0, R1, R2 +0+0038 bfinsi R3, R4, R5 +0+003a bfinsx R6, R7, R0 +0+003c bge \*170 Abs\* 0x000000e6 +0+003e bgt \*168 Abs\* 0x000000e6 +0+0040 bhi \*166 Abs\* 0x000000e6 +0+0042 bcc \*164 Abs\* 0x000000e6 +0+0044 bith R1, #0x20 +0+0046 bitl R2, #0x00 +0+0048 ble \*158 Abs\* 0x000000e6 +0+004a bcs \*156 Abs\* 0x000000e6 +0+004c bls \*154 Abs\* 0x000000e6 +0+004e blt \*152 Abs\* 0x000000e6 +0+0050 bmi \*150 Abs\* 0x000000e6 +0+0052 bne \*148 Abs\* 0x000000e6 +0+0054 bpl \*146 Abs\* 0x000000e6 +0+0056 bra \*144 Abs\* 0x000000e6 + ... +0+005a bvc \*140 Abs\* 0x000000e6 +0+005c bvs \*138 Abs\* 0x000000e6 +0+005e sub R0, R1, R2 +0+0060 cmpl R3, #0xff +0+0062 xnor R4, R0, R5 +0+0064 sbc R0, R6, R7 +0+0066 cmpl R1, #0xff Abs\* 0x0000ffdd +0+0068 cpch R1, #0xff +0+006a cpch R2, #0xff Abs\* 0x0000ffff +0+006c csem #0x4 +0+006e csem R5 +0+0070 csl R6, #0x0b +0+0072 csl R7, R0 +0+0074 csr R1, #0x02 +0+0076 csr R2, R3 +0+0078 jal R4 +0+007a ldb R5, \(R6, #0x14\) +0+007c ldb R7, \(R0, R1\+\) +0+007e ldb R7, \(R0, \-R1\) +0+0080 ldb R0, \(R0, R0\) +0+0082 ldh R1, #0xff +0+0084 ldl R2, #0xff Abs\* 0x0000ffff +0+0086 ldl R3, #0xe6 + 86: R_XGATE_IMM8_LO .text +0+0088 ldh R3, #0x00 Abs\* 0x000000e6 + 88: R_XGATE_IMM8_HI .text +0+008a ldw R4, \(R5, #0x14\) +0+008c ldw R5, \(R6, R7\+\) +0+008e ldw R5, \(R6, \-R7\) +0+0090 ldw R1, \(R2, R4\) +0+0092 lsl R1, #0x04 +0+0094 lsl R2, R3 +0+0096 lsr R4, #0x05 +0+0098 lsr R5, R6 +0+009a or R6, R0, R7 +0+009c sub R1, R0, R2 +0+009e nop +0+00a0 or R1, R2, R3 +0+00a2 orh R4, #0xff +0+00a4 orl R5, #0xff +0+00a6 par R6 +0+00a8 rol R7, #0x06 +0+00aa rol R1, R2 +0+00ac ror R3, #0x05 +0+00ae ror R4, R5 +0+00b0 rts +0+00b2 sbc R1, R2, R3 +0+00b4 ssem #0x4 +0+00b6 ssem R1 +0+00b8 sex R2 +0+00ba sif +0+00bc sif R4 +0+00be stb R5, \(R6, #0x5\) +0+00c0 stb R0, \(R0, R0\+\) +0+00c2 stb R0, \(R0, \-R0\) +0+00c4 stb R2, \(R0, R0\) +0+00c6 stw R1, \(R2, #0x10\) +0+00c8 stw R1, \(R2, R3\+\) +0+00ca stw R1, \(R2, \-R3\) +0+00cc stw R2, \(R3, R4\) +0+00ce sub R3, R4, R6 +0+00d0 subl R4, #0xff +0+00d2 subh R4, #0xff Abs\* 0x0000ffff +0+00d4 subh R5, #0xff +0+00d6 subl R6, #0xff Abs\* 0x0000ffff +0+00d8 tfr R7, PC +0+00da tfr R7, CCR +0+00dc tfr CCR, R7 +0+00de sub R0, R1, R0 +0+00e0 xnor R1, R2, R3 +0+00e2 xnorh R4, #0xff +0+00e4 xnorl R5, #0xff diff --git a/gas/testsuite/gas/xgate/all_insns.s b/gas/testsuite/gas/xgate/all_insns.s new file mode 100644 index 0000000000..20283e939b --- /dev/null +++ b/gas/testsuite/gas/xgate/all_insns.s @@ -0,0 +1,111 @@ +# Example of XGATE instructions + .sect .text +_start: +L0: adc r1, r2, r3 +L1: bcc END_CODE +L2: add r4, r5, r6 +L3: add r7 , #225 +L4: addh r1, 255 +L5: addl r2, #255 +L6: add r4, 8004 +L7: and r3, r4, r5 +L8: and r1, #0x8004 +L9: add r5, END_CODE +L10: and r7, END_CODE +L11: and r4, #65281 +L12: andl r3, #01 +L13: andh r6, #255 +L14: asr r0, #3 +L15: asr r1, r2 +L16: bcc END_CODE +L17: bcs END_CODE +L18: beq END_CODE +L19: bfext r3, r4, r5 +L20: bffo r6, r7 +L21: bfins r0, r1, r2 +L22: bfinsi r3, r4, r5 +L23: bfinsx r6, r7, r0 +L24: bge END_CODE +L25: bgt END_CODE +L26: bhi END_CODE +L27: bhs END_CODE +L28: bith r1, #32 +L29: bitl r2, #0 +L30: ble END_CODE +L31: blo END_CODE +L32: bls END_CODE +L33: blt END_CODE +L34: bmi END_CODE +L35: bne END_CODE +L36: bpl END_CODE +L37: bra END_CODE +L38: brk +L39: bvc END_CODE +L40: bvs END_CODE +L41: cmp r1, r2 +L42: cmpl r3, #255 +L43: com r4, r5 +L44: cpc r6, r7 +L45: cmp r1, #65535 +L46: cpch r2, #255 +L47: csem #4 +L48: csem r5 +L49: csl r6, #11 +L50: csl r7, r0 +L51: csr r1, #2 +L52: csr r2, r3 +L53: jal r4 +L54: ldb r5, (r6, #20) +L55: ldb r7, (r0, r1+) +L56: ldb r7, (r0, -r1) +L57: ldb r0, (r0, r0) +L58: ldh r1, #255 +L59: ldl r2, #255 +L60: ldd r3, END_CODE +L61: ldw r4, (r5, #20) +L62: ldw r5, (r6, r7+) +L63: ldw r5, (r6, -r7) +L64: ldw r1, (r2, r4) +L65: lsl r1, #4 +L66: lsl r2, r3 +L67: lsr r4, #5 +L68: lsr r5, r6 +L69: mov r6, r7 +L70: neg r1, r2 +L71: nop +L72: or r1, r2, r3 +L73: orh r4, #255 +L74: orl r5, #255 +L75: par r6 +L76: rol r7, #6 +L77: rol r1, r2 +L78: ror r3, #5 +L79: ror r4, r5 +L80: rts +L81: sbc r1, r2, r3 +L82: ssem #4 +L83: ssem r1 +L84: sex r2 +L85: sif +L86: sif r4 +L87: stb r5, (r6, #5) +L88: stb r0, (r0, r0+) +L89: stb r0, (r0, -r0) +L90: stb r2, (r0, r0) +L91: stw r1, (r2, #16) +L92: stw r1, (r2, r3+) +L93: stw r1, (r2, -r3) +L94: stw r2, (r3 ,r4) +L95: sub r3, r4, r6 +L96: sub r4, #65535 +L97: subh r5, #255 +L98: subl r6, #255 +L99: tfr r7, pc +L100: tfr r7,ccr +L101: tfr ccr, r7 +L102: tst r1 +L103: xnor r1, r2, r3 +L104: xnorh r4, #255 +L105: xnorl r5, #255 +END_CODE: + diff --git a/gas/testsuite/gas/xgate/insns-dwarf2.d b/gas/testsuite/gas/xgate/insns-dwarf2.d new file mode 100644 index 0000000000..3a8e6992aa --- /dev/null +++ b/gas/testsuite/gas/xgate/insns-dwarf2.d @@ -0,0 +1,84 @@ +#objdump: -S +#as: -gdwarf2 +#name: Dwarf2 test on insns.s +#source: insns.s + +# Test handling of basic instructions. + +.*: +file format elf32\-xgate + +Disassembly of section .text: + +0+0000 <_start>: + + .globl _start + .sect .text + +_start: + ldw R2, #block\+1024 + 0: f2 00 ldl R2, #0x00 + 2: fa 04 ldh R2, #0x04 Abs\* 0x400 + ldw R3, #block + 4: f3 00 ldl R3, #0x00 + 6: fb 00 ldh R3, #0x00 Abs\* 0x0 <_start> + ldw R1, #1 + 8: f1 01 ldl R1, #0x01 + a: f9 00 ldh R1, #0x00 Abs\* 0x1 <_start\+0x1> + +0+000c : +Loop: + bra test + c: 3c 04 bra \*10 Abs\* 0x16 + nop + e: 01 00 nop + bne Loop + 10: 25 fd bne \*-4 Abs\* 0xc + +0+0012 : + 12: cd 03 subh R5, #0x03 +Stop: + + .byte 0xcd + .byte 3 + bra _start + 14: 3f f5 bra \*-20 Abs\* 0x0 <_start> + +0+0016 : + +test: + ldw R5, #2 + 16: f5 02 ldl R5, #0x02 + 18: fd 00 ldh R5, #0x00 Abs\* 0x2 <_start\+0x2> + bra test2 + 1a: 3c 01 bra \*4 Abs\* 0x1e + rts + 1c: 02 00 rts + +0+001e : + +value = 23 + + .globl test2 +test2: + ldw R3, #value + 1e: f3 17 ldl R3, #0x17 + 20: fb 00 ldh R3, #0x00 Abs\* 0x17 + stw R4, \(R3, #0\) + 22: 5c 60 stw R4, \(R3, #0x0\) + ldw R4, #24\+_start\-44 + 24: f4 ec ldl R4, #0xec + 26: fc ff ldh R4, #0xff Abs\* 0xffec + bra Stop + 28: 3f f4 bra \*-22 Abs\* 0x12 + +0+002a : +L1: + ldw R1, test2 + 2a: f1 1e ldl R1, #0x1e + 2c: f9 00 ldh R1, #0x00 Abs\* 0x1e + ldw R2, test2 + 2e: f2 1e ldl R2, #0x1e + 30: fa 00 ldh R2, #0x00 Abs\* 0x1e + rts + 32: 02 00 rts + diff --git a/gas/testsuite/gas/xgate/insns.d b/gas/testsuite/gas/xgate/insns.d new file mode 100644 index 0000000000..a7d4d58ba1 --- /dev/null +++ b/gas/testsuite/gas/xgate/insns.d @@ -0,0 +1,45 @@ +#objdump: -d --prefix-addresses --reloc +#as: +#name: insns + +# Test handling of basic instructions. + +.*: +file format elf32\-xgate + +Disassembly of section .text: +0+0000 <\_start> ldl R2, #0x00 + 0: R_XGATE_IMM8_LO .bss +0+0002 <\_start\+0x2> ldh R2, #0x04 Abs\* 0x00000400 + 2: R_XGATE_IMM8_HI .bss +0+0004 <\_start\+0x4> ldl R3, #0x00 + 4: R_XGATE_IMM8_LO .bss +0+0006 <\_start\+0x6> ldh R3, #0x00 Abs\* 0x00000000 <\_start> + 6: R_XGATE_IMM8_HI .bss +0+0008 <\_start\+0x8> ldl R1, #0x01 +0+000a <\_start\+0xa> ldh R1, #0x00 Abs\* 0x00000001 <\_start\+0x1> +0+000c bra \*10 Abs\* 0x00000016 +0+000e nop +0+0010 bne \*\-4 Abs\* 0x0000000c +0+0012 subh R5, #0x03 +0+0014 bra \*\-20 Abs\* 0x00000000 <\_start> +0+0016 ldl R5, #0x02 +0+0018 ldh R5, #0x00 Abs\* 0x00000002 <\_start\+0x2> +0+001a bra \*4 Abs\* 0x0000001e +0+001c rts +0+001e ldl R3, #0x17 +0+0020 ldh R3, #0x00 Abs\* 0x00000017 +0+0022 stw R4, \(R3, #0x0\) +0+0024 ldl R4, #0xec + 24: R_XGATE_IMM8_LO .text +0+0026 ldh R4, #0xff Abs\* 0x0000ffec + 26: R_XGATE_IMM8_HI .text +0+0028 bra \*\-22 Abs\* 0x00000012 +0+002a ldl R1, #0x1e + 2a: R_XGATE_IMM8_LO .text +0+002c ldh R1, #0x00 Abs\* 0x0000001e + 2c: R_XGATE_IMM8_HI .text +0+002e ldl R2, #0x1e + 2e: R_XGATE_IMM8_LO .text +0+0030 ldh R2, #0x00 Abs\* 0x0000001e + 30: R_XGATE_IMM8_HI .text +0+0032 rts diff --git a/gas/testsuite/gas/xgate/insns.s b/gas/testsuite/gas/xgate/insns.s new file mode 100644 index 0000000000..e359e683fb --- /dev/null +++ b/gas/testsuite/gas/xgate/insns.s @@ -0,0 +1,43 @@ +# Test for correct generation of XGATE insns. + + .globl _start + .sect .text + +_start: + ldw R2, #block+1024 + ldw R3, #block + ldw R1, #1 +Loop: + bra test + nop + bne Loop +Stop: + + .byte 0xcd + .byte 3 + bra _start + +test: + ldw R5, #2 + bra test2 + rts + +value = 23 + + .globl test2 +test2: + ldw R3, #value + stw R4, (R3, #0) + ldw R4, #24+_start-44 + bra Stop +L1: + ldw R1, test2 + ldw R2, test2 + rts + + .sect .data + + .sect .bss +block: + .space 1024 +block_end: diff --git a/gas/testsuite/gas/xgate/xgate.exp b/gas/testsuite/gas/xgate/xgate.exp new file mode 100644 index 0000000000..1af5e76224 --- /dev/null +++ b/gas/testsuite/gas/xgate/xgate.exp @@ -0,0 +1,19 @@ +# +# Some generic XGATE tests +# + +if ![istarget "xgate-*-*"] then { + return +} + +# ABI tests +run_dump_test abi-xgate-16-64 +run_dump_test abi-xgate-16-32 +run_dump_test abi-xgate-32-64 +run_dump_test abi-xgate-32-32 + +# Some XGATE tests +run_dump_test insns-dwarf2 +run_dump_test all_insns +run_dump_test insns + diff --git a/include/ChangeLog b/include/ChangeLog index e3b1788110..7a747a7cc7 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2012-05-03 Sean Keys + + * dis-asm.h (print_insn_xgate): Define. + (print_insn_xgate): Ditto. + Added new files for XGATE port. + 2012-05-02 Cary Coutant * dwarf2.def: Remove DW_FORM_GNU_ref_index, diff --git a/include/dis-asm.h b/include/dis-asm.h index c9cbfbb321..203b113663 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -293,6 +293,7 @@ extern int print_insn_v850 (bfd_vma, disassemble_info *); extern int print_insn_vax (bfd_vma, disassemble_info *); extern int print_insn_w65 (bfd_vma, disassemble_info *); extern int print_insn_xc16x (bfd_vma, disassemble_info *); +extern int print_insn_xgate (bfd_vma, disassemble_info *); extern int print_insn_xstormy16 (bfd_vma, disassemble_info *); extern int print_insn_xtensa (bfd_vma, disassemble_info *); extern int print_insn_z80 (bfd_vma, disassemble_info *); diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index eb6edc55cc..ab9b2deae3 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2012-05-03 Sean Keys + + * xgate.h: Mininal file to support XGATE relocations. + 2012-04-27 David S. Miller * sparc.h: Add new ELF_SPARC_HWCAP_* defines for crypto, diff --git a/include/elf/xgate.h b/include/elf/xgate.h new file mode 100644 index 0000000000..33286a8d0c --- /dev/null +++ b/include/elf/xgate.h @@ -0,0 +1,77 @@ +/* XGATE ELF support for BFD. + Copyright 2010, 2011, 2012 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 2 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_XGATE_H +#define _ELF_XGATE_H + +#include "elf/reloc-macros.h" + +/* Relocation types. */ +START_RELOC_NUMBERS (elf_xgate_reloc_type) + RELOC_NUMBER (R_XGATE_NONE, 0) + RELOC_NUMBER (R_XGATE_8, 1) + RELOC_NUMBER (R_XGATE_PCREL_8, 2) + RELOC_NUMBER (R_XGATE_16, 3) + RELOC_NUMBER (R_XGATE_32, 4) + RELOC_NUMBER (R_XGATE_PCREL_16, 5) + /* These are GNU extensions to enable C++ vtable garbage collection. */ + RELOC_NUMBER (R_XGATE_GNU_VTINHERIT, 6) + RELOC_NUMBER (R_XGATE_GNU_VTENTRY, 7) + + RELOC_NUMBER (R_XGATE_24, 8) + RELOC_NUMBER (R_XGATE_LO16, 9) + RELOC_NUMBER (R_XGATE_GPAGE, 10) + RELOC_NUMBER (R_XGATE_PCREL_9, 11) + RELOC_NUMBER (R_XGATE_PCREL_10, 12) + RELOC_NUMBER (R_XGATE_IMM8_LO, 13) + RELOC_NUMBER (R_XGATE_IMM8_HI, 14) + RELOC_NUMBER (R_XGATE_IMM3, 15) + RELOC_NUMBER (R_XGATE_IMM4, 16) + RELOC_NUMBER (R_XGATE_IMM5, 17) + + /* GNU extension for linker relaxation. + Mark beginning of a jump instruction (any form). */ + RELOC_NUMBER (R_XGATE_RL_JUMP, 18) + + /* Mark beginning of Gcc relaxation group instruction. */ + RELOC_NUMBER (R_XGATE_RL_GROUP, 19) +END_RELOC_NUMBERS (R_XGATE_max) + +/* Processor specific flags for the ELF header e_flags field. */ + +/* ABI identification. */ +#define EF_XGATE_ABI 0x00000000F + +/* Integers are 32-bit long. */ +#define E_XGATE_I32 0x000000001 + +/* Doubles are 64-bit long. */ +#define E_XGATE_F64 0x000000002 + +#define EF_XGATE_MACH_MASK 0xF0 + +#define EF_XGATE_MACH 0x80 /* XGATE microcontroller. */ + +#define E_M68HCS12X_GLOBAL 0x100 + +/* Identify interrupt handlers. This is used by the debugger to + correctly compute the stack frame. */ +#define STO_XGATE_INTERRUPT 0x40 + +#endif diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index d4fb384024..af70340d68 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2012-05-03 Sean Keys + + * xgate.h: Header file for XGATE assembler. + 2012-04-27 David S. Miller * sparc.h: Document new arg code' )' for crypto RS3 diff --git a/include/opcode/xgate.h b/include/opcode/xgate.h new file mode 100644 index 0000000000..c516733424 --- /dev/null +++ b/include/opcode/xgate.h @@ -0,0 +1,120 @@ +/* xgate.h -- Freescale XGATE opcode list + Copyright 2010, 2011, 2012 Free Software Foundation, Inc. + Written by Sean Keys (skeys@ipdatasys.com) + + 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 file; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#ifndef _OPCODE_XGATE_H +#define _OPCODE_XGATE_H + +/* XGATE CCR flag definitions. */ +#define XGATE_N_BIT 0x08 /* XGN - Sign Flag */ +#define XGATE_Z_BIT 0x04 /* XGZ - Zero Flag */ +#define XGATE_V_BIT 0x02 /* XGV - Overflow Flag */ +#define XGATE_C_BIT 0x01 /* XGC - Carry Flag */ + +/* Access Detail Notation + V — Vector fetch: always an aligned word read, lasts for at least one RISC core cycle + P — Program word fetch: always an aligned word read, lasts for at least one RISC core cycle + r — 8-bit data read: lasts for at least one RISC core cycle + R — 16-bit data read: lasts for at least one RISC core cycle + w — 8-bit data write: lasts for at least one RISC core cycle + W — 16-bit data write: lasts for at least one RISC core cycle + A — Alignment cycle: no read or write, lasts for zero or one RISC core cycles + f — Free cycle: no read or write, lasts for one RISC core cycles. */ +#define XGATE_CYCLE_V 0x01 +#define XGATE_CYCLE_P 0x02 +#define XGATE_CYCLE_r 0x04 +#define XGATE_CYCLE_R 0x08 +#define XGATE_CYCLE_w 0x10 +#define XGATE_CYCLE_W 0x20 +#define XGATE_CYCLE_A 0x40 +#define XGATE_CYCLE_f 0x80 + +/* Opcode format abbreviations. */ +#define XG_INH 0x0001 /* Inherent. */ +#define XG_I 0x0002 /* 3-bit immediate address. */ +#define XG_R_I 0x0004 /* Register followed by 4/8-bit immediate value. */ +#define XG_R_R 0x0008 /* Register followed by a register. */ +#define XG_R_R_R 0x0010 /* Register followed by two registers. */ +#define XG_R 0x0020 /* Single register. */ +#define XG_PC 0x0040 /* PC relative 10 or 11 bit. */ +#define XG_R_C 0x0080 /* General register followed by ccr register. */ +#define XG_C_R 0x0100 /* CCR register followed by a general register. */ +#define XG_R_P 0x0200 /* General register followed by pc register. */ +#define XG_R_R_I 0x0400 /* Two general registers followed by an immediate value. */ +#define XG_PCREL 0x0800 /* Immediate value that is relative to the current pc. */ + +/* XGATE operand formats as stored in the XGATE_opcode table. + They are only used by GAS to recognize operands. */ +#define XGATE_OP_INH "" +#define XGATE_OP_TRI "r,r,r" +#define XGATE_OP_DYA "r,r" +#define XGATE_OP_IMM16 "r,if" +#define XGATE_OP_IMM8 "r,i8" +#define XGATE_OP_IMM4 "r,i4" +#define XGATE_OP_IMM3 "i3" +#define XGATE_OP_MON "r" +#define XGATE_OP_MON_R_C "r,c" +#define XGATE_OP_MON_C_R "c,r" +#define XGATE_OP_MON_R_P "r,p" +#define XGATE_OP_IDR "r,r,+" +#define XGATE_OP_IDO5 "r,r,i5" +#define XGATE_OP_REL9 "b9" +#define XGATE_OP_REL10 "ba" +#define XGATE_OP_DYA_MON "=r,r" +/* Macro definitions. */ +#define XGATE_OP_IMM16mADD "r,if; addl addh" +#define XGATE_OP_IMM16mAND "r,if; andl andh" +#define XGATE_OP_IMM16mCPC "r,if; cmpl cpch" +#define XGATE_OP_IMM16mSUB "r,if; subl subh" +#define XGATE_OP_IMM16mLDW "r,if; ldl ldh" + +/* CPU variant identification. */ +#define XGATE_V1 0x1 +#define XGATE_V2 0x2 +#define XGATE_V3 0x4 + +/* Max opcodes per opcode handle. */ +#define MAX_OPCODES 0x05 + +#define MAX_DETECT_CHARS 0x10 + +/* The opcode table definitions. */ +struct xgate_opcode +{ + char * name; /* Op-code name. */ + char * constraints; /* Constraint chars. */ + char * format; /* Bit definitions. */ + unsigned int sh_format; /* Shorthand format mask. */ + unsigned int size; /* Opcode size in bytes. */ + unsigned int bin_opcode; /* Binary opcode with operands masked off. */ + unsigned char cycles_min; /* Minimum cpu cycles needed. */ + unsigned char cycles_max; /* Maximum cpu cycles needed. */ + unsigned char set_flags_mask; /* CCR flags set. */ + unsigned char clr_flags_mask; /* CCR flags cleared. */ + unsigned char chg_flags_mask; /* CCR flags changed. */ + unsigned char arch; /* CPU variant. */ +}; + +/* The opcode table. The table contains all the opcodes (all pages). + You can't rely on the order. */ +extern const struct xgate_opcode xgate_opcodes[]; +extern const int xgate_num_opcodes; + +#endif /* _OPCODE_XGATE_H */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 94aa546fa8..ca5ae3408a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2012-05-03 Sean Keys + + * Makefile.am (ALL_EMULATIONS): Added new emulation for XGATE + and XGATE (elf). + * Makefile.in: Rebuild. + * configure.tgt: Recognize XGATE. + * scripttempl/elfxgate.sc: New file, mostly cloned from m68hc12. + * emulparams/xgateelf: New emulation, mostly cloned from m68hc12. + * NEWS: Mention new support. + 2012-04-26 Hans-Peter Nilsson Make bfd asserts cause linker errors. diff --git a/ld/Makefile.am b/ld/Makefile.am index abb16aa02f..65bfdcfb5d 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -457,6 +457,7 @@ ALL_EMULATION_SOURCES = \ evaxnbsd.c \ evsta.c \ ew65.c \ + exgateelf.c \ ez80.c \ ez8001.c \ ez8002.c @@ -1911,6 +1912,10 @@ evsta.c: $(srcdir)/emulparams/vsta.sh \ ew65.c: $(srcdir)/emulparams/w65.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS} ${GENSCRIPTS} w65 "$(tdir_w65)" +exgateelf.c: $(srcdir)/emulparams/xgateelf.sh \ + $(srcdir)/emultempl/generic.em $(ELF_DEPS) \ + $(srcdir)/scripttempl/elfxgate.sc ${GEN_DEPENDS} + ${GENSCRIPTS} xgateelf "$(tdir_xgate)" ez80.c: $(srcdir)/emulparams/z80.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \ $(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS} diff --git a/ld/Makefile.in b/ld/Makefile.in index 2c001c7c15..a9fca38552 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -764,6 +764,7 @@ ALL_EMULATION_SOURCES = \ evaxnbsd.c \ evsta.c \ ew65.c \ + exgateelf.c \ ez80.c \ ez8001.c \ ez8002.c @@ -1413,6 +1414,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evsta.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ew65.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@ @@ -3376,6 +3378,10 @@ evsta.c: $(srcdir)/emulparams/vsta.sh \ ew65.c: $(srcdir)/emulparams/w65.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS} ${GENSCRIPTS} w65 "$(tdir_w65)" +exgateelf.c: $(srcdir)/emulparams/xgateelf.sh \ + $(srcdir)/emultempl/generic.em $(ELF_DEPS) \ + $(srcdir)/scripttempl/elfxgate.sc ${GEN_DEPENDS} + ${GENSCRIPTS} xgateelf "$(tdir_xgate)" ez80.c: $(srcdir)/emulparams/z80.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \ $(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS} diff --git a/ld/NEWS b/ld/NEWS index 162f598b5e..0f1b7be768 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for the Freescale XGATE architecture. + * Add option -f FILE on AIX (for response file). * Add support for the Renesas RL78 architecture. diff --git a/ld/configure.tgt b/ld/configure.tgt index c36ec511a6..d7ad3baaac 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -703,6 +703,8 @@ xstormy16-*-*) targ_emul=elf32xstormy16 ;; xtensa*-*-*) targ_emul=elf32xtensa ;; +xgate-*-*) targ_emul=xgateelf + ;; z80-*-coff) targ_emul=z80 ;; z8k-*-coff) targ_emul=z8002; targ_extra_emuls=z8001 diff --git a/ld/emulparams/xgateelf.sh b/ld/emulparams/xgateelf.sh new file mode 100644 index 0000000000..1f9253e805 --- /dev/null +++ b/ld/emulparams/xgateelf.sh @@ -0,0 +1,18 @@ +MACHINE= +SCRIPT_NAME=elfxgate +OUTPUT_FORMAT="elf32-xgate" +ROM_START_ADDR=0x08000 +ROM_SIZE=0x8000 +RAM_START_ADDR=0x01100 +RAM_SIZE=0x6F00 +EEPROM_START_ADDR=0x0800 +EEPROM_SIZE=2048 +TEXT_MEMORY=text +DATA_MEMORY=data +EEPROM_MEMORY=eeprom +ARCH=xgate +MAXPAGESIZE=32 +EMBEDDED=yes +GENERIC_BOARD=no +TEMPLATE_NAME=elf32 +EXTRA_EM_FILE= diff --git a/ld/scripttempl/elfxgate.sc b/ld/scripttempl/elfxgate.sc new file mode 100644 index 0000000000..0774eb2135 --- /dev/null +++ b/ld/scripttempl/elfxgate.sc @@ -0,0 +1,463 @@ +# +# Unusual variables checked by this code: +# NOP - four byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# EMBEDDED - whether this is for an embedded system. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test "$LD_FLAG" = "N" && DATA_ADDR=. + +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ PROVIDE (__CTOR_LIST__ = .); } + ${CONSTRUCTING+${CTOR_START}} + KEEP (*(.ctors)) + + ${CONSTRUCTING+${CTOR_END}} + ${CONSTRUCTING+ PROVIDE(__CTOR_END__ = .); } + } ${RELOCATING+ > ${TEXT_MEMORY}}" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ PROVIDE(__DTOR_LIST__ = .); } + KEEP (*(.dtors)) + ${CONSTRUCTING+ PROVIDE(__DTOR_END__ = .); } + } ${RELOCATING+ > ${TEXT_MEMORY}}" + + +VECTORS=" + /* If the 'vectors_addr' symbol is defined, it indicates the start address + of interrupt vectors. This depends on the 68HC11 operating mode: + + Addr + Single chip 0xffc0 + Extended mode 0xffc0 + Bootstrap 0x00c0 + Test 0xbfc0 + + In general, the vectors address is 0xffc0. This can be overriden + with the '-defsym vectors_addr=0xbfc0' ld option. + + Note: for the bootstrap mode, the interrupt vectors are at 0xbfc0 but + they are redirected to 0x00c0 by the internal PROM. Application's vectors + must also consist of jump instructions (see Motorola's manual). */ + + PROVIDE (_vectors_addr = DEFINED (vectors_addr) ? vectors_addr : 0xffc0); + .vectors DEFINED (vectors_addr) ? vectors_addr : 0xffc0 : + { + KEEP (*(.vectors)) + }" + +# +# We provide two emulations: a fixed on that defines some memory banks +# and a configurable one that includes a user provided memory definition. +# +case $GENERIC_BOARD in + yes|1|YES) + MEMORY_DEF=" +/* Get memory banks definition from some user configuration file. + This file must be located in some linker directory (search path + with -L). See fixed memory banks emulation script. */ +INCLUDE memory.x; +" + ;; + *) +MEMORY_DEF=" +/* Fixed definition of the available memory banks. + See generic emulation script for a user defined configuration. */ +MEMORY +{ + page0 (rwx) : ORIGIN = 0x0, LENGTH = 256 + text (rx) : ORIGIN = ${ROM_START_ADDR}, LENGTH = ${ROM_SIZE} + data : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE} + eeprom : ORIGIN = ${EEPROM_START_ADDR}, LENGTH = ${EEPROM_SIZE} +} + +/* Setup the stack on the top of the data memory bank. */ +PROVIDE (_stack = ${RAM_START_ADDR} + ${RAM_SIZE} - 1); +" + ;; +esac + +STARTUP_CODE=" + /* Startup code. */ + KEEP (*(.install0)) /* Section should setup the stack pointer. */ + KEEP (*(.install1)) /* Place holder for applications. */ + KEEP (*(.install2)) /* Optional installation of data sections in RAM. */ + KEEP (*(.install3)) /* Place holder for applications. */ + KEEP (*(.install4)) /* Section that calls the main. */ +" + +FINISH_CODE=" + /* Finish code. */ + KEEP (*(.fini0)) /* Beginning of finish code (_exit symbol). */ + KEEP (*(.fini1)) /* Place holder for applications. */ + KEEP (*(.fini2)) /* C++ destructors. */ + KEEP (*(.fini3)) /* Place holder for applications. */ + KEEP (*(.fini4)) /* Runtime exit. */ +" + +PRE_COMPUTE_DATA_SIZE=" +/* SCz: this does not work yet... This is supposed to force the loading + of _map_data.o (from libgcc.a) when the .data section is not empty. + By doing so, this should bring the code that copies the .data section + from ROM to RAM at init time. + + ___pre_comp_data_size = SIZEOF(.data); + __install_data_sections = ___pre_comp_data_size > 0 ? + __map_data_sections : 0; +*/ +" + +INSTALL_RELOC=" + .install0 0 : { *(.install0) } + .install1 0 : { *(.install1) } + .install2 0 : { *(.install2) } + .install3 0 : { *(.install3) } + .install4 0 : { *(.install4) } +" + +FINISH_RELOC=" + .fini0 0 : { *(.fini0) } + .fini1 0 : { *(.fini1) } + .fini2 0 : { *(.fini2) } + .fini3 0 : { *(.fini3) } + .fini4 0 : { *(.fini4) } +" + +BSS_DATA_RELOC=" + .data1 0 : { *(.data1) } + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata 0 : { *(.sdata) } + .sbss 0 : { *(.sbss) } + .scommon 0 : { *(.scommon) } +" + +SOFT_REGS_RELOC=" + .softregs 0 : { *(.softregs) } +" + +cat < page0} + + /* Start of text section. */ + .stext ${RELOCATING-0} : + { + *(.stext) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + .init ${RELOCATING-0} : + { + *(.init) + } ${RELOCATING+=${NOP-0}} + + ${RELOCATING-${INSTALL_RELOC}} + ${RELOCATING-${FINISH_RELOC}} + + .text ${RELOCATING-0}: + { + /* Put startup code at beginning so that _start keeps same address. */ + ${RELOCATING+${STARTUP_CODE}} + + ${RELOCATING+*(.init)} + *(.text) + ${RELOCATING+*(.text.*)} + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + ${RELOCATING+*(.gnu.linkonce.t.*)} + ${RELOCATING+*(.tramp)} + ${RELOCATING+*(.tramp.*)} + + ${RELOCATING+${FINISH_CODE}} + + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =0xa7a7a7a7} + + .eh_frame ${RELOCATING-0} : + { + KEEP (*(.eh_frame)) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + .gcc_except_table ${RELOCATING-0} : + { + *(.gcc_except_table) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + .rodata ${RELOCATING-0} : + { + *(.rodata) + ${RELOCATING+*(.rodata.*)} + ${RELOCATING+*(.gnu.linkonce.r*)} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff} + + .rodata1 ${RELOCATING-0} : + { + *(.rodata1) + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff} + + /* Constructor and destructor tables are in ROM. */ + ${RELOCATING+${CTOR}} + ${RELOCATING+${DTOR}} + + .jcr ${RELOCATING-0} : + { + KEEP (*(.jcr)) + } ${RELOCATING+ > ${TEXT_MEMORY}} + + /* Start of the data section image in ROM. */ + ${RELOCATING+__data_image = .;} + ${RELOCATING+PROVIDE (__data_image = .);} + + /* All read-only sections that normally go in PROM must be above. + We construct the DATA image section in PROM at end of all these + read-only sections. The data image must be copied at init time. + Refer to GNU ld, Section 3.6.8.2 Output Section LMA. */ + .data ${RELOCATING-0} : ${RELOCATING+AT (__data_image)} + { + ${RELOCATING+__data_section_start = .;} + ${RELOCATING+PROVIDE (__data_section_start = .);} + + ${RELOCATING+${DATA_START_SYMBOLS}} + ${RELOCATING+*(.sdata)} + *(.data) + ${RELOCATING+*(.data.*)} + ${RELOCATING+*(.data1)} + ${RELOCATING+*(.gnu.linkonce.d.*)} + ${CONSTRUCTING+CONSTRUCTORS} + + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(2);} + } ${RELOCATING+ > ${DATA_MEMORY} =0xffffffff} + + ${RELOCATING+__data_section_size = SIZEOF(.data);} + ${RELOCATING+PROVIDE (__data_section_size = SIZEOF(.data));} + ${RELOCATING+__data_image_end = __data_image + __data_section_size;} + + ${RELOCATING+${PRE_COMPUTE_DATA_SIZE}} + + /* .install ${RELOCATING-0}: + { + . = _data_image_end; + } ${RELOCATING+ > ${TEXT_MEMORY}} */ + + /* Relocation for some bss and data sections. */ + ${RELOCATING-${BSS_DATA_RELOC}} + ${RELOCATING-${SOFT_REGS_RELOC}} + + .bss ${RELOCATING-0} : + { + ${RELOCATING+__bss_start = .;} + ${RELOCATING+*(.softregs)} + ${RELOCATING+*(.sbss)} + ${RELOCATING+*(.scommon)} + + *(.dynbss) + *(.bss) + ${RELOCATING+*(.bss.*)} + ${RELOCATING+*(.gnu.linkonce.b.*)} + *(COMMON) + ${RELOCATING+PROVIDE (_end = .);} + } ${RELOCATING+ > ${DATA_MEMORY}} + ${RELOCATING+__bss_size = SIZEOF(.bss);} + ${RELOCATING+PROVIDE (__bss_size = SIZEOF(.bss));} + + .eeprom ${RELOCATING-0} : + { + *(.eeprom) + *(.eeprom.*) + } ${RELOCATING+ > ${EEPROM_MEMORY}} + + ${RELOCATING+${VECTORS}} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. + Treatment of DWARF debug section must be at end of the linker + script to avoid problems when there are undefined symbols. It's necessary + to avoid that the DWARF section is relocated before such undefined + symbols are found. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } +} +EOF diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 371d8f6034..a43dd3d3da 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,14 @@ +2012-05-03 Sean Keys + + * Makefile.in, configure: regenerate + * disassemble.c (disassembler): Recognize ARCH_XGATE. + * xgate-dis.c (read_memory, print_insn, print_insn_xgate): + New functions. + * configure.in: Recognize xgate. + * xgate-dis.c, xgate-opc.c: New files for support of xgate + * Makefile.am (CFILES, ALL_MACHINES): New files for disassembly + and opcode generation for xgate. + 2012-04-30 DJ Delorie * rx-decode.opc (MOV): Do not sign-extend immediates which are diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am index b377c4d17c..a43aa0d1a1 100644 --- a/opcodes/Makefile.am +++ b/opcodes/Makefile.am @@ -234,6 +234,8 @@ TARGET_LIBOPCODES_CFILES = \ xstormy16-ibld.c \ xstormy16-opc.c \ xtensa-dis.c \ + xgate-dis.c \ + xgate-opc.c \ z80-dis.c \ z8k-dis.c diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in index 8ae4b841c9..f5035ea4ce 100644 --- a/opcodes/Makefile.in +++ b/opcodes/Makefile.in @@ -504,6 +504,8 @@ TARGET_LIBOPCODES_CFILES = \ xstormy16-ibld.c \ xstormy16-opc.c \ xtensa-dis.c \ + xgate-dis.c \ + xgate-opc.c \ z80-dis.c \ z8k-dis.c @@ -884,6 +886,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-dis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-ibld.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-opc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgate-dis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgate-opc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-asm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-desc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-dis.Plo@am__quote@ diff --git a/opcodes/configure b/opcodes/configure index cc690608e6..ec7434683e 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -12492,7 +12492,8 @@ if test x${all_targets} = xfalse ; then bfd_vax_arch) ta="$ta vax-dis.lo" ;; bfd_w65_arch) ta="$ta w65-dis.lo" ;; bfd_we32k_arch) ;; - bfd_xc16x_arch) ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;; + bfd_xc16x_arch) ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;; + bfd_xgate_arch) ta="$ta xgate-dis.lo xgate-opc.lo" ;; bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;; bfd_xtensa_arch) ta="$ta xtensa-dis.lo" ;; bfd_z80_arch) ta="$ta z80-dis.lo" ;; diff --git a/opcodes/configure.in b/opcodes/configure.in index 6da3ef1acd..999379a3b2 100644 --- a/opcodes/configure.in +++ b/opcodes/configure.in @@ -306,7 +306,8 @@ if test x${all_targets} = xfalse ; then bfd_vax_arch) ta="$ta vax-dis.lo" ;; bfd_w65_arch) ta="$ta w65-dis.lo" ;; bfd_we32k_arch) ;; - bfd_xc16x_arch) ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;; + bfd_xc16x_arch) ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;; + bfd_xgate_arch) ta="$ta xgate-dis.lo xgate-opc.lo" ;; bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;; bfd_xtensa_arch) ta="$ta xtensa-dis.lo" ;; bfd_z80_arch) ta="$ta z80-dis.lo" ;; diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 43e1d53eb4..7ff5f22731 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -91,6 +91,7 @@ #define ARCH_w65 #define ARCH_xstormy16 #define ARCH_xc16x +#define ARCH_xgate #define ARCH_xtensa #define ARCH_z80 #define ARCH_z8k @@ -430,6 +431,11 @@ disassembler (abfd) disassemble = print_insn_w65; break; #endif +#ifdef ARCH_xgate + case bfd_arch_xgate: + disassemble = print_insn_xgate; + break; +#endif #ifdef ARCH_xstormy16 case bfd_arch_xstormy16: disassemble = print_insn_xstormy16; diff --git a/opcodes/xgate-dis.c b/opcodes/xgate-dis.c new file mode 100644 index 0000000000..f703055586 --- /dev/null +++ b/opcodes/xgate-dis.c @@ -0,0 +1,403 @@ +/* xgate-dis.c -- Freescale XGATE disassembly + Copyright 2009, 2010, 2011 + Free Software Foundation, Inc. + Written by Sean Keys (skeys@ipdatasys.com) + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. +*/ + +#include +#include "sysdep.h" +#include "dis-asm.h" +#include "opintl.h" +#include "libiberty.h" +#include "ansidecl.h" +#include "opcode/xgate.h" + +#define XGATE_TWO_BYTES 0x02 +#define XGATE_NINE_BITS 0x1FF +#define XGATE_TEN_BITS 0x3FF +#define XGATE_NINE_SIGNBIT 0x100 +#define XGATE_TEN_SIGNBIT 0x200 + +/* Structures */ +struct decodeInfo { + unsigned int operMask; + unsigned int operMasksRegisterBits; + struct xgate_opcode *opcodePTR; +}; + +/* Prototypes for local functions. */ +static int +print_insn( bfd_vma, struct disassemble_info *); +static int +read_memory( bfd_vma, bfd_byte*, int, struct disassemble_info *); +static int +ripBits(unsigned int *, int, + struct xgate_opcode *, unsigned int); +int +macro_search(char *, char *); +struct decodeInfo * +find_match(unsigned int raw_code); + +/* statics */ +static struct decodeInfo *decodeTable; +static int initialized; +static char previousOpName[10]; +static unsigned int perviousBin; + +/* Disassemble one instruction at address 'memaddr'. Returns the number + of bytes used by that instruction. */ +static int +print_insn (bfd_vma memaddr, struct disassemble_info* info) +{ + int status; + unsigned int raw_code; + char *s = 0; + long bytesRead = 0; + int i = 0; + struct xgate_opcode *opcodePTR = (struct xgate_opcode*) xgate_opcodes; + struct decodeInfo *decodeTablePTR = 0; + struct decodeInfo *decodePTR = 0; + unsigned int operandRegisterBits = 0; + signed int relAddr = 0; + signed int operandOne = 0; + signed int operandTwo = 0; + bfd_byte buffer[4]; + bfd_vma absAddress; + + unsigned int operMaskReg = 0; + /* initialize our array of opcode masks and check them against our constant + table */ + if (!initialized) + { + decodeTable = xmalloc(sizeof(struct decodeInfo) * xgate_num_opcodes); + for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes; + i++, decodeTablePTR++, opcodePTR++) + { + unsigned int bin = 0; + unsigned int mask = 0; + for (s = opcodePTR->format; *s; s++) + { + bin <<= 1; + mask <<= 1; + operandRegisterBits <<= 1; + bin |= (*s == '1'); + mask |= (*s == '0' || *s == '1'); + operandRegisterBits |= (*s == 'r'); + } + /* asserting will uncover inconsistencies in our table */ + assert( + (s - opcodePTR->format) == 16 || (s - opcodePTR->format) == 32); + assert(opcodePTR->bin_opcode == bin); + decodeTablePTR->operMask = mask; + decodeTablePTR->operMasksRegisterBits = operandRegisterBits; + decodeTablePTR->opcodePTR = opcodePTR; + } + initialized = 1; + } + /* read 16 bits */ + bytesRead += XGATE_TWO_BYTES; + status = read_memory(memaddr, buffer, XGATE_TWO_BYTES, info); + if (status == 0) + { + raw_code = buffer[0]; + raw_code <<= 8; + raw_code += buffer[1]; + + decodePTR = find_match(raw_code); + if (decodePTR) + { + operMaskReg = decodePTR->operMasksRegisterBits; + (*info->fprintf_func)(info->stream, "%s", decodePTR->opcodePTR->name); + /* First we compare the shorthand format of the constraints. If we + still are unable to pinpoint the operands + we analyze the opcodes constraint string. */ + switch (decodePTR->opcodePTR->sh_format) + { + case XG_R_C: + (*info->fprintf_func)(info->stream, " R%x, CCR", + (raw_code >> 8) & 0x7); + break; + case XG_C_R: + (*info->fprintf_func)(info->stream, " CCR, R%x", + (raw_code >> 8) & 0x7); + break; + case XG_R_P: + (*info->fprintf_func)(info->stream, " R%x, PC", + (raw_code >> 8) & 0x7); + break; + case XG_INH: + break; + case XG_R_R_R: + if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_TRI)) + { + (*info->fprintf_func)(info->stream, " R%x, R%x, R%x", + (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, + (raw_code >> 2) & 0x7); + } + else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IDR)) + { + if (raw_code & 0x01) + { + (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x+)", + (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, + (raw_code >> 2) & 0x7); + } + else if (raw_code & 0x02) + { + (*info->fprintf_func)(info->stream, " R%x, (R%x, -R%x)", + (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, + (raw_code >> 2) & 0x7); + } + else + { + (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x)", + (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, + (raw_code >> 2) & 0x7); + } + } + else + { + (*info->fprintf_func)(info->stream, " unhandled mode %s", + decodePTR->opcodePTR->constraints); + } + break; + case XG_R_R: + if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_DYA_MON)) + { + operandOne = ripBits(&operMaskReg, 3, decodePTR->opcodePTR, + raw_code); + operandTwo = ripBits(&operMaskReg, 3, decodePTR->opcodePTR, + raw_code); + (*info->fprintf_func)(info->stream, " R%x, R%x", operandOne, + operandTwo); + } + else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_DYA)) + { + operandOne = ripBits(&operMaskReg, 3, opcodePTR, raw_code); + operandTwo = ripBits(&operMaskReg, 3, opcodePTR, raw_code); + (*info->fprintf_func)(info->stream, " R%x, R%x", operandOne, + operandTwo); + } + else + { + (*info->fprintf_func)(info->stream, " unhandled mode %s", + opcodePTR->constraints); + } + break; + case XG_R_R_I: + (*info->fprintf_func)(info->stream, " R%x, (R%x, #0x%x)", + (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, raw_code & 0x1f); + break; + case XG_R: + operandOne = ripBits(&operMaskReg, 3, decodePTR->opcodePTR, + raw_code); + (*info->fprintf_func)(info->stream, " R%x", operandOne); + break; + case XG_I | XG_PCREL: + if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_REL9)) + { + /* if address is negative handle it accordingly */ + if (raw_code & XGATE_NINE_SIGNBIT) + { + relAddr = XGATE_NINE_BITS >> 1; /* clip sign bit */ + relAddr = ~relAddr; /* make signed */ + relAddr |= (raw_code & 0xFF) + 1; /* apply our value */ + relAddr <<= 1; /* multiply by two as per processor docs */ + } + else + { + relAddr = raw_code & 0xff; + relAddr = (relAddr << 1) + 2; + } + (*info->fprintf_func)(info->stream, " *%d", relAddr); + (*info->fprintf_func)(info->stream, " Abs* 0x"); + (*info->print_address_func)(memaddr + relAddr, info); + } + else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_REL10)) + { + /* if address is negative handle it accordingly */ + if (raw_code & XGATE_TEN_SIGNBIT) + { + relAddr = XGATE_TEN_BITS >> 1; /* clip sign bit */ + relAddr = ~relAddr; /* make signed */ + relAddr |= (raw_code & 0x1FF) + 1; /* apply our value */ + relAddr <<= 1; /* multiply by two as per processor docs */ + } + else + { + relAddr = raw_code & 0x1FF; + relAddr = (relAddr << 1) + 2; + } + (*info->fprintf_func)(info->stream, " *%d", relAddr); + (*info->fprintf_func)(info->stream, " Abs* 0x"); + (*info->print_address_func)(memaddr + relAddr, info); + } + else + { + (*info->fprintf_func)(info->stream, + " Can't disassemble for mode) %s", + decodePTR->opcodePTR->constraints); + } + break; + case XG_R_I: + if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IMM4)) + { + (*info->fprintf_func)(info->stream, " R%x, #0x%02x", + (raw_code >> 8) & 0x7, (raw_code >> 4) & 0xF); + } + else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IMM8)) + { + if (macro_search(decodePTR->opcodePTR->name, previousOpName) && + previousOpName[0]) + { + absAddress = (0xFF & raw_code) << 8; + absAddress |= perviousBin & 0xFF; + (*info->fprintf_func)(info->stream, " R%x, #0x%02x Abs* 0x", + (raw_code >> 8) & 0x7, raw_code & 0xff); + (*info->print_address_func)(absAddress, info); + previousOpName[0] = 0; + } + else + { + strcpy(previousOpName, decodePTR->opcodePTR->name); + (*info->fprintf_func)(info->stream, " R%x, #0x%02x", + (raw_code >> 8) & 0x7, raw_code & 0xff); + } + } + else + { + (*info->fprintf_func)(info->stream, + " Can't disassemble for mode %s", + decodePTR->opcodePTR->constraints); + } + break; + case XG_I: + (*info->fprintf_func)(info->stream, " #0x%x", + (raw_code >> 8) & 0x7); + break; + default: + (*info->fprintf_func)(info->stream, "address mode not found\t %x", + opcodePTR->bin_opcode); + break; + } + perviousBin = raw_code; + } + else + { + (*info->fprintf_func)(info->stream, + " unable to find opcode match #0%x", raw_code); + } + } + return bytesRead; +} + +int +print_insn_xgate (bfd_vma memaddr, struct disassemble_info* info) +{ + return print_insn (memaddr, info); +} + +static int +read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, + struct disassemble_info* info) +{ + int status; + status = (*info->read_memory_func) (memaddr, buffer, size, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + return 0; +} + +static int +ripBits(unsigned int *operandBitsRemaining, int numBitsRequested, + struct xgate_opcode *opcodePTR, unsigned int memory) +{ + unsigned int currentBit; + int operand; + int numBitsFound; + for (operand = 0, numBitsFound = 0, currentBit = 1 + << ((opcodePTR->size * 8) - 1); + (numBitsFound < numBitsRequested) && currentBit; currentBit >>= 1) + { + if(currentBit & *operandBitsRemaining) { + *operandBitsRemaining &= ~(currentBit); /* consume the current bit */ + operand <<= 1; /* make room for our next bit */ + numBitsFound++; + operand |= (currentBit & memory) > 0; + } + } + return operand; +} + +int +macro_search(char *currentName, char *lastName) +{ + int i; + int length = 0; + char *where; + for (i = 0; i < xgate_num_opcodes; i++) + { + where = strstr(xgate_opcodes[i].constraints, lastName); + if (where) + { + length = strlen(where); + } + if (length) + { + where = strstr(xgate_opcodes[i].constraints, currentName); + if (where) + { + length = strlen(where); + return 1; + } + } + } + return 0; +} + +struct decodeInfo* +find_match(unsigned int raw_code) +{ + struct decodeInfo *decodeTablePTR = 0; + int i; + + for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes; + i++, decodeTablePTR++) + { + if ((raw_code & decodeTablePTR->operMask) + == decodeTablePTR->opcodePTR->bin_opcode) + { + /* make sure we didn't run into a macro or alias */ + if (decodeTablePTR->opcodePTR->cycles_min != 0) + { + return decodeTablePTR; + break; + } + else + { + continue; + } + } + } + return 0; +} diff --git a/opcodes/xgate-opc.c b/opcodes/xgate-opc.c new file mode 100644 index 0000000000..9b5fe077cb --- /dev/null +++ b/opcodes/xgate-opc.c @@ -0,0 +1,203 @@ +/* mc9xgate-opc.c -- Freescale XGATE opcode list + Copyright 1999, 2000, 2002, 2005, 2007 Free Software Foundation, Inc. + Written by Sean Keys (skeys@ipdatasys.com) + + 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 file; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. +*/ + +#include +#include "ansidecl.h" +#include "opcode/xgate.h" + +#define TABLE_SIZE(X) (sizeof(X) / sizeof(X[0])) + +/* Combination of CCR flags. */ +/* ORDER HI TO LOW NZVC */ +#define XGATE_NZ_BIT XGATE_N_BIT|XGATE_Z_BIT +#define XGATE_NV_BIT XGATE_N_BIT|XGATE_V_BIT +#define XGATE_NC_BIT XGATE_N_BIT|XGATE_C_BIT +#define XGATE_ZV_BIT XGATE_Z_BIT|XGATE_V_BIT +#define XGATE_ZC_BIT XGATE_Z_BIT|XGATE_C_BIT +#define XGATE_VC_BIT XGATE_V_BIT|XGATE_C_BIT +#define XGATE_NVC_BIT XGATE_NV_BIT|XGATE_C_BIT +#define XGATE_NZC_BIT XGATE_NZ_BIT|XGATE_C_BIT +#define XGATE_NZV_BIT XGATE_N_BIT|XGATE_Z_BIT|XGATE_V_BIT +#define XGATE_ZVC_BIT XGATE_VC_BIT|XGATE_Z_BIT +#define XGATE_NZVC_BIT XGATE_NZV_BIT|XGATE_C_BIT + +/* Flags when the insn only changes some CCR flags. */ +#define CHG_NONE 0,0,0 +#define CHG_Z 0,0,XGATE_Z_BIT +#define CHG_C 0,0,XGATE_C_BIT +#define CHG_ZVC 0,0,XGATE_ZVC_BIT +#define CHG_NZC 0,0,XGATE_NZC_BIT +#define CHG_NZV 0,0,XGATE_NZV_BIT +#define CHG_NZVC 0,0,(XGATE_NZVC_BIT) +#define CHG_HNZVC 0,0,XGATE_HNZVC_BIT // TODO DELETE +#define CHG_ALL 0,0,0xff + +/* The insn clears and changes some flags. */ +#define CLR_I 0,XG_I_BIT,0 +#define CLR_C 0,XGATE_C_BIT,0 +#define CLR_V 0,XGATE_V_BIT,0 +#define CLR_V_CHG_ZC 0,XGATE_V_BIT,XGATE_ZC_BIT +#define CLR_V_CHG_NZ 0,XGATE_V_BIT,XGATE_NZ_BIT +#define CLR_V_CHG_ZVC 0,XGATE_V_BIT,XGATE_ZVC_BIT +#define CLR_N_CHG_ZVC 0,XGATE_N_BIT,XGATE_ZVC_BIT /* Used by lsr */ +#define CLR_VC_CHG_NZ 0,XGATE_VC_BIT,XGATE_NZ_BIT + +/* The insn sets some flags. */ +#define SET_I XGATE_I_BIT,0,0 +#define SET_C XGATE_C_BIT,0,0 +#define SET_V XGATE_V_BIT,0,0 +#define SET_Z_CLR_NVC XGATE_Z_BIT,XGATE_NVC_BIT,0 +#define SET_C_CLR_V_CHG_NZ XGATE_C_BIT,XGATE_V_BIT,XGATE_NZ_BIT +#define SET_Z_CHG_HNVC XGATE_Z_BIT,0,XGATE_HNVC_BIT + +/* operand modes */ +#define OP_NONE XGATE_OP_NONE +#define OP_INH XGATE_OP_INH +#define OP_TRI XGATE_OP_TRI +#define OP_DYA XGATE_OP_DYA +#define OP_DM XGATE_OP_DYA_MON +#define OP_IMM3 XGATE_OP_IMM3 +#define OP_IMM4 XGATE_OP_IMM4 +#define OP_IMM8 XGATE_OP_IMM8 +#define OP_IMM16 XGATE_OP_IMM16 +#define OP_MON XGATE_OP_MON +#define OP_MON_R_C XGATE_OP_MON_R_C +#define OP_MON_C_R XGATE_OP_MON_C_R +#define OP_MON_R_P XGATE_OP_MON_R_P +#define OP_IDR XGATE_OP_IDR +#define OP_IDO5 XGATE_OP_IDO5 +#define OP_REL9 XGATE_OP_REL9 +#define OP_REL10 XGATE_OP_REL10 +/* macro operand modes */ +#define OP_mADD XGATE_OP_IMM16mADD +#define OP_mAND XGATE_OP_IMM16mAND +#define OP_mCPC XGATE_OP_IMM16mCPC +#define OP_mLDW XGATE_OP_IMM16mLDW +#define OP_mSUB XGATE_OP_IMM16mSUB + +#define ALL XGATE_V1|XGATE_V2|XGATE_V3 +#define XG_IP XG_I|XG_PCREL + +const struct xgate_opcode xgate_opcodes[] = { +/* Name -+ +-- CPU + Constraints --+ +------------ CCR changes + Format ----------------+ +---------------- Max # cycles + Short Hand Format-------------------------+ +------------------- Min # cycles + Size -----------------------------------------------+ +-------------------------- Opcode */ + { "adc", OP_TRI, "00011rrrrrrrrr11", XG_R_R_R, 2, 0x1803, 1, 1, CHG_NZVC, ALL}, + { "add", OP_TRI, "00011rrrrrrrrr10", XG_R_R_R, 2, 0x1802, 1, 1, CHG_NZVC, ALL}, + { "addh", OP_IMM8, "11101rrriiiiiiii", XG_R_I, 2, 0xE800, 1, 1, CHG_NZVC, ALL}, + { "addl", OP_IMM8, "11100rrriiiiiiii", XG_R_I, 2, 0xE000, 1, 1, CHG_NZVC, ALL}, + { "and", OP_TRI, "00010rrrrrrrrr00", XG_R_R_R, 2, 0x1000, 1, 1, CHG_NZV, ALL}, + { "andh", OP_IMM8, "10001rrriiiiiiii", XG_R_I, 2, 0x8800, 1, 1, CHG_NZV, ALL}, + { "andl", OP_IMM8, "10000rrriiiiiiii", XG_R_I, 2, 0x8000, 1, 1, CHG_NZV, ALL}, + { "asr", OP_IMM4, "00001rrriiii1001", XG_R_I, 2, 0x0809, 1, 1, CHG_NZVC, ALL}, + { "asr", OP_DYA, "00001rrrrrr10001", XG_R_R, 2, 0x0811, 1, 1, CHG_NZVC, ALL}, + { "bcc", OP_REL9, "0010000iiiiiiiii", XG_IP, 2, 0x2000, 1, 2, CHG_NONE, ALL}, + { "bcs", OP_REL9, "0010001iiiiiiiii", XG_IP, 2, 0x2200, 1, 2, CHG_NONE, ALL}, + { "beq", OP_REL9, "0010011iiiiiiiii", XG_IP, 2, 0x2600, 1, 2, CHG_NONE, ALL}, + { "bfext", OP_TRI, "01100rrrrrrrrr11", XG_R_R_R, 2, 0x6003, 1, 1, CHG_NZV, ALL}, + { "bffo", OP_DYA, "00001rrrrrr10000", XG_R_R, 2, 0x0810, 1, 1, CHG_NZVC, ALL}, + { "bfins", OP_TRI, "01101rrrrrrrrr11", XG_R_R_R, 2, 0x6803, 1, 1, CHG_NZV, ALL}, + {"bfinsi", OP_TRI, "01110rrrrrrrrr11", XG_R_R_R, 2, 0x7003, 1, 1, CHG_NZV, ALL}, + {"bfinsx", OP_TRI, "01111rrrrrrrrr11", XG_R_R_R, 2, 0x7803, 1, 1, CHG_NZV, ALL}, + { "bge", OP_REL9, "0011010iiiiiiiii", XG_IP, 2, 0x3400, 1, 2, CHG_NONE, ALL}, + { "bgt", OP_REL9, "0011100iiiiiiiii", XG_IP, 2, 0x3800, 1, 2, CHG_NONE, ALL}, + { "bhi", OP_REL9, "0011000iiiiiiiii", XG_IP, 2, 0x3000, 1, 2, CHG_NONE, ALL}, + { "bith", OP_IMM8, "10011rrriiiiiiii", XG_R_I, 2, 0x9800, 1, 1, CHG_NZV, ALL}, + { "bitl", OP_IMM8, "10010rrriiiiiiii", XG_R_I, 2, 0x9000, 1, 1, CHG_NZV, ALL}, + { "ble", OP_REL9, "0011101iiiiiiiii", XG_IP, 2, 0x3A00, 1, 2, CHG_NONE, ALL}, + { "bls", OP_REL9, "0011001iiiiiiiii", XG_IP, 2, 0x3200, 1, 2, CHG_NONE, ALL}, + { "blt", OP_REL9, "0011011iiiiiiiii", XG_IP, 2, 0x3600, 1, 2, CHG_NONE, ALL}, + { "bmi", OP_REL9, "0010101iiiiiiiii", XG_IP, 2, 0x2A00, 1, 2, CHG_NONE, ALL}, + { "bne", OP_REL9, "0010010iiiiiiiii", XG_IP, 2, 0x2400, 1, 2, CHG_NONE, ALL}, + { "bpl", OP_REL9, "0010100iiiiiiiii", XG_IP, 2, 0x2800, 1, 2, CHG_NONE, ALL}, + { "bra", OP_REL10, "001111iiiiiiiiii", XG_IP, 2, 0x3C00, 2, 2, CHG_NONE, ALL}, + { "brk", OP_INH, "0000000000000000", XG_INH, 2, 0x0000, 1, 1, CHG_NONE, ALL}, + { "bvc", OP_REL9, "0010110iiiiiiiii", XG_IP, 2, 0x2C00, 1, 2, CHG_NONE, ALL}, + { "bvs", OP_REL9, "0010111iiiiiiiii", XG_IP, 2, 0x2E00, 1, 2, CHG_NONE, ALL}, + { "cmpl", OP_IMM8, "11010rrriiiiiiii", XG_R_I, 2, 0xD000, 1, 1, CHG_NZVC, ALL}, + { "cpch", OP_IMM8, "11011rrriiiiiiii", XG_R_I, 2, 0xD800, 1, 1, CHG_NZVC, ALL}, + { "csem", OP_IMM3, "00000iii11110000", XG_I , 2, 0x00F0, 1, 1, CHG_NONE, ALL}, + { "csem", OP_MON, "00000rrr11110001", XG_R, 2, 0x00F1, 1, 1, CHG_NONE, ALL}, + { "csl", OP_IMM4, "00001rrriiii1010", XG_R_I, 2, 0x080A, 1, 1, CHG_NZVC, ALL}, + { "csl", OP_DYA, "00001rrrrrr10010", XG_R_R, 2, 0x0812, 1, 1, CHG_NZVC, ALL}, + { "csr", OP_IMM4, "00001rrriiii1011", XG_R_I, 2, 0x080B, 1, 1, CHG_NZVC, ALL}, + { "csr", OP_DYA, "00001rrrrrr10011", XG_R_R, 2, 0x0813, 1, 1, CHG_NZVC, ALL}, + { "jal", OP_MON, "00000rrr11110110", XG_R, 2, 0x00F6, 2, 2, CHG_NONE, ALL}, + { "ldb", OP_IDO5, "01000rrrrrriiiii", XG_R_R_I, 2, 0x4000, 2, 2, CHG_NONE, ALL}, + { "ldb", OP_IDR, "01100rrrrrrrrrrr", XG_R_R_R, 2, 0x6000, 2, 2, CHG_NONE, ALL}, + { "ldh", OP_IMM8, "11111rrriiiiiiii", XG_R_I, 2, 0xF800, 1, 1, CHG_NONE, ALL}, + { "ldl", OP_IMM8, "11110rrriiiiiiii", XG_R_I, 2, 0xF000, 1, 1, CHG_NONE, ALL}, + { "ldw", OP_IDO5, "01001rrrrrriiiii", XG_R_R_I, 2, 0x4800, 2, 2, CHG_NONE, ALL}, + { "ldw", OP_IDR, "01101rrrrrrrrrrr", XG_R_R_R, 2, 0x6800, 2, 2, CHG_NONE, ALL}, + { "lsl", OP_IMM4, "00001rrriiii1100", XG_R_I, 2, 0x080C, 1, 1, CHG_NZVC, ALL}, + { "lsl", OP_DYA, "00001rrrrrr10100", XG_R_R, 2, 0x0814, 1, 1, CHG_NZVC, ALL}, + { "lsr", OP_IMM4, "00001rrriiii1101", XG_R_I, 2, 0x080D, 1, 1, CHG_NZVC, ALL}, + { "lsr", OP_DYA, "00001rrrrrr10101", XG_R_R, 2, 0x0815, 1, 1, CHG_NZVC, ALL}, + { "nop", OP_INH, "0000000100000000", XG_INH, 2, 0x0100, 1, 1, CHG_NONE, ALL}, + { "or", OP_TRI, "00010rrrrrrrrr10", XG_R_R_R, 2, 0x1002, 1, 1, CHG_NZV, ALL}, + { "orh", OP_IMM8, "10101rrriiiiiiii", XG_R_I, 2, 0xA800, 1, 1, CHG_NZV, ALL}, + { "orl", OP_IMM8, "10100rrriiiiiiii", XG_R_I, 2, 0xA000, 1, 1, CHG_NZV, ALL}, + { "par", OP_MON, "00000rrr11110101", XG_R, 2, 0x00F5, 1, 1, CHG_NZV, ALL}, + { "rol", OP_IMM4, "00001rrriiii1110", XG_R_I, 2, 0x080E, 1, 1, CHG_NZV, ALL}, + { "rol", OP_DYA, "00001rrrrrr10110", XG_R_R, 2, 0x0816, 1, 1, CHG_NZV, ALL}, + { "ror", OP_IMM4, "00001rrriiii1111", XG_R_I, 2, 0x080F, 1, 1, CHG_NZV, ALL}, + { "ror", OP_DYA, "00001rrrrrr10111", XG_R_R, 2, 0x0817, 1, 1, CHG_NZV, ALL}, + { "rts", OP_INH, "0000001000000000", XG_INH, 2, 0x0200, 2, 2, CHG_NONE, ALL}, + { "sbc", OP_TRI, "00011rrrrrrrrr01", XG_R_R_R, 2, 0x1801, 1, 1, CHG_NZV, ALL}, + { "ssem", OP_IMM3, "00000iii11110010", XG_I , 2, 0x00F2, 2, 2, CHG_C, ALL}, + { "ssem", OP_MON, "00000rrr11110011", XG_R, 2, 0x00F3, 2, 2, CHG_C, ALL}, + { "sex", OP_MON, "00000rrr11110100", XG_R, 2, 0x00F4, 1, 1, CHG_NZV, ALL}, + { "sif", OP_INH, "0000001100000000", XG_INH, 2, 0x0300, 2, 2, CHG_NONE, ALL}, + { "sif", OP_MON, "00000rrr11110111", XG_R, 2, 0x00F7, 2, 2, CHG_NONE, ALL}, + { "stb", OP_IDO5, "01010rrrrrriiiii", XG_R_R_I, 2, 0x5000, 2, 2, CHG_NONE, ALL}, + { "stb", OP_IDR, "01110rrrrrrrrrrr", XG_R_R_R, 2, 0x7000, 2, 2, CHG_NONE, ALL}, + { "stw", OP_IDO5, "01011rrrrrriiiii", XG_R_R_I, 2, 0x5800, 2, 2, CHG_NONE, ALL}, + { "stw", OP_IDR, "01111rrrrrrrrrrr", XG_R_R_R, 2, 0x7800, 2, 2, CHG_NONE, ALL}, + { "sub", OP_TRI, "00011rrrrrrrrr00", XG_R_R_R, 2, 0x1800, 1, 1, CHG_NZVC, ALL}, + { "subh", OP_IMM8, "11001rrriiiiiiii", XG_R_I, 2, 0xC800, 1, 1, CHG_NZVC, ALL}, + { "subl", OP_IMM8, "11000rrriiiiiiii", XG_R_I, 2, 0xC000, 1, 1, CHG_NZVC, ALL}, + { "tfr", OP_MON_R_C, "00000rrr11111000",XG_R_C, 2, 0x00F8, 1, 1, CHG_NONE, ALL}, + { "tfr", OP_MON_C_R, "00000rrr11111001",XG_C_R, 2, 0x00F9, 1, 1, CHG_NONE, ALL}, + { "tfr", OP_MON_R_P, "00000rrr11111010",XG_R_P, 2, 0x00FA, 1, 1, CHG_NONE, ALL}, + { "xnor", OP_TRI, "00010rrrrrrrrr11", XG_R_R_R, 2, 0x1003, 1, 1, CHG_NZV, ALL}, + { "xnorh", OP_IMM8, "10111rrriiiiiiii", XG_R_I, 2, 0xB800, 1, 1, CHG_NZV, ALL}, + { "xnorl", OP_IMM8, "10110rrriiiiiiii", XG_R_I, 2, 0xB000, 1, 1, CHG_NZV, ALL}, + /* macro and alias codes */ + { "add", OP_mADD, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "and", OP_mAND, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "bhs", OP_REL9, "0010000iiiiiiiii", XG_IP, 2, 0x2000, 0, 0, CHG_NONE, ALL}, + { "blo", OP_REL9, "0010001iiiiiiiii", XG_IP, 2, 0x2200, 0, 0, CHG_NONE, ALL}, + { "cmp", OP_mCPC, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "cmp", OP_DYA, "00011sssrrrrrr00", XG_R_R, 2, 0x1800, 0, 0, CHG_NZVC, ALL}, + { "com", OP_DM, "00010rrrsssrrr11", XG_R_R, 2, 0x1003, 0, 0, CHG_NZV, ALL}, + { "cpc", OP_DYA, "00011sssrrrrrr01", XG_R_R, 2, 0x1801, 0, 0, CHG_NZVC, ALL}, + { "ldd", OP_mLDW, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "ldw", OP_mLDW, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "mov", OP_DYA, "00010rrrsssrrr10", XG_R_R, 2, 0x1002, 0, 0, CHG_NZVC, ALL}, + { "neg", OP_DYA, "00011rrrsssrrr00", XG_R_R, 2, 0x1800, 0, 0, CHG_NZVC, ALL}, + { "sub", OP_mSUB, "----------------", XG_R_I, 4, 0, 0, 0, CHG_NONE, ALL}, + { "tst", OP_MON, "00011sssrrrsss00", XG_R, 2, 0x1800, 0, 0, CHG_NZV, ALL} +}; + +const int xgate_num_opcodes = TABLE_SIZE (xgate_opcodes); -- 2.34.1