diff -rNU3 dist.orig/bfd/ChangeLog dist/bfd/ChangeLog --- dist.orig/bfd/ChangeLog 2013-03-25 10:08:08.000000000 +0100 +++ dist/bfd/ChangeLog 2015-10-18 13:11:12.000000000 +0200 @@ -1,3 +1,8 @@ +2013-12-14 Alan Modra + + * elflink.c (_bfd_elf_merge_symbol): If merging a new weak + symbol that will be skipped, we don't have a new definition. + 2013-03-25 Tristan Gingold * configure.in: Bump version to 2.23.2 diff -rNU3 dist.orig/bfd/Makefile.am dist/bfd/Makefile.am --- dist.orig/bfd/Makefile.am 2013-03-25 10:08:05.000000000 +0100 +++ dist/bfd/Makefile.am 2015-10-18 13:11:13.000000000 +0200 @@ -897,6 +897,18 @@ sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new mv -f elf64-ia64.new elf64-ia64.c +elf32-riscv.c : elfnn-riscv.c + rm -f elf32-riscv.c + echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf32-riscv.new + sed -e s/NN/32/g < $(srcdir)/elfnn-riscv.c >> elf32-riscv.new + mv -f elf32-riscv.new elf32-riscv.c + +elf64-riscv.c : elfnn-riscv.c + rm -f elf64-riscv.c + echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf64-riscv.new + sed -e s/NN/64/g < $(srcdir)/elfnn-riscv.c >> elf64-riscv.new + mv -f elf64-riscv.new elf64-riscv.c + peigen.c : peXXigen.c rm -f peigen.c sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new diff -rNU3 dist.orig/bfd/Makefile.in dist/bfd/Makefile.in --- dist.orig/bfd/Makefile.in 2013-03-25 10:08:08.000000000 +0100 +++ dist/bfd/Makefile.in 2015-10-18 13:11:13.000000000 +0200 @@ -419,7 +419,7 @@ cpu-mt.lo \ cpu-ns32k.lo \ cpu-openrisc.lo \ - cpu-or32.lo \ + cpu-or1k.lo \ cpu-pdp11.lo \ cpu-pj.lo \ cpu-plugin.lo \ @@ -500,7 +500,7 @@ cpu-mt.c \ cpu-ns32k.c \ cpu-openrisc.c \ - cpu-or32.c \ + cpu-or1k.c \ cpu-pdp11.c \ cpu-pj.c \ cpu-plugin.c \ @@ -559,7 +559,7 @@ coff-m68k.lo \ coff-m88k.lo \ coff-mips.lo \ - coff-or32.lo \ + coff-or1k.lo \ coff-rs6000.lo \ coff-sh.lo \ coff-sparc.lo \ @@ -627,7 +627,7 @@ elf32-msp430.lo \ elf32-mt.lo \ elf32-openrisc.lo \ - elf32-or32.lo \ + elf32-or1k.lo \ elf32-pj.lo \ elf32-ppc.lo \ elf32-rl78.lo \ @@ -747,7 +747,7 @@ coff-m68k.c \ coff-m88k.c \ coff-mips.c \ - coff-or32.c \ + coff-or1k.c \ coff-rs6000.c \ coff-sh.c \ coff-sparc.c \ @@ -815,7 +815,7 @@ elf32-msp430.c \ elf32-mt.c \ elf32-openrisc.c \ - elf32-or32.c \ + elf32-or1k.c \ elf32-pj.c \ elf32-ppc.c \ elf32-rl78.c \ @@ -1253,7 +1253,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-m68k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-m88k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-mips.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-or32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-or1k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-rs6000.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-sh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-sparc.Plo@am__quote@ @@ -1323,7 +1323,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ns32k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-openrisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-or32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-or1k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-pdp11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-pj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-plugin.Plo@am__quote@ @@ -1408,7 +1408,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-msp430.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-openrisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-or32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-or1k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-pj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-ppc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-rl78.Plo@am__quote@ @@ -1967,6 +1967,18 @@ sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new mv -f elf64-ia64.new elf64-ia64.c +elf32-riscv.c : elfnn-riscv.c + rm -f elf32-riscv.c + echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf32-riscv.new + sed -e s/NN/32/g < $(srcdir)/elfnn-riscv.c >> elf32-riscv.new + mv -f elf32-riscv.new elf32-riscv.c + +elf64-riscv.c : elfnn-riscv.c + rm -f elf64-riscv.c + echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf64-riscv.new + sed -e s/NN/64/g < $(srcdir)/elfnn-riscv.c >> elf64-riscv.new + mv -f elf64-riscv.new elf64-riscv.c + peigen.c : peXXigen.c rm -f peigen.c sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new diff -rNU3 dist.orig/bfd/aoutx.h dist/bfd/aoutx.h --- dist.orig/bfd/aoutx.h 2012-05-01 18:07:33.000000000 +0200 +++ dist/bfd/aoutx.h 2015-10-18 13:11:12.000000000 +0200 @@ -762,7 +762,7 @@ break; case bfd_arch_arm: - if (machine == 0) + if (machine == 0 || machine == 5) arch_flags = M_ARM; break; diff -rNU3 dist.orig/bfd/archive.c dist/bfd/archive.c --- dist.orig/bfd/archive.c 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/archive.c 2015-10-18 13:11:12.000000000 +0200 @@ -157,6 +157,9 @@ #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen) #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) + +static const char * normalize (bfd *, const char *); + #define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata (bfd)->arch_header) /* True iff NAME designated a BSD 4.4 extended name. */ @@ -760,7 +763,9 @@ /* Pad to an even boundary... Note that last_file->origin can be odd in the case of BSD-4.4-style element with a long odd size. */ - filestart += filestart % 2; + if (!strncmp(arch_hdr (last_file)->ar_name, "#1/", 3)) + size += strlen(normalize(last_file, last_file->filename)); + filestart += size % 2; } return _bfd_get_elt_at_filepos (archive, filestart); @@ -2180,11 +2185,22 @@ current = current->archive_next) { char buffer[DEFAULT_BUFFERSIZE]; - bfd_size_type remaining = arelt_size (current); + bfd_size_type saved_size = arelt_size (current); + bfd_size_type remaining = saved_size; + struct ar_hdr *hdr = arch_hdr (current); /* Write ar header. */ if (!_bfd_write_ar_hdr (arch, current)) - return FALSE; + return FALSE; + /* Write filename if it is a 4.4BSD extended file, and add to size. */ + if (!strncmp (hdr->ar_name, "#1/", 3)) + { + const char *normal = normalize (current, current->filename); + unsigned int thislen = strlen (normal); + if (bfd_write (normal, 1, thislen, arch) != thislen) + return FALSE; + saved_size += thislen; + } if (bfd_is_thin_archive (arch)) continue; if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) @@ -2457,11 +2473,19 @@ { do { +#if 1 + bfd_size_type size = arelt_size (current); + if (!strncmp(arch_hdr (current)->ar_name, "#1/", 3)) + size += strlen(normalize(current, current->filename)); + firstreal += size + sizeof (struct ar_hdr); + firstreal += size % 2; +#else struct areltdata *ared = arch_eltdata (current); firstreal += (ared->parsed_size + ared->extra_size + sizeof (struct ar_hdr)); firstreal += firstreal % 2; +#endif current = current->archive_next; } while (current != map[count].u.abfd); diff -rNU3 dist.orig/bfd/archures.c dist/bfd/archures.c --- dist.orig/bfd/archures.c 2012-09-04 14:53:41.000000000 +0200 +++ dist/bfd/archures.c 2015-10-18 13:11:12.000000000 +0200 @@ -123,7 +123,7 @@ .#define bfd_mach_i960_jx 7 .#define bfd_mach_i960_hx 8 . -. bfd_arch_or32, {* OpenRISC 32 *} +. bfd_arch_or1k, {* OpenRISC 32 *} . . bfd_arch_sparc, {* SPARC *} .#define bfd_mach_sparc 1 @@ -245,6 +245,9 @@ .#define bfd_mach_ppc_e6500 5007 .#define bfd_mach_ppc_titan 83 .#define bfd_mach_ppc_vle 84 +. bfd_arch_riscv, {* RISC-V *} +.#define bfd_mach_riscv32 132 +.#define bfd_mach_riscv64 164 . bfd_arch_rs6000, {* IBM RS/6000 *} .#define bfd_mach_rs6k 6000 .#define bfd_mach_rs6k_rs1 6001 @@ -556,12 +559,13 @@ extern const bfd_arch_info_type bfd_mt_arch; extern const bfd_arch_info_type bfd_ns32k_arch; extern const bfd_arch_info_type bfd_openrisc_arch; -extern const bfd_arch_info_type bfd_or32_arch; +extern const bfd_arch_info_type bfd_or1k_arch; extern const bfd_arch_info_type bfd_pdp11_arch; extern const bfd_arch_info_type bfd_pj_arch; extern const bfd_arch_info_type bfd_plugin_arch; extern const bfd_arch_info_type bfd_powerpc_archs[]; #define bfd_powerpc_arch bfd_powerpc_archs[0] +extern const bfd_arch_info_type bfd_riscv_arch; extern const bfd_arch_info_type bfd_rs6000_arch; extern const bfd_arch_info_type bfd_rl78_arch; extern const bfd_arch_info_type bfd_rx_arch; @@ -642,9 +646,10 @@ &bfd_mt_arch, &bfd_ns32k_arch, &bfd_openrisc_arch, - &bfd_or32_arch, + &bfd_or1k_arch, &bfd_pdp11_arch, &bfd_powerpc_arch, + &bfd_riscv_arch, &bfd_rs6000_arch, &bfd_rl78_arch, &bfd_rx_arch, diff -rNU3 dist.orig/bfd/bfd-in2.h dist/bfd/bfd-in2.h --- dist.orig/bfd/bfd-in2.h 2012-09-04 14:53:41.000000000 +0200 +++ dist/bfd/bfd-in2.h 2015-10-18 13:11:12.000000000 +0200 @@ -1852,7 +1852,9 @@ #define bfd_mach_i960_jx 7 #define bfd_mach_i960_hx 8 - bfd_arch_or32, /* OpenRISC 32 */ + bfd_arch_or1k, /* OpenRISC 1000 */ +#define bfd_mach_or1k 1 +#define bfd_mach_or1knd 2 bfd_arch_sparc, /* SPARC */ #define bfd_mach_sparc 1 @@ -1974,6 +1976,9 @@ #define bfd_mach_ppc_e6500 5007 #define bfd_mach_ppc_titan 83 #define bfd_mach_ppc_vle 84 + bfd_arch_riscv, /* RISC-V */ +#define bfd_mach_riscv32 132 +#define bfd_mach_riscv64 164 bfd_arch_rs6000, /* IBM RS/6000 */ #define bfd_mach_rs6k 6000 #define bfd_mach_rs6k_rs1 6001 @@ -4803,9 +4808,66 @@ BFD_RELOC_860_HIGOT, BFD_RELOC_860_HIGOTOFF, -/* OpenRISC Relocations. */ - BFD_RELOC_OPENRISC_ABS_26, - BFD_RELOC_OPENRISC_REL_26, +/* OpenRISC 1000 Relocations. */ + BFD_RELOC_OR1K_REL_26, + BFD_RELOC_OR1K_GOTPC_HI16, + BFD_RELOC_OR1K_GOTPC_LO16, + BFD_RELOC_OR1K_GOT16, + BFD_RELOC_OR1K_PLT26, + BFD_RELOC_OR1K_GOTOFF_HI16, + BFD_RELOC_OR1K_GOTOFF_LO16, + BFD_RELOC_OR1K_COPY, + BFD_RELOC_OR1K_GLOB_DAT, + BFD_RELOC_OR1K_JMP_SLOT, + BFD_RELOC_OR1K_RELATIVE, + BFD_RELOC_OR1K_TLS_GD_HI16, + BFD_RELOC_OR1K_TLS_GD_LO16, + BFD_RELOC_OR1K_TLS_LDM_HI16, + BFD_RELOC_OR1K_TLS_LDM_LO16, + BFD_RELOC_OR1K_TLS_LDO_HI16, + BFD_RELOC_OR1K_TLS_LDO_LO16, + BFD_RELOC_OR1K_TLS_IE_HI16, + BFD_RELOC_OR1K_TLS_IE_LO16, + BFD_RELOC_OR1K_TLS_LE_HI16, + BFD_RELOC_OR1K_TLS_LE_LO16, + BFD_RELOC_OR1K_TLS_TPOFF, + BFD_RELOC_OR1K_TLS_DTPOFF, + BFD_RELOC_OR1K_TLS_DTPMOD, + +/* RISC-V relocations. */ + BFD_RELOC_RISCV_HI20, + BFD_RELOC_RISCV_PCREL_HI20, + BFD_RELOC_RISCV_PCREL_LO12_I, + BFD_RELOC_RISCV_PCREL_LO12_S, + BFD_RELOC_RISCV_LO12_I, + BFD_RELOC_RISCV_LO12_S, + BFD_RELOC_RISCV_GPREL12_I, + BFD_RELOC_RISCV_GPREL12_S, + BFD_RELOC_RISCV_TPREL_HI20, + BFD_RELOC_RISCV_TPREL_LO12_I, + BFD_RELOC_RISCV_TPREL_LO12_S, + BFD_RELOC_RISCV_TPREL_ADD, + BFD_RELOC_RISCV_CALL, + BFD_RELOC_RISCV_CALL_PLT, + BFD_RELOC_RISCV_ADD8, + BFD_RELOC_RISCV_ADD16, + BFD_RELOC_RISCV_ADD32, + BFD_RELOC_RISCV_ADD64, + BFD_RELOC_RISCV_SUB8, + BFD_RELOC_RISCV_SUB16, + BFD_RELOC_RISCV_SUB32, + BFD_RELOC_RISCV_SUB64, + BFD_RELOC_RISCV_GOT_HI20, + BFD_RELOC_RISCV_TLS_GOT_HI20, + BFD_RELOC_RISCV_TLS_GD_HI20, + BFD_RELOC_RISCV_JMP, + BFD_RELOC_RISCV_TLS_DTPMOD32, + BFD_RELOC_RISCV_TLS_DTPREL32, + BFD_RELOC_RISCV_TLS_DTPMOD64, + BFD_RELOC_RISCV_TLS_DTPREL64, + BFD_RELOC_RISCV_TLS_TPREL32, + BFD_RELOC_RISCV_TLS_TPREL64, + BFD_RELOC_RISCV_ALIGN, /* H8 elf Relocations. */ BFD_RELOC_H8_DIR16A8, @@ -5788,6 +5850,11 @@ /* This BFD has been created by the linker and doesn't correspond to any input file. */ #define BFD_LINKER_CREATED 0x2000 + /* This may be set before writing out a BFD to request that it + be written using values for UIDs, GIDs, timestamps, etc. that + will be consistent from run to run. */ +#define BFD_DETERMINISTIC_OUTPUT 0x4000 + /* This may be set before writing out a BFD to request that it be written using values for UIDs, GIDs, timestamps, etc. that diff -rNU3 dist.orig/bfd/coff-alpha.c dist/bfd/coff-alpha.c --- dist.orig/bfd/coff-alpha.c 2012-07-13 16:22:42.000000000 +0200 +++ dist/bfd/coff-alpha.c 2015-10-18 13:11:12.000000000 +0200 @@ -642,7 +642,9 @@ case ALPHA_R_OP_STORE: /* The STORE reloc needs the size and offset fields. We store them in the addend. */ +#if 0 BFD_ASSERT (intern->r_offset <= 256); +#endif rptr->addend = (intern->r_offset << 8) + intern->r_size; break; diff -rNU3 dist.orig/bfd/coff-or32.c dist/bfd/coff-or32.c --- dist.orig/bfd/coff-or32.c 2012-07-13 16:22:43.000000000 +0200 +++ dist/bfd/coff-or32.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,629 +0,0 @@ -/* BFD back-end for OpenRISC 1000 COFF binaries. - Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 - Free Software Foundation, Inc. - Contributed by Ivan Guzvinec - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#define OR32 1 - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "coff/or32.h" -#include "coff/internal.h" -#include "libcoff.h" - -static bfd_reloc_status_type or32_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -#define INSERT_HWORD(WORD,HWORD) \ - (((WORD) & 0xffff0000) | ((HWORD)& 0x0000ffff)) -#define EXTRACT_HWORD(WORD) \ - ((WORD) & 0x0000ffff) -#define SIGN_EXTEND_HWORD(HWORD) \ - ((HWORD) & 0x8000 ? (HWORD)|(~0xffffL) : (HWORD)) - -#define INSERT_JUMPTARG(WORD,JT) \ - (((WORD) & 0xfc000000) | ((JT)& 0x03ffffff)) -#define EXTRACT_JUMPTARG(WORD) \ - ((WORD) & 0x03ffffff) -#define SIGN_EXTEND_JUMPTARG(JT) \ - ((JT) & 0x04000000 ? (JT)|(~0x03ffffffL) : (JT)) - -/* Provided the symbol, returns the value reffed. */ - -static long -get_symbol_value (asymbol *symbol) -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - - return relocation; -} - -/* This function is in charge of performing all the or32 relocations. */ - -static bfd_reloc_status_type -or32_reloc (bfd *abfd, - arelent *reloc_entry, - asymbol *symbol_in, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message) -{ - /* The consth relocation comes in two parts, we have to remember - the state between calls, in these variables. */ - static bfd_boolean part1_consth_active = FALSE; - static unsigned long part1_consth_value; - - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; - - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - - r_type = reloc_entry->howto->type; - - if (output_bfd) - { - /* Partial linking - do nothing. */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - { - /* Keep the state machine happy in case we're called again. */ - if (r_type == R_IHIHALF) - { - part1_consth_active = TRUE; - part1_consth_value = 0; - } - - return bfd_reloc_undefined; - } - - if ((part1_consth_active) && (r_type != R_IHCONST)) - { - part1_consth_active = FALSE; - *error_message = (char *) "Missing IHCONST"; - - return bfd_reloc_dangerous; - } - - sym_value = get_symbol_value (symbol_in); - - switch (r_type) - { - case R_IREL: - insn = bfd_get_32(abfd, hit_data); - - /* Take the value in the field and sign extend it. */ - signed_value = EXTRACT_JUMPTARG (insn); - signed_value = SIGN_EXTEND_JUMPTARG (signed_value); - signed_value <<= 2; - - /* See the note on the R_IREL reloc in coff_or32_relocate_section. */ - if (signed_value == - (long) reloc_entry->address) - signed_value = 0; - - signed_value += sym_value + reloc_entry->addend; - /* Relative jmp/call, so subtract from the value the - address of the place we're coming from. */ - signed_value -= (reloc_entry->address - + input_section->output_section->vma - + input_section->output_offset); - if (signed_value > 0x7ffffff || signed_value < -0x8000000) - return bfd_reloc_overflow; - - signed_value >>= 2; - insn = INSERT_JUMPTARG (insn, signed_value); - bfd_put_32 (abfd, insn, hit_data); - break; - - case R_ILOHALF: - insn = bfd_get_32 (abfd, hit_data); - unsigned_value = EXTRACT_HWORD (insn); - unsigned_value += sym_value + reloc_entry->addend; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (abfd, insn, hit_data); - break; - - case R_IHIHALF: - insn = bfd_get_32 (abfd, hit_data); - - /* consth, part 1 - Just get the symbol value that is referenced. */ - part1_consth_active = TRUE; - part1_consth_value = sym_value + reloc_entry->addend; - - /* Don't modify insn until R_IHCONST. */ - break; - - case R_IHCONST: - insn = bfd_get_32 (abfd, hit_data); - - /* consth, part 2 - Now relocate the reference. */ - if (! part1_consth_active) - { - *error_message = (char *) "Missing IHIHALF"; - return bfd_reloc_dangerous; - } - - /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */ - unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/ - unsigned_value += reloc_entry->addend; /* r_symndx */ - unsigned_value += part1_consth_value; - unsigned_value = unsigned_value >> 16; - insn = INSERT_HWORD (insn, unsigned_value); - part1_consth_active = FALSE; - bfd_put_32 (abfd, insn, hit_data); - break; - - case R_BYTE: - insn = bfd_get_8 (abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffffff00) - return bfd_reloc_overflow; - bfd_put_8 (abfd, unsigned_value, hit_data); - break; - - case R_HWORD: - insn = bfd_get_16 (abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffff0000) - return bfd_reloc_overflow; - bfd_put_16 (abfd, insn, hit_data); - break; - - case R_WORD: - insn = bfd_get_32 (abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32 (abfd, insn, hit_data); - break; - - default: - *error_message = _("Unrecognized reloc"); - return bfd_reloc_dangerous; - } - - return bfd_reloc_ok; -} - -/* type rightshift - size - bitsize - pc-relative - bitpos - absolute - complain_on_overflow - special_function - relocation name - partial_inplace - src_mask -*/ - -/* FIXME: I'm not real sure about this table. */ -static reloc_howto_type howto_table[] = -{ - { R_ABS, 0, 3, 32, FALSE, 0, complain_overflow_bitfield, or32_reloc, "ABS", TRUE, 0xffffffff,0xffffffff, FALSE }, - EMPTY_HOWTO (1), - EMPTY_HOWTO (2), - EMPTY_HOWTO (3), - EMPTY_HOWTO (4), - EMPTY_HOWTO (5), - EMPTY_HOWTO (6), - EMPTY_HOWTO (7), - EMPTY_HOWTO (8), - EMPTY_HOWTO (9), - EMPTY_HOWTO (10), - EMPTY_HOWTO (11), - EMPTY_HOWTO (12), - EMPTY_HOWTO (13), - EMPTY_HOWTO (14), - EMPTY_HOWTO (15), - EMPTY_HOWTO (16), - EMPTY_HOWTO (17), - EMPTY_HOWTO (18), - EMPTY_HOWTO (19), - EMPTY_HOWTO (20), - EMPTY_HOWTO (21), - EMPTY_HOWTO (22), - EMPTY_HOWTO (23), - { R_IREL, 0, 3, 32, TRUE, 0, complain_overflow_signed, or32_reloc, "IREL", TRUE, 0xffffffff,0xffffffff, FALSE }, - { R_IABS, 0, 3, 32, FALSE, 0, complain_overflow_bitfield, or32_reloc, "IABS", TRUE, 0xffffffff,0xffffffff, FALSE }, - { R_ILOHALF, 0, 3, 16, TRUE, 0, complain_overflow_signed, or32_reloc, "ILOHALF", TRUE, 0x0000ffff,0x0000ffff, FALSE }, - { R_IHIHALF, 0, 3, 16, TRUE, 16,complain_overflow_signed, or32_reloc, "IHIHALF", TRUE, 0xffff0000,0xffff0000, FALSE }, - { R_IHCONST, 0, 3, 16, TRUE, 0, complain_overflow_signed, or32_reloc, "IHCONST", TRUE, 0xffff0000,0xffff0000, FALSE }, - { R_BYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, or32_reloc, "BYTE", TRUE, 0x000000ff,0x000000ff, FALSE }, - { R_HWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, or32_reloc, "HWORD", TRUE, 0x0000ffff,0x0000ffff, FALSE }, - { R_WORD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, or32_reloc, "WORD", TRUE, 0xffffffff,0xffffffff, FALSE }, -}; - -#define BADMAG(x) OR32BADMAG (x) - -#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \ - reloc_processing (relent, reloc, symbols, abfd, section) - -static void -reloc_processing (arelent *relent, - struct internal_reloc *reloc, - asymbol **symbols, - bfd *abfd, - asection *section) -{ - static bfd_vma ihihalf_vaddr = (bfd_vma) -1; - - relent->address = reloc->r_vaddr; - relent->howto = howto_table + reloc->r_type; - - if (reloc->r_type == R_IHCONST) - { - /* The address of an R_IHCONST should always be the address of - the immediately preceding R_IHIHALF. relocs generated by gas - are correct, but relocs generated by High C are different (I - can't figure out what the address means for High C). We can - handle both gas and High C by ignoring the address here, and - simply reusing the address saved for R_IHIHALF. */ - if (ihihalf_vaddr == (bfd_vma) -1) - abort (); - - relent->address = ihihalf_vaddr; - ihihalf_vaddr = (bfd_vma) -1; - relent->addend = reloc->r_symndx; - relent->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr; - } - else - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - relent->addend = 0; - relent->address-= section->vma; - - if (reloc->r_type == R_IHIHALF) - ihihalf_vaddr = relent->address; - else if (ihihalf_vaddr != (bfd_vma) -1) - abort (); - } -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static bfd_boolean -coff_or32_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - struct internal_reloc *relocs, - struct internal_syment *syms, - asection **sections) -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - bfd_boolean hihalf; - bfd_vma hihalf_val; - - /* If we are performing a relocatable link, we don't need to do a - thing. The caller will take care of adjusting the reloc - addresses and symbol indices. */ - if (info->relocatable) - return TRUE; - - hihalf = FALSE; - hihalf_val = 0; - - rel = relocs; - relend = rel + input_section->reloc_count; - - for (; rel < relend; rel++) - { - long symndx; - bfd_byte *loc; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - asection *sec; - bfd_vma val; - bfd_boolean overflow; - unsigned long insn; - long signed_value; - unsigned long unsigned_value; - bfd_reloc_status_type rstat; - - symndx = rel->r_symndx; - loc = contents + rel->r_vaddr - input_section->vma; - - if (symndx == -1 || rel->r_type == R_IHCONST) - h = NULL; - else - h = obj_coff_sym_hashes (input_bfd)[symndx]; - - sym = NULL; - sec = NULL; - val = 0; - - /* An R_IHCONST reloc does not have a symbol. Instead, the - symbol index is an addend. R_IHCONST is always used in - conjunction with R_IHHALF. */ - if (rel->r_type != R_IHCONST) - { - if (h == NULL) - { - if (symndx == -1) - sec = bfd_abs_section_ptr; - else - { - sym = syms + symndx; - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma, TRUE))) - return FALSE; - } - } - - if (hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHCONST reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return FALSE; - hihalf = FALSE; - } - } - - overflow = FALSE; - - switch (rel->r_type) - { - default: - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_IREL: - insn = bfd_get_32 (input_bfd, loc); - - /* Extract the addend. */ - signed_value = EXTRACT_JUMPTARG (insn); - signed_value = SIGN_EXTEND_JUMPTARG (signed_value); - signed_value <<= 2; - - /* Determine the destination of the jump. */ - signed_value += val; - - /* Make the destination PC relative. */ - signed_value -= (input_section->output_section->vma - + input_section->output_offset - + (rel->r_vaddr - input_section->vma)); - if (signed_value > 0x7ffffff || signed_value < - 0x8000000) - { - overflow = TRUE; - signed_value = 0; - } - - /* Put the adjusted value back into the instruction. */ - signed_value >>= 2; - insn = INSERT_JUMPTARG(insn, signed_value); - - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - break; - - case R_ILOHALF: - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = EXTRACT_HWORD (insn); - unsigned_value += val; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, insn, loc); - break; - - case R_IHIHALF: - /* Save the value for the R_IHCONST reloc. */ - hihalf = TRUE; - hihalf_val = val; - break; - - case R_IHCONST: - if (! hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHIHALF reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return FALSE; - hihalf_val = 0; - } - - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = rel->r_symndx + hihalf_val; - unsigned_value >>= 16; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - - hihalf = FALSE; - break; - - case R_BYTE: - case R_HWORD: - case R_WORD: - rstat = _bfd_relocate_contents (howto_table + rel->r_type, - input_bfd, val, loc); - if (rstat == bfd_reloc_overflow) - overflow = TRUE; - else if (rstat != bfd_reloc_ok) - abort (); - break; - } - - if (overflow) - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = NULL; - else if (sym == NULL) - name = "*unknown*"; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, - howto_table[rel->r_type].name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return FALSE; - } - } - - return TRUE; -} - -#define coff_relocate_section coff_or32_relocate_section - -/* We don't want to change the symndx of a R_IHCONST reloc, since it - is actually an addend, not a symbol index at all. */ - -static bfd_boolean -coff_or32_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - bfd *ibfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED, - struct internal_reloc *irel, - bfd_boolean *adjustedp) -{ - if (irel->r_type == R_IHCONST) - *adjustedp = TRUE; - else - *adjustedp = FALSE; - return TRUE; -} - -#define coff_adjust_symndx coff_or32_adjust_symndx - -#ifndef bfd_pe_print_pdata -#define bfd_pe_print_pdata NULL -#endif - -#include "coffcode.h" - -const bfd_target or32coff_big_vec = -{ - "coff-or32-big", /* Name. */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* Data byte order is big. */ - BFD_ENDIAN_BIG, /* Header byte order is big. */ - - (HAS_RELOC | EXEC_P | /* Object flags. */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | /* Section flags. */ - SEC_LOAD | SEC_RELOC | - SEC_READONLY ), - '_', /* Leading underscore. */ - '/', /* ar_pad_char. */ - 15, /* ar_max_namelen. */ - 0, /* match priority. */ - - /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Headers. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - { - _bfd_dummy_target, - coff_object_p, - bfd_generic_archive_p, - _bfd_dummy_target - }, - { - bfd_false, - coff_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - coff_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - /* Alternative_target. */ -#ifdef TARGET_LITTLE_SYM - & TARGET_LITTLE_SYM, -#else - NULL, -#endif - - COFF_SWAP_TABLE -}; diff -rNU3 dist.orig/bfd/coffcode.h dist/bfd/coffcode.h --- dist.orig/bfd/coffcode.h 2011-09-27 18:03:49.000000000 +0200 +++ dist/bfd/coffcode.h 2015-10-18 13:11:12.000000000 +0200 @@ -2083,12 +2083,6 @@ machine = 0; switch (internal_f->f_magic) { -#ifdef OR32_MAGIC_BIG - case OR32_MAGIC_BIG: - case OR32_MAGIC_LITTLE: - arch = bfd_arch_or32; - break; -#endif #ifdef PPCMAGIC case PPCMAGIC: arch = bfd_arch_powerpc; @@ -3055,15 +3049,6 @@ return TRUE; #endif -#ifdef OR32_MAGIC_BIG - case bfd_arch_or32: - if (bfd_big_endian (abfd)) - * magicp = OR32_MAGIC_BIG; - else - * magicp = OR32_MAGIC_LITTLE; - return TRUE; -#endif - default: /* Unknown architecture. */ /* Fall through to "return FALSE" below, to avoid "statement never reached" errors on the one below. */ diff -rNU3 dist.orig/bfd/config.bfd dist/bfd/config.bfd --- dist.orig/bfd/config.bfd 2012-09-04 16:14:59.000000000 +0200 +++ dist/bfd/config.bfd 2015-10-18 13:11:12.000000000 +0200 @@ -86,16 +86,18 @@ i[3-7]86) targ_archs=bfd_i386_arch ;; i370) targ_archs=bfd_i370_arch ;; lm32) targ_archs=bfd_lm32_arch ;; +m5200|m5407) targ_archs=bfd_m68k_arch ;; m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;; m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;; m68*) targ_archs=bfd_m68k_arch ;; m88*) targ_archs=bfd_m88k_arch ;; microblaze*) targ_archs=bfd_microblaze_arch ;; mips*) targ_archs=bfd_mips_arch ;; -or32*) targ_archs=bfd_or32_arch ;; +or1k*) targ_archs=bfd_or1k_arch ;; pdp11*) targ_archs=bfd_pdp11_arch ;; pj*) targ_archs="bfd_pj_arch bfd_i386_arch";; powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; +riscv*) targ_archs=bfd_riscv_arch ;; rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; s390*) targ_archs=bfd_s390_arch ;; sh*) targ_archs=bfd_sh_arch ;; @@ -164,6 +166,16 @@ targ_selvecs="bfd_elf64_littleaarch64_vec bfd_elf32_bigarm_vec bfd_elf32_littlearm_vec" want64=true ;; + aarch64-*-netbsd*) + targ_defvec=bfd_elf64_littleaarch64_vec + targ_selvecs="bfd_elf64_bigaarch64_vec bfd_elf32_littlearm_vec bfd_elf32_bigarm_vec" + want64=true + ;; + aarch64_be-*-netbsd*) + targ_defvec=bfd_elf64_bigaarch64_vec + targ_selvecs="bfd_elf64_littleaarch64_vec bfd_elf32_bigarm_vec bfd_elf32_littlearm_vec" + want64=true + ;; alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) targ_defvec=bfd_elf64_alpha_freebsd_vec targ_selvecs="bfd_elf64_alpha_vec ecoffalpha_little_vec" @@ -250,17 +262,17 @@ targ64_selvecs="bfd_elf32_x86_64_nacl_vec bfd_elf64_x86_64_nacl_vec" targ_archs="$targ_archs bfd_i386_arch" ;; - armeb-*-netbsdelf*) + arm*eb-*-netbsdelf*) targ_defvec=bfd_elf32_bigarm_vec - targ_selvecs="bfd_elf32_littlearm_vec armnetbsd_vec" + targ_selvecs="bfd_elf32_littlearm_vec armnetbsd_vec armcoff_little_vec armcoff_big_vec" ;; - arm-*-netbsdelf*) + arm*-*-netbsdelf*) targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs="bfd_elf32_bigarm_vec armnetbsd_vec" + targ_selvecs="bfd_elf32_bigarm_vec armnetbsd_vec armcoff_little_vec armcoff_big_vec" ;; arm-*-netbsd* | arm-*-openbsd*) targ_defvec=armnetbsd_vec - targ_selvecs="bfd_elf32_littlearm_vec bfd_elf32_bigarm_vec" + targ_selvecs="bfd_elf32_littlearm_vec bfd_elf32_bigarm_vec armcoff_little_vec armcoff_big_vec" targ_underscore=yes targ_cflags=-D__QNXTARGET__ ;; @@ -574,8 +586,8 @@ ;; i[3-7]86-*-netbsdelf* | i[3-7]86-*-netbsd*-gnu* | i[3-7]86-*-knetbsd*-gnu) targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386netbsd_vec - targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" + targ_selvecs="i386netbsd_vec i386coff_vec i386pei_vec" + targ64_selvecs="bfd_elf64_x86_64_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" ;; i[3-7]86-*-netbsdpe*) targ_defvec=i386pe_vec @@ -845,12 +857,12 @@ # targ_selvecs=m68kmach3_vec # targ_cflags=-DSTAT_FOR_EXEC ;; - m68*-hp*-netbsd*) + m68k4k*-*-netbsd*) targ_defvec=m68k4knetbsd_vec - targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec" + targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec bfd_elf32_m68k_vec" targ_underscore=yes ;; - m68*-*-netbsdelf*) + m68*-*-netbsdelf* | m5407-*-netbsdelf*) targ_defvec=bfd_elf32_m68k_vec targ_selvecs="m68knetbsd_vec m68k4knetbsd_vec hp300bsd_vec sunos_big_vec" ;; @@ -923,6 +935,16 @@ targ_defvec=ecoff_big_vec targ_selvecs=ecoff_little_vec ;; +#ifdef BFD64 + mips64*el-*-netbsd*) + targ_defvec=bfd_elf32_ntradlittlemips_vec + targ_selvecs="bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec" + ;; + mips64*-*-netbsd*) + targ_defvec=bfd_elf32_ntradbigmips_vec + targ_selvecs="bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf32_ntradlittlemips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec" + ;; +#endif mips*el-*-netbsd*) targ_defvec=bfd_elf32_tradlittlemips_vec targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec ecoff_little_vec ecoff_big_vec" @@ -1102,17 +1124,16 @@ targ_underscore=yes ;; - openrisc-*-elf) - targ_defvec=bfd_elf32_openrisc_vec + or1k*-*-elf) + targ_defvec=bfd_elf32_or1k_big_vec ;; - or32-*-coff) - targ_defvec=or32coff_big_vec - targ_underscore=yes + or1k*-*-linux*) + targ_defvec=bfd_elf32_or1k_big_vec ;; - or32-*-elf) - targ_defvec=bfd_elf32_or32_big_vec + or1k*-*-netbsd*) + targ_defvec=bfd_elf32_or1k_big_vec ;; pdp11-*-*) @@ -1252,6 +1273,14 @@ targ_defvec=bfd_elf32_rl78_vec ;; +#ifdef BFD64 + riscv*-*-*) + targ_defvec=bfd_elf64_riscv_vec + targ_selvecs="bfd_elf32_riscv_vec bfd_elf64_riscv_vec" + want64=true + ;; +#endif + rx-*-elf) targ_defvec=bfd_elf32_rx_le_vec targ_selvecs="bfd_elf32_rx_be_vec bfd_elf32_rx_le_vec bfd_elf32_rx_be_ns_vec" @@ -1347,6 +1376,8 @@ want64=true ;; +#endif + sh*l*-*-netbsdelf*) targ_defvec=bfd_elf32_shlnbsd_vec targ_selvecs="bfd_elf32_shnbsd_vec shcoff_vec shlcoff_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec" @@ -1357,8 +1388,6 @@ targ_selvecs="bfd_elf32_shlnbsd_vec shcoff_vec shlcoff_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec" want64=true ;; -#endif - sh*-*-netbsdelf*) targ_defvec=bfd_elf32_shnbsd_vec targ_selvecs="bfd_elf32_shlnbsd_vec shcoff_vec shlcoff_vec" @@ -1448,11 +1477,12 @@ ;; sparc-*-netbsdelf*) targ_defvec=bfd_elf32_sparc_vec - targ_selvecs=sparcnetbsd_vec + targ_selvecs="sparcnetbsd_vec sunos_big_vec" + want64=true ;; - sparc-*-netbsdaout* | sparc-*-netbsd*) + sparc-*-netbsd*) targ_defvec=sparcnetbsd_vec - targ_selvecs=bfd_elf32_sparc_vec + targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec" targ_underscore=yes ;; sparc-*-openbsd[0-2].* | sparc-*-openbsd3.[0-1]) @@ -1500,6 +1530,10 @@ targ_selvecs="bfd_elf32_sparc_vec sparclinux_vec sunos_big_vec" want64=true ;; + sparc64-*-netbsd*) + targ_defvec=bfd_elf64_sparc_vec + targ_selvecs="bfd_elf32_sparc_vec sparcnetbsd_vec sunos_big_vec" + ;; sparc64-*-elf* | sparc64-*-rtems* ) targ_defvec=bfd_elf64_sparc_vec targ_selvecs=bfd_elf32_sparc_vec diff -rNU3 dist.orig/bfd/configure dist/bfd/configure --- dist.orig/bfd/configure 2013-03-25 10:08:07.000000000 +0100 +++ dist/bfd/configure 2015-10-18 13:11:12.000000000 +0200 @@ -12101,10 +12101,10 @@ withval=$with_pkgversion; case "$withval" in yes) as_fn_error "package version not specified" "$LINENO" 5 ;; no) PKGVERSION= ;; - *) PKGVERSION="($withval) " ;; + *) PKGVERSION="($withval)\ " ;; esac else - PKGVERSION="(GNU Binutils) " + PKGVERSION="(GNU Binutils)\ " fi @@ -13861,6 +13861,7 @@ COREFILE=netbsd-core.lo ;; arm-*-riscix) COREFILE=trad-core.lo ;; + arm*-*-netbsd*) COREFILE=netbsd-core.lo ;; hppa*-*-hpux*) COREFILE=hpux-core.lo ;; hppa*-*-hiux*) COREFILE=hpux-core.lo ;; hppa*-*-mpeix*) COREFILE=hpux-core.lo ;; @@ -13923,7 +13924,7 @@ COREFILE=trad-core.lo TRAD_HEADER='"hosts/i860mach3.h"' ;; - mips-*-netbsd* | mips*-*-openbsd*) + mips*-*-netbsd* | mips*-*-openbsd*) COREFILE=netbsd-core.lo ;; mips-dec-*) @@ -15278,14 +15279,14 @@ tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; bfd_elf32_ntradlittlemips_vec | bfd_elf32_ntradlittlemips_freebsd_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; - bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;; - bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;; + bfd_elf32_or1k_big_vec) tb="$tb elf32-or1k.lo elf32.lo $elf" ;; bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; bfd_elf32_pjl_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;; bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;; bfd_elf32_powerpc_freebsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;; bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;; + bfd_elf32_riscv_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf" ;; bfd_elf32_rl78_vec) tb="$tb elf32-rl78.lo $elf" ;; bfd_elf32_rx_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;; bfd_elf32_rx_be_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;; @@ -15356,6 +15357,7 @@ bfd_elf64_powerpc_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_powerpcle_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;; bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;; + bfd_elf64_riscv_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;; bfd_elf64_s390_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_sh64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;; bfd_elf64_sh64l_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;; @@ -15447,7 +15449,6 @@ nlm32_i386_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;; nlm32_powerpc_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;; nlm32_sparc_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;; - or32coff_big_vec) tb="$tb coff-or32.lo cofflink.lo" ;; pc532machaout_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;; pc532netbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;; pef_vec) tb="$tb pef.lo" ;; diff -rNU3 dist.orig/bfd/configure.host dist/bfd/configure.host --- dist.orig/bfd/configure.host 2010-12-31 12:00:52.000000000 +0100 +++ dist/bfd/configure.host 2015-10-18 13:11:12.000000000 +0200 @@ -57,6 +57,18 @@ m68*-hp-hpux*) HDEFINES=-DHOST_HP300HPUX ;; +sparc64*-*-netbsd*) host64=true; HOST_64BIT_TYPE=long ;; + +x86_64*-*-netbsd*) host64=true; HOST_64BIT_TYPE=long ;; + +*-*-aix*) HOST_64BIT_TYPE="long long" + HOST_U_64BIT_TYPE="unsigned long long" + ;; + +*-*-solaris*) HOST_64BIT_TYPE="long long" + HOST_U_64BIT_TYPE="unsigned long long" + ;; + # Some Solaris systems (osol0906 at least) have a libc that doesn't recognise # the "MS-ANSI" code page name, so we define an override for CP_ACP (sets the # default code page used by windres/windmc when not specified by a commandline diff -rNU3 dist.orig/bfd/configure.in dist/bfd/configure.in --- dist.orig/bfd/configure.in 2013-03-25 10:08:05.000000000 +0100 +++ dist/bfd/configure.in 2015-10-18 13:11:12.000000000 +0200 @@ -254,6 +254,7 @@ COREFILE=netbsd-core.lo ;; arm-*-riscix) COREFILE=trad-core.lo ;; + arm*-*-netbsd*) COREFILE=netbsd-core.lo ;; hppa*-*-hpux*) COREFILE=hpux-core.lo ;; hppa*-*-hiux*) COREFILE=hpux-core.lo ;; hppa*-*-mpeix*) COREFILE=hpux-core.lo ;; @@ -340,7 +341,7 @@ COREFILE=trad-core.lo TRAD_HEADER='"hosts/i860mach3.h"' ;; - mips-*-netbsd* | mips*-*-openbsd*) + mips*-*-netbsd* | mips*-*-openbsd*) COREFILE=netbsd-core.lo ;; mips-dec-*) @@ -771,7 +772,8 @@ bfd_elf32_ntradlittlemips_vec | bfd_elf32_ntradlittlemips_freebsd_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;; - bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;; + bfd_elf32_or1k_big_vec) tb="$tb elf32-or1k.lo elf32.lo $elf" ;; + bfd_elf32_riscv_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;; bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; bfd_elf32_pjl_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;; @@ -835,6 +837,7 @@ bfd_elf64_bigaarch64_vec) tb="$tb elf64-aarch64.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_bigmips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;; bfd_elf64_hppa_linux_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_hppa_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_ia64_big_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;; @@ -844,10 +847,12 @@ bfd_elf64_littleaarch64_vec)tb="$tb elf64-aarch64.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_little_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_littlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;; bfd_elf64_mmix_vec) tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;; bfd_elf64_powerpc_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_powerpcle_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;; bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;; + bfd_elf64_riscv_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;; bfd_elf64_s390_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;; bfd_elf64_sh64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;; bfd_elf64_sh64l_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;; @@ -939,7 +944,6 @@ nlm32_i386_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;; nlm32_powerpc_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;; nlm32_sparc_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;; - or32coff_big_vec) tb="$tb coff-or32.lo cofflink.lo" ;; pc532machaout_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;; pc532netbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;; pef_vec) tb="$tb pef.lo" ;; diff -rNU3 dist.orig/bfd/cpu-or1k.c dist/bfd/cpu-or1k.c --- dist.orig/bfd/cpu-or1k.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/cpu-or1k.c 2015-10-18 13:11:12.000000000 +0200 @@ -0,0 +1,61 @@ +/* BFD support for the OpenRISC 1000 architecture. + Copyright 2002, 2005, 2007 Free Software Foundation, Inc. + Contributed by Ivan Guzvinec + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +extern const bfd_arch_info_type bfd_or1knd_arch; + +const bfd_arch_info_type bfd_or1k_arch = + { + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_or1k, + bfd_mach_or1k, + "or1k", + "or1k", + 4, + TRUE, /* The one and only. */ + bfd_default_compatible, + bfd_default_scan, + bfd_arch_default_fill, + &bfd_or1knd_arch, + }; + + +const bfd_arch_info_type bfd_or1knd_arch = + { + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_or1k, + bfd_mach_or1knd, + "or1knd", + "or1knd", + 4, + TRUE, /* The one and only. */ + bfd_default_compatible, + bfd_default_scan, + bfd_arch_default_fill, + 0, + }; diff -rNU3 dist.orig/bfd/cpu-or32.c dist/bfd/cpu-or32.c --- dist.orig/bfd/cpu-or32.c 2012-01-31 18:54:35.000000000 +0100 +++ dist/bfd/cpu-or32.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,42 +0,0 @@ -/* BFD support for the OpenRISC 1000 architecture. - Copyright 2002, 2005, 2007 Free Software Foundation, Inc. - Contributed by Ivan Guzvinec - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_or32_arch = - { - 32, /* 32 bits in a word. */ - 32, /* 32 bits in an address. */ - 8, /* 8 bits in a byte. */ - bfd_arch_or32, - 0, /* Only 1 machine. */ - "or32", - "or32", - 4, - TRUE, /* The one and only. */ - bfd_default_compatible, - bfd_default_scan, - bfd_arch_default_fill, - 0, - }; - diff -rNU3 dist.orig/bfd/cpu-riscv.c dist/bfd/cpu-riscv.c --- dist.orig/bfd/cpu-riscv.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/cpu-riscv.c 2015-10-18 13:11:12.000000000 +0200 @@ -0,0 +1,80 @@ +/* BFD backend for RISC-V + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +static const bfd_arch_info_type *riscv_compatible + (const bfd_arch_info_type *, const bfd_arch_info_type *); + +/* The default routine tests bits_per_word, which is wrong on RISC-V, as + RISC-V word size doesn't correlate with reloc size. */ + +static const bfd_arch_info_type * +riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b) +{ + if (a->arch != b->arch) + return NULL; + + /* Machine compatibility is checked in + _bfd_riscv_elf_merge_private_bfd_data. */ + + return a; +} + +#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \ + { \ + BITS_WORD, /* bits in a word */ \ + BITS_ADDR, /* bits in an address */ \ + 8, /* 8 bits in a byte */ \ + bfd_arch_riscv, \ + NUMBER, \ + "riscv", \ + PRINT, \ + 3, \ + DEFAULT, \ + riscv_compatible, \ + bfd_default_scan, \ + bfd_arch_default_fill, \ + NEXT, \ + } + +enum +{ + I_riscv64, + I_riscv32 +}; + +#define NN(index) (&arch_info_struct[(index) + 1]) + +static const bfd_arch_info_type arch_info_struct[] = +{ + N (64, 64, bfd_mach_riscv64, "riscv:rv64", FALSE, NN(I_riscv64)), + N (32, 32, bfd_mach_riscv32, "riscv:rv32", FALSE, 0) +}; + +/* The default architecture is riscv:rv64. */ + +const bfd_arch_info_type bfd_riscv_arch = +N (64, 64, 0, "riscv", TRUE, &arch_info_struct[0]); diff -rNU3 dist.orig/bfd/doc/Makefile.in dist/bfd/doc/Makefile.in --- dist.orig/bfd/doc/Makefile.in 2013-03-25 10:08:08.000000000 +0100 +++ dist/bfd/doc/Makefile.in 2015-10-18 13:11:12.000000000 +0200 @@ -417,7 +417,9 @@ clean-libtool: -rm -rf .libs _libs -bfd.info: bfd.texinfo $(bfd_TEXINFOS) +bfd.info: + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_bfd.info: bfd.texinfo $(bfd_TEXINFOS) restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ diff -rNU3 dist.orig/bfd/doc/reloc.texi dist/bfd/doc/reloc.texi --- dist.orig/bfd/doc/reloc.texi 2012-11-13 15:19:29.000000000 +0100 +++ dist/bfd/doc/reloc.texi 2015-10-18 13:11:12.000000000 +0200 @@ -570,6 +570,12 @@ @deffnx {} BFD_RELOC_68K_TLS_LE8 Relocations used by 68K ELF. @end deffn +@deffn {} BFD_RELOC_VAX_GLOB_DAT +@deffnx {} BFD_RELOC_VAX_GLOB_REF +@deffnx {} BFD_RELOC_VAX_JMP_SLOT +@deffnx {} BFD_RELOC_VAX_RELATIVE +Relocations used by VAX ELF. +@end deffn @deffn {} BFD_RELOC_32_BASEREL @deffnx {} BFD_RELOC_16_BASEREL @deffnx {} BFD_RELOC_LO16_BASEREL diff -rNU3 dist.orig/bfd/elf-bfd.h dist/bfd/elf-bfd.h --- dist.orig/bfd/elf-bfd.h 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/elf-bfd.h 2015-10-18 13:11:12.000000000 +0200 @@ -420,6 +420,7 @@ MICROBLAZE_ELF_DATA, MIPS_ELF_DATA, MN10300_ELF_DATA, + OR1K_ELF_DATA, PPC32_ELF_DATA, PPC64_ELF_DATA, S390_ELF_DATA, @@ -432,6 +433,7 @@ XGATE_ELF_DATA, TILEGX_ELF_DATA, TILEPRO_ELF_DATA, + RISCV_ELF_DATA, GENERIC_ELF_DATA }; diff -rNU3 dist.orig/bfd/elf.c dist/bfd/elf.c --- dist.orig/bfd/elf.c 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/elf.c 2015-10-18 13:11:12.000000000 +0200 @@ -8756,6 +8756,23 @@ return TRUE; } + /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5. + There's also old PT___GETREGS40 == mach + 1 for old reg + structure which lacks GBR. */ + + case bfd_arch_sh: + switch (note->type) + { + case NT_NETBSDCORE_FIRSTMACH+3: + return elfcore_make_note_pseudosection (abfd, ".reg", note); + + case NT_NETBSDCORE_FIRSTMACH+5: + return elfcore_make_note_pseudosection (abfd, ".reg2", note); + + default: + return TRUE; + } + /* On all other arch's, PT_GETREGS == mach+1 and PT_GETFPREGS == mach+3. */ diff -rNU3 dist.orig/bfd/elf32-arm.c dist/bfd/elf32-arm.c --- dist.orig/bfd/elf32-arm.c 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/elf32-arm.c 2015-10-18 13:11:12.000000000 +0200 @@ -13475,6 +13475,10 @@ { struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation to `%s' in readonly section `%s'"), + h->root.root.string, s->name); info->flags |= DF_TEXTREL; /* Not an error, just cut short the traversal. */ @@ -15640,7 +15644,7 @@ #ifdef __QNXTARGET__ #define ELF_MAXPAGESIZE 0x1000 #else -#define ELF_MAXPAGESIZE 0x8000 +#define ELF_MAXPAGESIZE 0x10000 #endif #define ELF_MINPAGESIZE 0x1000 #define ELF_COMMONPAGESIZE 0x1000 @@ -15769,9 +15773,6 @@ #undef elf_backend_modify_program_headers #define elf_backend_modify_program_headers nacl_modify_program_headers -#undef ELF_MAXPAGESIZE -#define ELF_MAXPAGESIZE 0x10000 - #include "elf32-target.h" /* Reset to defaults. */ diff -rNU3 dist.orig/bfd/elf32-hppa.c dist/bfd/elf32-hppa.c --- dist.orig/bfd/elf32-hppa.c 2012-06-29 16:45:58.000000000 +0200 +++ dist/bfd/elf32-hppa.c 2015-10-18 13:11:12.000000000 +0200 @@ -2191,6 +2191,10 @@ { struct bfd_link_info *info = inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + eh->root.root.string); info->flags |= DF_TEXTREL; /* Not an error, just cut short the traversal. */ diff -rNU3 dist.orig/bfd/elf32-i386.c dist/bfd/elf32-i386.c --- dist.orig/bfd/elf32-i386.c 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/elf32-i386.c 2015-10-18 13:11:12.000000000 +0200 @@ -518,7 +518,7 @@ /* The name of the dynamic interpreter. This is put in the .interp section. */ -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" +#define ELF_DYNAMIC_INTERPRETER "/libexec/ld.elf_so" /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid copying dynamic variables from a shared lib into an app's dynbss @@ -2552,7 +2552,10 @@ if (s != NULL && (s->flags & SEC_READONLY) != 0) { struct bfd_link_info *info = (struct bfd_link_info *) inf; - + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + h->root.root.string); info->flags |= DF_TEXTREL; if (info->warn_shared_textrel && info->shared) diff -rNU3 dist.orig/bfd/elf32-m68k.c dist/bfd/elf32-m68k.c --- dist.orig/bfd/elf32-m68k.c 2012-07-13 16:22:47.000000000 +0200 +++ dist/bfd/elf32-m68k.c 2015-10-18 13:11:12.000000000 +0200 @@ -2532,7 +2532,7 @@ if (ind->got_entry_key != 0) { BFD_ASSERT (dir->got_entry_key == 0); - /* Assert that GOTs aren't partioned yet. */ + /* Assert that GOTs aren't partitioned yet. */ BFD_ASSERT (ind->glist == NULL); dir->got_entry_key = ind->got_entry_key; @@ -3104,6 +3104,7 @@ /* Make sure we know what is going on here. */ BFD_ASSERT (dynobj != NULL && (h->needs_plt + || h->type == STT_GNU_IFUNC || h->u.weakdef != NULL || (h->def_dynamic && h->ref_regular @@ -3112,7 +3113,7 @@ /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if ((h->type == STT_FUNC || h->type == STT_GNU_IFUNC) || h->needs_plt) { if ((h->plt.refcount <= 0 diff -rNU3 dist.orig/bfd/elf32-openrisc.c dist/bfd/elf32-openrisc.c --- dist.orig/bfd/elf32-openrisc.c 2012-05-07 05:27:50.000000000 +0200 +++ dist/bfd/elf32-openrisc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,566 +0,0 @@ -/* OpenRISC-specific support for 32-bit ELF. - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2012 - Free Software Foundation, Inc. - Contributed by Johan Rydberg, jrydberg@opencores.org - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/openrisc.h" -#include "libiberty.h" - -static reloc_howto_type openrisc_elf_howto_table[] = -{ - /* This reloc does nothing. */ - HOWTO (R_OPENRISC_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A PC relative 26 bit relocation, right shifted by 2. */ - HOWTO (R_OPENRISC_INSN_REL_26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_INSN_REL_26", /* name */ - FALSE, /* partial_inplace */ - 0x00000000, /* src_mask */ - 0x03ffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A absolute 26 bit relocation, right shifted by 2. */ - HOWTO (R_OPENRISC_INSN_ABS_26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_INSN_ABS_26", /* name */ - FALSE, /* partial_inplace */ - 0x00000000, /* src_mask */ - 0x03ffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - HOWTO (R_OPENRISC_LO_16_IN_INSN, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_LO_16_IN_INSN", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - HOWTO (R_OPENRISC_HI_16_IN_INSN, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_HI_16_IN_INSN", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* An 8 bit absolute relocation. */ - HOWTO (R_OPENRISC_8, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_8", /* name */ - TRUE, /* partial_inplace */ - 0x0000, /* src_mask */ - 0x00ff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A 16 bit absolute relocation. */ - HOWTO (R_OPENRISC_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_16", /* name */ - TRUE, /* partial_inplace */ - 0x00000000, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A 32 bit absolute relocation. */ - HOWTO (R_OPENRISC_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OPENRISC_32", /* name */ - TRUE, /* partial_inplace */ - 0x00000000, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy. */ - HOWTO (R_OPENRISC_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_OPENRISC_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage. */ - HOWTO (R_OPENRISC_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_OPENRISC_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ -}; - -/* Map BFD reloc types to OpenRISC ELF reloc types. */ - -struct openrisc_reloc_map -{ - bfd_reloc_code_real_type bfd_reloc_val; - unsigned int openrisc_reloc_val; -}; - -static const struct openrisc_reloc_map openrisc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_OPENRISC_NONE }, - { BFD_RELOC_32, R_OPENRISC_32 }, - { BFD_RELOC_16, R_OPENRISC_16 }, - { BFD_RELOC_8, R_OPENRISC_8 }, - { BFD_RELOC_OPENRISC_REL_26, R_OPENRISC_INSN_REL_26 }, - { BFD_RELOC_OPENRISC_ABS_26, R_OPENRISC_INSN_ABS_26 }, - { BFD_RELOC_HI16, R_OPENRISC_HI_16_IN_INSN }, - { BFD_RELOC_LO16, R_OPENRISC_LO_16_IN_INSN }, - { BFD_RELOC_VTABLE_INHERIT, R_OPENRISC_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_OPENRISC_GNU_VTENTRY } -}; - -static reloc_howto_type * -openrisc_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, - bfd_reloc_code_real_type code) -{ - unsigned int i; - - for (i = ARRAY_SIZE (openrisc_reloc_map); --i;) - if (openrisc_reloc_map[i].bfd_reloc_val == code) - return & openrisc_elf_howto_table[openrisc_reloc_map[i]. - openrisc_reloc_val]; - - return NULL; -} - -static reloc_howto_type * -openrisc_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, - const char *r_name) -{ - unsigned int i; - - for (i = 0; - i < (sizeof (openrisc_elf_howto_table) - / sizeof (openrisc_elf_howto_table[0])); - i++) - if (openrisc_elf_howto_table[i].name != NULL - && strcasecmp (openrisc_elf_howto_table[i].name, r_name) == 0) - return &openrisc_elf_howto_table[i]; - - return NULL; -} - -/* Set the howto pointer for an OpenRISC ELF reloc. */ - -static void -openrisc_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, - arelent * cache_ptr, - Elf_Internal_Rela * dst) -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_OPENRISC_max); - cache_ptr->howto = & openrisc_elf_howto_table[r_type]; -} - -/* Perform a single relocation. By default we use the standard BFD - routines, but a few relocs, we have to do them ourselves. */ - -static bfd_reloc_status_type -openrisc_final_link_relocate (reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - Elf_Internal_Rela *rel, - bfd_vma relocation) -{ - bfd_reloc_status_type r = bfd_reloc_ok; - - switch (howto->type) - { - case R_OPENRISC_LO_16_IN_INSN: - relocation &= 0xffff; - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - break; - - default: - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - } - - return r; -} - -/* Relocate an OpenRISC ELF section. - - The RELOCATE_SECTION function is called by the new ELF backend linker - to handle the relocations for a section. - - The relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. - - This function is responsible for adjusting the section contents as - necessary, and (if using Rela relocs and generating a relocatable - output file) adjusting the reloc addend as necessary. - - This function does not have to worry about setting the reloc - address or the reloc symbol index. - - LOCAL_SYMS is a pointer to the swapped in local symbols. - - LOCAL_SECTIONS is an array giving the section in the input file - corresponding to the st_shndx field of each local symbol. - - The global hash table entry for the global symbols can be found - via elf_sym_hashes (input_bfd). - - When generating relocatable output, this function must handle - STB_LOCAL/STT_SECTION symbols specially. The output symbol is - going to be the section symbol corresponding to the output - section, which means that the addend must be adjusted - accordingly. */ - -static bfd_boolean -openrisc_elf_relocate_section (bfd *output_bfd, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, - asection **local_sections) -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - relend = relocs + input_section->reloc_count; - - for (rel = relocs; rel < relend; rel++) - { - reloc_howto_type *howto; - unsigned long r_symndx; - Elf_Internal_Sym *sym; - asection *sec; - struct elf_link_hash_entry *h; - bfd_vma relocation; - bfd_reloc_status_type r; - const char *name = NULL; - int r_type; - - r_type = ELF32_R_TYPE (rel->r_info); - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_type == R_OPENRISC_GNU_VTINHERIT - || r_type == R_OPENRISC_GNU_VTENTRY) - continue; - - if ((unsigned int) r_type > - (sizeof openrisc_elf_howto_table / sizeof (reloc_howto_type))) - abort (); - - howto = openrisc_elf_howto_table + ELF32_R_TYPE (rel->r_info); - h = NULL; - sym = NULL; - sec = NULL; - - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); - - name = bfd_elf_string_from_elf_section - (input_bfd, symtab_hdr->sh_link, sym->st_name); - name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; - } - else - { - bfd_boolean unresolved_reloc, warned; - - RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, - r_symndx, symtab_hdr, sym_hashes, - h, sec, relocation, - unresolved_reloc, warned); - } - - if (sec != NULL && discarded_section (sec)) - RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, 1, relend, howto, 0, contents); - - if (info->relocatable) - continue; - - r = openrisc_final_link_relocate (howto, input_bfd, input_section, - contents, rel, relocation); - - if (r != bfd_reloc_ok) - { - const char *msg = NULL; - - switch (r) - { - case bfd_reloc_overflow: - r = info->callbacks->reloc_overflow - (info, (h ? &h->root : NULL), name, howto->name, - (bfd_vma) 0, input_bfd, input_section, rel->r_offset); - break; - - case bfd_reloc_undefined: - r = info->callbacks->undefined_symbol - (info, name, input_bfd, input_section, rel->r_offset, TRUE); - break; - - case bfd_reloc_outofrange: - msg = _("internal error: out of range error"); - break; - - case bfd_reloc_notsupported: - msg = _("internal error: unsupported relocation error"); - break; - - case bfd_reloc_dangerous: - msg = _("internal error: dangerous relocation"); - break; - - default: - msg = _("internal error: unknown error"); - break; - } - - if (msg) - r = info->callbacks->warning - (info, msg, name, input_bfd, input_section, rel->r_offset); - - if (!r) - return FALSE; - } - } - - return TRUE; -} - -/* Return the section that should be marked against GC for a given - relocation. */ - -static asection * -openrisc_elf_gc_mark_hook (asection *sec, - struct bfd_link_info *info, - Elf_Internal_Rela *rel, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - if (h != NULL) - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_OPENRISC_GNU_VTINHERIT: - case R_OPENRISC_GNU_VTENTRY: - return NULL; - } - - return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); -} - -/* Look through the relocs for a section during the first phase. - Since we don't do .gots or .plts, we just need to consider the - virtual table relocs for gc. */ - -static bfd_boolean -openrisc_elf_check_relocs (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - - if (info->relocatable) - return TRUE; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - struct elf_link_hash_entry *h; - unsigned long r_symndx; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - - switch (ELF32_R_TYPE (rel->r_info)) - { - /* This relocation describes the C++ object vtable hierarchy. - Reconstruct it for later use during GC. */ - case R_OPENRISC_GNU_VTINHERIT: - if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return FALSE; - break; - - /* This relocation describes which C++ vtable entries are actually - used. Record for later use during GC. */ - case R_OPENRISC_GNU_VTENTRY: - BFD_ASSERT (h != NULL); - if (h != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) - return FALSE; - break; - } - } - - return TRUE; -} - -/* Set the right machine number. */ - -static bfd_boolean -openrisc_elf_object_p (bfd *abfd) -{ - bfd_default_set_arch_mach (abfd, bfd_arch_openrisc, 0); - return TRUE; -} - -/* Store the machine number in the flags field. */ - -static void -openrisc_elf_final_write_processing (bfd *abfd, - bfd_boolean linker ATTRIBUTE_UNUSED) -{ - unsigned long val; - - switch (bfd_get_mach (abfd)) - { - default: - val = 0; - break; - } - - elf_elfheader (abfd)->e_flags &= ~0xf; - elf_elfheader (abfd)->e_flags |= val; -} - - -#define ELF_ARCH bfd_arch_openrisc -#define ELF_MACHINE_CODE EM_OPENRISC -#define ELF_MACHINE_ALT1 EM_OPENRISC_OLD -#define ELF_MAXPAGESIZE 0x1000 - -#define TARGET_BIG_SYM bfd_elf32_openrisc_vec -#define TARGET_BIG_NAME "elf32-openrisc" - -#define elf_info_to_howto_rel NULL -#define elf_info_to_howto openrisc_info_to_howto_rela -#define elf_backend_relocate_section openrisc_elf_relocate_section -#define elf_backend_gc_mark_hook openrisc_elf_gc_mark_hook -#define elf_backend_check_relocs openrisc_elf_check_relocs - -#define elf_backend_can_gc_sections 1 -#define elf_backend_rela_normal 1 - -#define bfd_elf32_bfd_reloc_type_lookup openrisc_reloc_type_lookup -#define bfd_elf32_bfd_reloc_name_lookup openrisc_reloc_name_lookup - -#define elf_backend_object_p openrisc_elf_object_p -#define elf_backend_final_write_processing openrisc_elf_final_write_processing - -#include "elf32-target.h" diff -rNU3 dist.orig/bfd/elf32-or1k.c dist/bfd/elf32-or1k.c --- dist.orig/bfd/elf32-or1k.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/elf32-or1k.c 2015-10-18 13:11:12.000000000 +0200 @@ -0,0 +1,2852 @@ +/* Or1k-specific support for 32-bit ELF. + Copyright 2001-2014 Free Software Foundation, Inc. + Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org + + PIC parts added by Stefan Kristiansson, stefan.kristiansson@saunalahti.fi, + largely based on elf32-m32r.c and elf32-microblaze.c. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elf/or1k.h" +#include "libiberty.h" + +#define PLT_ENTRY_SIZE 20 + +#define PLT0_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(.got+4) */ +#define PLT0_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(.got+4) */ +#define PLT0_ENTRY_WORD2 0x85ec0004 /* l.lwz r15, 4(r12) <- *(.got+8)*/ +#define PLT0_ENTRY_WORD3 0x44007800 /* l.jr r15 */ +#define PLT0_ENTRY_WORD4 0x858c0000 /* l.lwz r12, 0(r12) */ + +#define PLT0_PIC_ENTRY_WORD0 0x85900004 /* l.lwz r12, 4(r16) */ +#define PLT0_PIC_ENTRY_WORD1 0x85f00008 /* l.lwz r15, 8(r16) */ +#define PLT0_PIC_ENTRY_WORD2 0x44007800 /* l.jr r15 */ +#define PLT0_PIC_ENTRY_WORD3 0x15000000 /* l.nop */ +#define PLT0_PIC_ENTRY_WORD4 0x15000000 /* l.nop */ + +#define PLT_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(got idx addr) */ +#define PLT_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(got idx addr) */ +#define PLT_ENTRY_WORD2 0x858c0000 /* l.lwz r12, 0(r12) */ +#define PLT_ENTRY_WORD3 0x44006000 /* l.jr r12 */ +#define PLT_ENTRY_WORD4 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */ + +#define PLT_PIC_ENTRY_WORD0 0x85900000 /* l.lwz r12, 0(r16) <- index in got */ +#define PLT_PIC_ENTRY_WORD1 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */ +#define PLT_PIC_ENTRY_WORD2 0x44006000 /* l.jr r12 */ +#define PLT_PIC_ENTRY_WORD3 0x15000000 /* l.nop */ +#define PLT_PIC_ENTRY_WORD4 0x15000000 /* l.nop */ + +#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" + +static reloc_howto_type or1k_elf_howto_table[] = +{ + /* This reloc does nothing. */ + HOWTO (R_OR1K_NONE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_NONE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_32, + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_32", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_16, + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_16", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_8, + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_8", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_LO_16_IN_INSN, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_LO_16_IN_INSN", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_HI_16_IN_INSN, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_HI_16_IN_INSN", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A PC relative 26 bit relocation, right shifted by 2. */ + HOWTO (R_OR1K_INSN_REL_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_INSN_REL_26", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x03ffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable hierarchy. */ + HOWTO (R_OR1K_GNU_VTINHERIT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + NULL, /* special_function */ + "R_OR1K_GNU_VTINHERIT", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable member usage. */ + HOWTO (R_OR1K_GNU_VTENTRY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_elf_rel_vtable_reloc_fn, /* special_function */ + "R_OR1K_GNU_VTENTRY", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_32_PCREL, + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_32_PCREL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_16_PCREL, + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_16_PCREL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_8_PCREL, + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_8_PCREL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_GOTPC_HI16, /* Type. */ + 16, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain on overflow. */ + bfd_elf_generic_reloc, /* Special Function. */ + "R_OR1K_GOTPC_HI16", /* Name. */ + FALSE, /* Partial Inplace. */ + 0, /* Source Mask. */ + 0xffff, /* Dest Mask. */ + TRUE), /* PC relative offset? */ + + HOWTO (R_OR1K_GOTPC_LO16, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain on overflow. */ + bfd_elf_generic_reloc, /* Special Function. */ + "R_OR1K_GOTPC_LO16", /* Name. */ + FALSE, /* Partial Inplace. */ + 0, /* Source Mask. */ + 0xffff, /* Dest Mask. */ + TRUE), /* PC relative offset? */ + + HOWTO (R_OR1K_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_GOT16", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A 26 bit PLT relocation. Shifted by 2. */ + HOWTO (R_OR1K_PLT26, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 26, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain on overflow. */ + bfd_elf_generic_reloc,/* Special Function. */ + "R_OR1K_PLT26", /* Name. */ + FALSE, /* Partial Inplace. */ + 0, /* Source Mask. */ + 0x03ffffff, /* Dest Mask. */ + TRUE), /* PC relative offset? */ + + HOWTO (R_OR1K_GOTOFF_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_GOTOFF_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_GOTOFF_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_GOTOFF_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_COPY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_COPY", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_JMP_SLOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_JMP_SLOT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_RELATIVE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_RELATIVE", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_GD_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_GD_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_GD_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_GD_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LDM_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LDM_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LDM_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LDM_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LDO_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LDO_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LDO_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LDO_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_IE_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_IE_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_IE_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_IE_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LE_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LE_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_OR1K_TLS_LE_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR1K_TLS_LE_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + +}; + +/* Map BFD reloc types to Or1k ELF reloc types. */ + +struct or1k_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned int or1k_reloc_val; +}; + +static const struct or1k_reloc_map or1k_reloc_map[] = +{ + { BFD_RELOC_NONE, R_OR1K_NONE }, + { BFD_RELOC_32, R_OR1K_32 }, + { BFD_RELOC_16, R_OR1K_16 }, + { BFD_RELOC_8, R_OR1K_8 }, + { BFD_RELOC_LO16, R_OR1K_LO_16_IN_INSN }, + { BFD_RELOC_HI16, R_OR1K_HI_16_IN_INSN }, + { BFD_RELOC_OR1K_REL_26, R_OR1K_INSN_REL_26 }, + { BFD_RELOC_VTABLE_ENTRY, R_OR1K_GNU_VTENTRY }, + { BFD_RELOC_VTABLE_INHERIT, R_OR1K_GNU_VTINHERIT }, + { BFD_RELOC_32_PCREL, R_OR1K_32_PCREL }, + { BFD_RELOC_16_PCREL, R_OR1K_16_PCREL }, + { BFD_RELOC_8_PCREL, R_OR1K_8_PCREL }, + { BFD_RELOC_OR1K_GOTPC_HI16, R_OR1K_GOTPC_HI16 }, + { BFD_RELOC_OR1K_GOTPC_LO16, R_OR1K_GOTPC_LO16 }, + { BFD_RELOC_OR1K_GOT16, R_OR1K_GOT16 }, + { BFD_RELOC_OR1K_PLT26, R_OR1K_PLT26 }, + { BFD_RELOC_OR1K_GOTOFF_HI16, R_OR1K_GOTOFF_HI16 }, + { BFD_RELOC_OR1K_GOTOFF_LO16, R_OR1K_GOTOFF_LO16 }, + { BFD_RELOC_OR1K_GLOB_DAT, R_OR1K_GLOB_DAT }, + { BFD_RELOC_OR1K_COPY, R_OR1K_COPY }, + { BFD_RELOC_OR1K_JMP_SLOT, R_OR1K_JMP_SLOT }, + { BFD_RELOC_OR1K_RELATIVE, R_OR1K_RELATIVE }, + { BFD_RELOC_OR1K_TLS_GD_HI16, R_OR1K_TLS_GD_HI16 }, + { BFD_RELOC_OR1K_TLS_GD_LO16, R_OR1K_TLS_GD_LO16 }, + { BFD_RELOC_OR1K_TLS_LDM_HI16, R_OR1K_TLS_LDM_HI16 }, + { BFD_RELOC_OR1K_TLS_LDM_LO16, R_OR1K_TLS_LDM_LO16 }, + { BFD_RELOC_OR1K_TLS_LDO_HI16, R_OR1K_TLS_LDO_HI16 }, + { BFD_RELOC_OR1K_TLS_LDO_LO16, R_OR1K_TLS_LDO_LO16 }, + { BFD_RELOC_OR1K_TLS_IE_HI16, R_OR1K_TLS_IE_HI16 }, + { BFD_RELOC_OR1K_TLS_IE_LO16, R_OR1K_TLS_IE_LO16 }, + { BFD_RELOC_OR1K_TLS_LE_HI16, R_OR1K_TLS_LE_HI16 }, + { BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 }, +}; + +/* The linker needs to keep track of the number of relocs that it + decides to copy as dynamic relocs in check_relocs for each symbol. + This is so that it can later discard them if they are found to be + unnecessary. We store the information in a field extending the + regular ELF linker hash table. */ + +struct elf_or1k_dyn_relocs +{ + struct elf_or1k_dyn_relocs *next; + + /* The input section of the reloc. */ + asection *sec; + + /* Total number of relocs copied for the input section. */ + bfd_size_type count; + + /* Number of pc-relative relocs copied for the input section. */ + bfd_size_type pc_count; +}; + +#define TLS_UNKNOWN 0 +#define TLS_NONE 1 +#define TLS_GD 2 +#define TLS_LD 3 +#define TLS_IE 4 +#define TLS_LE 5 + +/* ELF linker hash entry. */ +struct elf_or1k_link_hash_entry +{ + struct elf_link_hash_entry root; + + /* Track dynamic relocs copied for this symbol. */ + struct elf_or1k_dyn_relocs *dyn_relocs; + + /* Track type of TLS access. */ + unsigned char tls_type; +}; + +/* ELF object data. */ +struct elf_or1k_obj_tdata +{ + struct elf_obj_tdata root; + + /* tls_type for each local got entry. */ + unsigned char *local_tls_type; +}; + +#define elf_or1k_tdata(abfd) \ + ((struct elf_or1k_obj_tdata *) (abfd)->tdata.any) + +#define elf_or1k_local_tls_type(abfd) \ + (elf_or1k_tdata (abfd)->local_tls_type) + +/* ELF linker hash table. */ +struct elf_or1k_link_hash_table +{ + struct elf_link_hash_table root; + + /* Short-cuts to get to dynamic linker sections. */ + asection *sgot; + asection *sgotplt; + asection *srelgot; + asection *splt; + asection *srelplt; + asection *sdynbss; + asection *srelbss; + + /* Small local sym to section mapping cache. */ + struct sym_cache sym_sec; +}; + +/* Get the ELF linker hash table from a link_info structure. */ +#define or1k_elf_hash_table(p) \ + (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ + == OR1K_ELF_DATA ? ((struct elf_or1k_link_hash_table *) ((p)->hash)) : NULL) + +static bfd_boolean +elf_or1k_mkobject (bfd *abfd) +{ + return bfd_elf_allocate_object (abfd, sizeof (struct elf_or1k_obj_tdata), + OR1K_ELF_DATA); +} + +/* Create an entry in an or1k ELF linker hash table. */ + +static struct bfd_hash_entry * +or1k_elf_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) +{ + struct elf_or1k_link_hash_entry *ret = + (struct elf_or1k_link_hash_entry *) entry; + + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (ret == NULL) + ret = bfd_hash_allocate (table, + sizeof (struct elf_or1k_link_hash_entry)); + if (ret == NULL) + return NULL; + + /* Call the allocation method of the superclass. */ + ret = ((struct elf_or1k_link_hash_entry *) + _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, + table, string)); + if (ret != NULL) + { + struct elf_or1k_link_hash_entry *eh; + + eh = (struct elf_or1k_link_hash_entry *) ret; + eh->dyn_relocs = NULL; + eh->tls_type = TLS_UNKNOWN; + } + + return (struct bfd_hash_entry *) ret; +} + +/* Create an or1k ELF linker hash table. */ + +static struct bfd_link_hash_table * +or1k_elf_link_hash_table_create (bfd *abfd) +{ + struct elf_or1k_link_hash_table *ret; + bfd_size_type amt = sizeof (struct elf_or1k_link_hash_table); + + ret = bfd_zmalloc (amt); + if (ret == NULL) + return NULL; + + if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, + or1k_elf_link_hash_newfunc, + sizeof (struct elf_or1k_link_hash_entry), + OR1K_ELF_DATA)) + { + free (ret); + return NULL; + } + + return &ret->root.root; +} + +static reloc_howto_type * +or1k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = ARRAY_SIZE (or1k_reloc_map); --i;) + if (or1k_reloc_map[i].bfd_reloc_val == code) + return & or1k_elf_howto_table[or1k_reloc_map[i].or1k_reloc_val]; + + return NULL; +} + +static reloc_howto_type * +or1k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < (sizeof (or1k_elf_howto_table) + / sizeof (or1k_elf_howto_table[0])); + i++) + if (or1k_elf_howto_table[i].name != NULL + && strcasecmp (or1k_elf_howto_table[i].name, r_name) == 0) + return &or1k_elf_howto_table[i]; + + return NULL; +} + +/* Set the howto pointer for an Or1k ELF reloc. */ + +static void +or1k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela * dst) +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + BFD_ASSERT (r_type < (unsigned int) R_OR1K_max); + cache_ptr->howto = & or1k_elf_howto_table[r_type]; +} + + +/* Return the relocation value for @tpoff relocations.. */ +static bfd_vma +tpoff (struct bfd_link_info *info, bfd_vma address) +{ + /* If tls_sec is NULL, we should have signalled an error already. */ + if (elf_hash_table (info)->tls_sec == NULL) + return 0; + + /* The thread pointer on or1k stores the address after the TCB where + the data is, just compute the difference. No need to compensate + for the size of TCB. */ + return (address - elf_hash_table (info)->tls_sec->vma); +} + +/* Relocate an Or1k ELF section. + + The RELOCATE_SECTION function is called by the new ELF backend linker + to handle the relocations for a section. + + The relocs are always passed as Rela structures; if the section + actually uses Rel structures, the r_addend field will always be + zero. + + This function is responsible for adjusting the section contents as + necessary, and (if using Rela relocs and generating a relocatable + output file) adjusting the reloc addend as necessary. + + This function does not have to worry about setting the reloc + address or the reloc symbol index. + + LOCAL_SYMS is a pointer to the swapped in local symbols. + + LOCAL_SECTIONS is an array giving the section in the input file + corresponding to the st_shndx field of each local symbol. + + The global hash table entry for the global symbols can be found + via elf_sym_hashes (input_bfd). + + When generating relocatable output, this function must handle + STB_LOCAL/STT_SECTION symbols specially. The output symbol is + going to be the section symbol corresponding to the output + section, which means that the addend must be adjusted + accordingly. */ + +static bfd_boolean +or1k_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + Elf_Internal_Rela *rel; + Elf_Internal_Rela *relend; + struct elf_or1k_link_hash_table *htab = or1k_elf_hash_table (info); + bfd *dynobj; + asection *sreloc; + bfd_vma *local_got_offsets; + asection *sgot; + + if (htab == NULL) + return FALSE; + + dynobj = htab->root.dynobj; + local_got_offsets = elf_local_got_offsets (input_bfd); + + sreloc = elf_section_data (input_section)->sreloc; + + sgot = htab->sgot; + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + relend = relocs + input_section->reloc_count; + + for (rel = relocs; rel < relend; rel++) + { + reloc_howto_type *howto; + unsigned long r_symndx; + Elf_Internal_Sym *sym; + asection *sec; + struct elf_link_hash_entry *h; + bfd_vma relocation; + bfd_reloc_status_type r; + const char *name = NULL; + int r_type; + + r_type = ELF32_R_TYPE (rel->r_info); + r_symndx = ELF32_R_SYM (rel->r_info); + + if (r_type == R_OR1K_GNU_VTINHERIT + || r_type == R_OR1K_GNU_VTENTRY) + continue; + + if (r_type < 0 || r_type >= (int) R_OR1K_max) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + howto = or1k_elf_howto_table + ELF32_R_TYPE (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + + name = bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, sym->st_name); + name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; + } + else + { + bfd_boolean unresolved_reloc, warned; + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, warned); + } + + if (sec != NULL && discarded_section (sec)) + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, 1, relend, howto, 0, contents); + + if (info->relocatable) + continue; + + switch (howto->type) + { + case R_OR1K_PLT26: + { + if (htab->splt != NULL && h != NULL + && h->plt.offset != (bfd_vma) -1) + { + relocation = (htab->splt->output_section->vma + + htab->splt->output_offset + + h->plt.offset); + } + break; + } + + case R_OR1K_GOT16: + /* Relocation is to the entry for this symbol in the global + offset table. */ + BFD_ASSERT (sgot != NULL); + if (h != NULL) + { + bfd_boolean dyn; + bfd_vma off; + + off = h->got.offset; + BFD_ASSERT (off != (bfd_vma) -1); + + dyn = htab->root.dynamic_sections_created; + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) + || (info->shared + && SYMBOL_REFERENCES_LOCAL (info, h))) + { + /* This is actually a static link, or it is a + -Bsymbolic link and the symbol is defined + locally, or the symbol was forced to be local + because of a version file. We must initialize + this entry in the global offset table. Since the + offset must always be a multiple of 4, we use the + least significant bit to record whether we have + initialized it already. + + When doing a dynamic link, we create a .rela.got + relocation entry to initialize the value. This + is done in the finish_dynamic_symbol routine. */ + if ((off & 1) != 0) + off &= ~1; + else + { + /* Write entry in GOT. */ + bfd_put_32 (output_bfd, relocation, + sgot->contents + off); + /* Mark GOT entry as having been written. */ + h->got.offset |= 1; + } + } + + relocation = sgot->output_offset + off; + } + else + { + bfd_vma off; + bfd_byte *loc; + + BFD_ASSERT (local_got_offsets != NULL + && local_got_offsets[r_symndx] != (bfd_vma) -1); + + /* Get offset into GOT table. */ + off = local_got_offsets[r_symndx]; + + /* The offset must always be a multiple of 4. We use + the least significant bit to record whether we have + already processed this entry. */ + if ((off & 1) != 0) + off &= ~1; + else + { + /* Write entry in GOT. */ + bfd_put_32 (output_bfd, relocation, sgot->contents + off); + if (info->shared) + { + asection *srelgot; + Elf_Internal_Rela outrel; + + /* We need to generate a R_OR1K_RELATIVE reloc + for the dynamic linker. */ + srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); + BFD_ASSERT (srelgot != NULL); + + outrel.r_offset = (sgot->output_section->vma + + sgot->output_offset + + off); + outrel.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE); + outrel.r_addend = relocation; + loc = srelgot->contents; + loc += srelgot->reloc_count * sizeof (Elf32_External_Rela); + bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc); + ++srelgot->reloc_count; + } + + local_got_offsets[r_symndx] |= 1; + } + relocation = sgot->output_offset + off; + } + + /* Addend should be zero. */ + if (rel->r_addend != 0) + (*_bfd_error_handler) + (_("internal error: addend should be zero for R_OR1K_GOT16")); + + break; + + case R_OR1K_GOTOFF_LO16: + case R_OR1K_GOTOFF_HI16: + /* Relocation is offset from GOT. */ + BFD_ASSERT (sgot != NULL); + relocation -= sgot->output_section->vma; + break; + + case R_OR1K_INSN_REL_26: + case R_OR1K_HI_16_IN_INSN: + case R_OR1K_LO_16_IN_INSN: + case R_OR1K_32: + /* R_OR1K_16? */ + { + /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == STN_UNDEF + || (input_section->flags & SEC_ALLOC) == 0) + break; + + if ((info->shared + && (h == NULL + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) + && (howto->type != R_OR1K_INSN_REL_26 + || !SYMBOL_CALLS_LOCAL (info, h))) + || (!info->shared + && h != NULL + && h->dynindx != -1 + && !h->non_got_ref + && ((h->def_dynamic + && !h->def_regular) + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined))) + { + Elf_Internal_Rela outrel; + bfd_byte *loc; + bfd_boolean skip; + + /* When generating a shared object, these relocations + are copied into the output file to be resolved at run + time. */ + + BFD_ASSERT (sreloc != NULL); + + skip = FALSE; + + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1) + skip = TRUE; + else if (outrel.r_offset == (bfd_vma) -2) + skip = TRUE; + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + + if (skip) + memset (&outrel, 0, sizeof outrel); + /* h->dynindx may be -1 if the symbol was marked to + become local. */ + else if (h != NULL + && ((! info->symbolic && h->dynindx != -1) + || !h->def_regular)) + { + BFD_ASSERT (h->dynindx != -1); + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); + outrel.r_addend = rel->r_addend; + } + else + { + if (r_type == R_OR1K_32) + { + outrel.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; + } + else + { + BFD_FAIL (); + (*_bfd_error_handler) + (_("%B: probably compiled without -fPIC?"), + input_bfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + } + + loc = sreloc->contents; + loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); + bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); + break; + } + break; + } + + case R_OR1K_TLS_LDM_HI16: + case R_OR1K_TLS_LDM_LO16: + case R_OR1K_TLS_LDO_HI16: + case R_OR1K_TLS_LDO_LO16: + /* TODO: implement support for local dynamic. */ + BFD_FAIL (); + (*_bfd_error_handler) + (_("%B: support for local dynamic not implemented"), + input_bfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + + + case R_OR1K_TLS_GD_HI16: + case R_OR1K_TLS_GD_LO16: + case R_OR1K_TLS_IE_HI16: + case R_OR1K_TLS_IE_LO16: + { + bfd_vma gotoff; + Elf_Internal_Rela rela; + bfd_byte *loc; + int dynamic; + + sreloc = bfd_get_section_by_name (dynobj, ".rela.got"); + + /* Mark as TLS related GOT entry by setting + bit 2 as well as bit 1. */ + if (h != NULL) + { + gotoff = h->got.offset; + h->got.offset |= 3; + } + else + { + gotoff = local_got_offsets[r_symndx]; + local_got_offsets[r_symndx] |= 3; + } + + /* Only process the relocation once. */ + if (gotoff & 1) + { + relocation = sgot->output_offset + (gotoff & ~3); + break; + } + + BFD_ASSERT (elf_hash_table (info)->hgot == NULL + || elf_hash_table (info)->hgot->root.u.def.value == 0); + + /* Dynamic entries will require relocations. if we do not need + them we will just use the default R_OR1K_NONE and + not set anything. */ + dynamic = info->shared + || (sec && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak || !h->def_regular)); + + /* Shared GD. */ + if (dynamic && (howto->type == R_OR1K_TLS_GD_HI16 + || howto->type == R_OR1K_TLS_GD_LO16)) + { + int i; + + /* Add DTPMOD and DTPOFF GOT and rela entries. */ + for (i = 0; i < 2; ++i) + { + rela.r_offset = sgot->output_section->vma + + sgot->output_offset + gotoff + i*4; + if (h != NULL && h->dynindx != -1) + { + rela.r_info = ELF32_R_INFO (h->dynindx, + (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF)); + rela.r_addend = 0; + } + else + { + rela.r_info = ELF32_R_INFO (0, + (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF)); + rela.r_addend = tpoff (info, relocation); + } + + loc = sreloc->contents; + loc += sreloc->reloc_count++ * + sizeof (Elf32_External_Rela); + + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + bfd_put_32 (output_bfd, 0, sgot->contents + gotoff + i*4); + } + } + /* Static GD. */ + else if (howto->type == R_OR1K_TLS_GD_HI16 + || howto->type == R_OR1K_TLS_GD_LO16) + { + bfd_put_32 (output_bfd, 1, sgot->contents + gotoff); + bfd_put_32 (output_bfd, tpoff (info, relocation), + sgot->contents + gotoff + 4); + } + /* Shared IE. */ + else if (dynamic) + { + /* Add TPOFF GOT and rela entries. */ + rela.r_offset = sgot->output_section->vma + + sgot->output_offset + gotoff; + if (h != NULL && h->dynindx != -1) + { + rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_TLS_TPOFF); + rela.r_addend = 0; + } + else + { + rela.r_info = ELF32_R_INFO (0, R_OR1K_TLS_TPOFF); + rela.r_addend = tpoff (info, relocation); + } + + loc = sreloc->contents; + loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); + + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + bfd_put_32 (output_bfd, 0, sgot->contents + gotoff); + } + /* Static IE. */ + else + { + bfd_put_32 (output_bfd, tpoff (info, relocation), + sgot->contents + gotoff); + } + relocation = sgot->output_offset + gotoff; + break; + } + case R_OR1K_TLS_LE_HI16: + case R_OR1K_TLS_LE_LO16: + + /* Relocation is offset from TP. */ + relocation = tpoff (info, relocation); + break; + + case R_OR1K_TLS_DTPMOD: + case R_OR1K_TLS_DTPOFF: + case R_OR1K_TLS_TPOFF: + /* These are resolved dynamically on load and shouldn't + be used as linker input. */ + BFD_FAIL (); + (*_bfd_error_handler) + (_("%B: will not resolve runtime TLS relocation"), + input_bfd); + bfd_set_error (bfd_error_bad_value); + return FALSE; + + default: + break; + } + r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, + rel->r_offset, relocation, rel->r_addend); + + if (r != bfd_reloc_ok) + { + const char *msg = NULL; + + switch (r) + { + case bfd_reloc_overflow: + r = info->callbacks->reloc_overflow + (info, (h ? &h->root : NULL), name, howto->name, + (bfd_vma) 0, input_bfd, input_section, rel->r_offset); + break; + + case bfd_reloc_undefined: + r = info->callbacks->undefined_symbol + (info, name, input_bfd, input_section, rel->r_offset, TRUE); + break; + + case bfd_reloc_outofrange: + msg = _("internal error: out of range error"); + break; + + case bfd_reloc_notsupported: + msg = _("internal error: unsupported relocation error"); + break; + + case bfd_reloc_dangerous: + msg = _("internal error: dangerous relocation"); + break; + + default: + msg = _("internal error: unknown error"); + break; + } + + if (msg) + r = info->callbacks->warning + (info, msg, name, input_bfd, input_section, rel->r_offset); + + if (!r) + return FALSE; + } + } + + return TRUE; +} + +/* Return the section that should be marked against GC for a given + relocation. */ + +static asection * +or1k_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + if (h != NULL) + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_OR1K_GNU_VTINHERIT: + case R_OR1K_GNU_VTENTRY: + return NULL; + } + + return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); +} + +static bfd_boolean +or1k_elf_gc_sweep_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) +{ + /* Update the got entry reference counts for the section being removed. */ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_signed_vma *local_got_refcounts; + const Elf_Internal_Rela *rel, *relend; + + elf_section_data (sec)->local_dynrel = NULL; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + local_got_refcounts = elf_local_got_refcounts (abfd); + + relend = relocs + sec->reloc_count; + for (rel = relocs; rel < relend; rel++) + { + unsigned long r_symndx; + struct elf_link_hash_entry *h = NULL; + + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + } + + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_OR1K_GOT16: + if (h != NULL) + { + if (h->got.refcount > 0) + h->got.refcount--; + } + else + { + if (local_got_refcounts && local_got_refcounts[r_symndx] > 0) + local_got_refcounts[r_symndx]--; + } + break; + + default: + break; + } + } + return TRUE; +} + +/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up + shortcuts to them in our hash table. */ + +static bfd_boolean +create_got_section (bfd *dynobj, struct bfd_link_info *info) +{ + struct elf_or1k_link_hash_table *htab; + asection *s; + + /* This function may be called more than once. */ + s = bfd_get_section_by_name (dynobj, ".got"); + if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0) + return TRUE; + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + if (! _bfd_elf_create_got_section (dynobj, info)) + return FALSE; + + htab->sgot = bfd_get_section_by_name (dynobj, ".got"); + htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); + htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); + + if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot) + abort (); + + if (! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED + | SEC_READONLY) + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) + return FALSE; + + return TRUE; +} + +/* Look through the relocs for a section during the first phase. */ + +static bfd_boolean +or1k_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel; + + const Elf_Internal_Rela *rel_end; + struct elf_or1k_link_hash_table *htab; + bfd *dynobj; + asection *sreloc = NULL; + + if (info->relocatable) + return TRUE; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + dynobj = htab->root.dynobj; + + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + struct elf_link_hash_entry *h; + unsigned long r_symndx; + unsigned char tls_type; + + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* PR15323, ref flags aren't set for references in the same + object. */ + h->root.non_ir_ref = 1; + } + + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_OR1K_TLS_GD_HI16: + case R_OR1K_TLS_GD_LO16: + tls_type = TLS_GD; + break; + case R_OR1K_TLS_LDM_HI16: + case R_OR1K_TLS_LDM_LO16: + case R_OR1K_TLS_LDO_HI16: + case R_OR1K_TLS_LDO_LO16: + tls_type = TLS_LD; + break; + case R_OR1K_TLS_IE_HI16: + case R_OR1K_TLS_IE_LO16: + tls_type = TLS_IE; + break; + case R_OR1K_TLS_LE_HI16: + case R_OR1K_TLS_LE_LO16: + tls_type = TLS_LE; + break; + default: + tls_type = TLS_NONE; + } + + /* Record TLS type. */ + if (h != NULL) + ((struct elf_or1k_link_hash_entry *) h)->tls_type = tls_type; + else + { + unsigned char *local_tls_type; + + /* This is a TLS type record for a local symbol. */ + local_tls_type = (unsigned char *) elf_or1k_local_tls_type (abfd); + if (local_tls_type == NULL) + { + bfd_size_type size; + + size = symtab_hdr->sh_info; + local_tls_type = bfd_zalloc (abfd, size); + if (local_tls_type == NULL) + return FALSE; + elf_or1k_local_tls_type (abfd) = local_tls_type; + } + local_tls_type[r_symndx] = tls_type; + } + + switch (ELF32_R_TYPE (rel->r_info)) + { + /* This relocation describes the C++ object vtable hierarchy. + Reconstruct it for later use during GC. */ + case R_OR1K_GNU_VTINHERIT: + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return FALSE; + break; + + /* This relocation describes which C++ vtable entries are actually + used. Record for later use during GC. */ + case R_OR1K_GNU_VTENTRY: + BFD_ASSERT (h != NULL); + if (h != NULL + && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return FALSE; + break; + + /* This relocation requires .plt entry. */ + case R_OR1K_PLT26: + if (h != NULL) + { + h->needs_plt = 1; + h->plt.refcount += 1; + } + break; + + case R_OR1K_GOT16: + case R_OR1K_GOTOFF_HI16: + case R_OR1K_GOTOFF_LO16: + case R_OR1K_TLS_GD_HI16: + case R_OR1K_TLS_GD_LO16: + case R_OR1K_TLS_IE_HI16: + case R_OR1K_TLS_IE_LO16: + if (htab->sgot == NULL) + { + if (dynobj == NULL) + htab->root.dynobj = dynobj = abfd; + if (! create_got_section (dynobj, info)) + return FALSE; + } + + if (ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_HI16 && + ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_LO16) + { + if (h != NULL) + h->got.refcount += 1; + else + { + bfd_signed_vma *local_got_refcounts; + + /* This is a global offset table entry for a local symbol. */ + local_got_refcounts = elf_local_got_refcounts (abfd); + if (local_got_refcounts == NULL) + { + bfd_size_type size; + + size = symtab_hdr->sh_info; + size *= sizeof (bfd_signed_vma); + local_got_refcounts = bfd_zalloc (abfd, size); + if (local_got_refcounts == NULL) + return FALSE; + elf_local_got_refcounts (abfd) = local_got_refcounts; + } + local_got_refcounts[r_symndx] += 1; + } + } + break; + + case R_OR1K_INSN_REL_26: + case R_OR1K_HI_16_IN_INSN: + case R_OR1K_LO_16_IN_INSN: + case R_OR1K_32: + /* R_OR1K_16? */ + { + if (h != NULL && !info->shared) + { + /* We may need a copy reloc. */ + h->non_got_ref = 1; + + /* We may also need a .plt entry. */ + h->plt.refcount += 1; + if (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26) + h->pointer_equality_needed = 1; + } + + /* If we are creating a shared library, and this is a reloc + against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc + into the shared library. However, if we are linking with + -Bsymbolic, we do not need to copy a reloc against a + global symbol which is defined in an object we are + including in the link (i.e., DEF_REGULAR is set). At + this point we have not seen all the input files, so it is + possible that DEF_REGULAR is not set now but will be set + later (it is never cleared). In case of a weak definition, + DEF_REGULAR may be cleared later by a strong definition in + a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash + table entry. A similar situation occurs when creating + shared libraries and symbol visibility changes render the + symbol local. + + If on the other hand, we are creating an executable, we + may need to keep relocations for symbols satisfied by a + dynamic library if we manage to avoid copy relocs for the + symbol. */ + + if ((info->shared + && (sec->flags & SEC_ALLOC) != 0 + && (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26 + || (h != NULL + && (!SYMBOLIC_BIND (info, h) + || h->root.type == bfd_link_hash_defweak + || !h->def_regular)))) + || (!info->shared + && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak + || !h->def_regular))) + { + struct elf_or1k_dyn_relocs *p; + struct elf_or1k_dyn_relocs **head; + + /* When creating a shared object, we must copy these + relocs into the output file. We create a reloc + section in dynobj and make room for the reloc. */ + if (sreloc == NULL) + { + const char *name; + unsigned int strndx = elf_elfheader (abfd)->e_shstrndx; + unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name; + + name = bfd_elf_string_from_elf_section (abfd, strndx, shnam); + if (name == NULL) + return FALSE; + + if (strncmp (name, ".rela", 5) != 0 + || strcmp (bfd_get_section_name (abfd, sec), + name + 5) != 0) + { + (*_bfd_error_handler) + (_("%B: bad relocation section name `%s\'"), + abfd, name); + } + + if (htab->root.dynobj == NULL) + htab->root.dynobj = abfd; + dynobj = htab->root.dynobj; + + sreloc = bfd_get_section_by_name (dynobj, name); + if (sreloc == NULL) + { + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); + + if (sreloc == NULL) + return FALSE; + } + elf_section_data (sec)->sreloc = sreloc; + } + + /* If this is a global symbol, we count the number of + relocations we need for this symbol. */ + if (h != NULL) + head = &((struct elf_or1k_link_hash_entry *) h)->dyn_relocs; + else + { + /* Track dynamic relocs needed for local syms too. + We really need local syms available to do this + easily. Oh well. */ + + asection *s; + Elf_Internal_Sym *isym; + void *vpp; + + isym = bfd_sym_from_r_symndx (&htab->sym_sec, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + return FALSE; + + vpp = &elf_section_data (s)->local_dynrel; + head = (struct elf_or1k_dyn_relocs **) vpp; + } + + p = *head; + if (p == NULL || p->sec != sec) + { + bfd_size_type amt = sizeof *p; + p = ((struct elf_or1k_dyn_relocs *) + bfd_alloc (htab->root.dynobj, amt)); + if (p == NULL) + return FALSE; + p->next = *head; + *head = p; + p->sec = sec; + p->count = 0; + p->pc_count = 0; + } + + p->count += 1; + if (ELF32_R_TYPE (rel->r_info) == R_OR1K_INSN_REL_26) + p->pc_count += 1; + } + } + break; + } + } + + return TRUE; +} + +/* Finish up the dynamic sections. */ + +static bfd_boolean +or1k_elf_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) +{ + bfd *dynobj; + asection *sdyn, *sgot; + struct elf_or1k_link_hash_table *htab; + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + dynobj = htab->root.dynobj; + + sgot = htab->sgotplt; + sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + + if (htab->root.dynamic_sections_created) + { + asection *splt; + Elf32_External_Dyn *dyncon, *dynconend; + + BFD_ASSERT (sgot != NULL && sdyn != NULL); + + dyncon = (Elf32_External_Dyn *) sdyn->contents; + dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); + + for (; dyncon < dynconend; dyncon++) + { + Elf_Internal_Dyn dyn; + asection *s; + + bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); + + switch (dyn.d_tag) + { + default: + continue; + + case DT_PLTGOT: + s = htab->sgot->output_section; + BFD_ASSERT (s != NULL); + dyn.d_un.d_ptr = s->vma; + break; + + case DT_JMPREL: + s = htab->srelplt->output_section; + BFD_ASSERT (s != NULL); + dyn.d_un.d_ptr = s->vma; + break; + + case DT_PLTRELSZ: + s = htab->srelplt->output_section; + BFD_ASSERT (s != NULL); + dyn.d_un.d_val = s->size; + break; + + case DT_RELASZ: + /* My reading of the SVR4 ABI indicates that the + procedure linkage table relocs (DT_JMPREL) should be + included in the overall relocs (DT_RELA). This is + what Solaris does. However, UnixWare can not handle + that case. Therefore, we override the DT_RELASZ entry + here to make it not include the JMPREL relocs. Since + the linker script arranges for .rela.plt to follow all + other relocation sections, we don't have to worry + about changing the DT_RELA entry. */ + if (htab->srelplt != NULL) + { + /* FIXME: this calculation sometimes produces + wrong result, the problem is that the dyn.d_un.d_val + is not always correct, needs investigation why + that happens. In the meantime, reading the + ".rela.dyn" section by name seems to yield + correct result. + + s = htab->srelplt->output_section; + dyn.d_un.d_val -= s->size; + */ + + s = bfd_get_section_by_name (output_bfd, ".rela.dyn"); + dyn.d_un.d_val = s ? s->size : 0; + } + break; + } + bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + } + + + /* Fill in the first entry in the procedure linkage table. */ + splt = htab->splt; + if (splt && splt->size > 0) + { + if (info->shared) + { + bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, + splt->contents); + bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, + splt->contents + 4); + bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2, + splt->contents + 8); + bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3, + splt->contents + 12); + bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4, + splt->contents + 16); + } + else + { + unsigned long addr; + /* addr = .got + 4 */ + addr = sgot->output_section->vma + sgot->output_offset + 4; + bfd_put_32 (output_bfd, + PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff), + splt->contents); + bfd_put_32 (output_bfd, + PLT0_ENTRY_WORD1 | (addr & 0xffff), + splt->contents + 4); + bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8); + bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12); + bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16); + } + + elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; + } + } + + /* Set the first entry in the global offset table to the address of + the dynamic section. */ + if (sgot && sgot->size > 0) + { + if (sdyn == NULL) + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); + else + bfd_put_32 (output_bfd, + sdyn->output_section->vma + sdyn->output_offset, + sgot->contents); + elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; + } + + if (htab->sgot && htab->sgot->size > 0) + elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4; + + return TRUE; +} + +/* Finish up dynamic symbol handling. We set the contents of various + dynamic sections here. */ + +static bfd_boolean +or1k_elf_finish_dynamic_symbol (bfd *output_bfd, + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + struct elf_or1k_link_hash_table *htab; + bfd_byte *loc; + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + if (h->plt.offset != (bfd_vma) -1) + { + asection *splt; + asection *sgot; + asection *srela; + + bfd_vma plt_index; + bfd_vma got_offset; + bfd_vma got_addr; + Elf_Internal_Rela rela; + + /* This symbol has an entry in the procedure linkage table. Set + it up. */ + BFD_ASSERT (h->dynindx != -1); + + splt = htab->splt; + sgot = htab->sgotplt; + srela = htab->srelplt; + BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); + + /* Get the index in the procedure linkage table which + corresponds to this symbol. This is the index of this symbol + in all the symbols for which we are making plt entries. The + first entry in the procedure linkage table is reserved. */ + plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; + + /* Get the offset into the .got table of the entry that + corresponds to this function. Each .got entry is 4 bytes. + The first three are reserved. */ + got_offset = (plt_index + 3) * 4; + got_addr = got_offset; + + /* Fill in the entry in the procedure linkage table. */ + if (! info->shared) + { + got_addr += htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset; + bfd_put_32 (output_bfd, PLT_ENTRY_WORD0 | ((got_addr >> 16) & 0xffff), + splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, PLT_ENTRY_WORD1 | (got_addr & 0xffff), + splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2, + splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3, + splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, PLT_ENTRY_WORD4 + | plt_index * sizeof (Elf32_External_Rela), + splt->contents + h->plt.offset + 16); + } + else + { + bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD0 | (got_addr & 0xffff), + splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD1 + | plt_index * sizeof (Elf32_External_Rela), + splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD2, + splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD3, + splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD4, + splt->contents + h->plt.offset + 16); + } + + /* Fill in the entry in the global offset table. */ + bfd_put_32 (output_bfd, + (splt->output_section->vma + + splt->output_offset), /* Same offset. */ + sgot->contents + got_offset); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = (sgot->output_section->vma + + sgot->output_offset + + got_offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_JMP_SLOT); + rela.r_addend = 0; + loc = srela->contents; + loc += plt_index * sizeof (Elf32_External_Rela); + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + + if (!h->def_regular) + { + /* Mark the symbol as undefined, rather than as defined in + the .plt section. Leave the value alone. */ + sym->st_shndx = SHN_UNDEF; + } + + } + + if (h->got.offset != (bfd_vma) -1 + && (h->got.offset & 2) == 0) /* Homemade TLS check. */ + { + asection *sgot; + asection *srela; + Elf_Internal_Rela rela; + + /* This symbol has an entry in the global offset table. Set it + up. */ + sgot = htab->sgot; + srela = htab->srelgot; + BFD_ASSERT (sgot != NULL && srela != NULL); + + rela.r_offset = (sgot->output_section->vma + + sgot->output_offset + + (h->got.offset &~ 1)); + + /* If this is a -Bsymbolic link, and the symbol is defined + locally, we just want to emit a RELATIVE reloc. Likewise if + the symbol was forced to be local because of a version file. + The entry in the global offset table will already have been + initialized in the relocate_section function. */ + if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h)) + { + rela.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + { + BFD_ASSERT ((h->got.offset & 1) == 0); + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_GLOB_DAT); + rela.r_addend = 0; + } + + loc = srela->contents; + loc += srela->reloc_count * sizeof (Elf32_External_Rela); + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + ++srela->reloc_count; + } + + if (h->needs_copy) + { + asection *s; + Elf_Internal_Rela rela; + + /* This symbols needs a copy reloc. Set it up. */ + BFD_ASSERT (h->dynindx != -1 + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak)); + + s = bfd_get_section_by_name (h->root.u.def.section->owner, + ".rela.bss"); + BFD_ASSERT (s != NULL); + + rela.r_offset = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_COPY); + rela.r_addend = 0; + loc = s->contents; + loc += s->reloc_count * sizeof (Elf32_External_Rela); + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + ++s->reloc_count; + } + + /* Mark some specially defined symbols as absolute. */ + if (strcmp (h->root.root.string, "_DYNAMIC") == 0 + || h == htab->root.hgot) + sym->st_shndx = SHN_ABS; + + return TRUE; +} + +static enum elf_reloc_type_class +or1k_elf_reloc_type_class (const Elf_Internal_Rela *rela) +{ + switch ((int) ELF32_R_TYPE (rela->r_info)) + { + case R_OR1K_RELATIVE: return reloc_class_relative; + case R_OR1K_JMP_SLOT: return reloc_class_plt; + case R_OR1K_COPY: return reloc_class_copy; + default: return reloc_class_normal; + } +} + +/* Adjust a symbol defined by a dynamic object and referenced by a + regular object. The current definition is in some section of the + dynamic object, but we're not including those sections. We have to + change the definition to something the rest of the link can + understand. */ + +static bfd_boolean +or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + struct elf_or1k_link_hash_table *htab; + struct elf_or1k_link_hash_entry *eh; + struct elf_or1k_dyn_relocs *p; + bfd *dynobj; + asection *s; + + dynobj = elf_hash_table (info)->dynobj; + + /* Make sure we know what is going on here. */ + BFD_ASSERT (dynobj != NULL + && (h->needs_plt + || h->type == STT_GNU_IFUNC + || h->u.weakdef != NULL + || (h->def_dynamic + && h->ref_regular + && !h->def_regular))); + + /* If this is a function, put it in the procedure linkage table. We + will fill in the contents of the procedure linkage table later, + when we know the address of the .got section. */ + if ((h->type == STT_FUNC || h->type == STT_GNU_IFUNC) + || h->needs_plt) + { + if (! info->shared + && !h->def_dynamic + && !h->ref_dynamic + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined) + { + /* This case can occur if we saw a PLT reloc in an input + file, but the symbol was never referred to by a dynamic + object. In such a case, we don't actually need to build + a procedure linkage table, and we can just do a PCREL + reloc instead. */ + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + + return TRUE; + } + else + h->plt.offset = (bfd_vma) -1; + + /* If this is a weak symbol, and there is a real definition, the + processor independent code will have arranged for us to see the + real definition first, and we can just use the same value. */ + if (h->u.weakdef != NULL) + { + BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined + || h->u.weakdef->root.type == bfd_link_hash_defweak); + h->root.u.def.section = h->u.weakdef->root.u.def.section; + h->root.u.def.value = h->u.weakdef->root.u.def.value; + return TRUE; + } + + /* This is a reference to a symbol defined by a dynamic object which + is not a function. */ + + /* If we are creating a shared library, we must presume that the + only references to the symbol are via the global offset table. + For such cases we need not do anything here; the relocations will + be handled correctly by relocate_section. */ + if (info->shared) + return TRUE; + + /* If there are no references to this symbol that do not use the + GOT, we don't need to generate a copy reloc. */ + if (!h->non_got_ref) + return TRUE; + + /* If -z nocopyreloc was given, we won't generate them either. */ + if (info->nocopyreloc) + { + h->non_got_ref = 0; + return TRUE; + } + + eh = (struct elf_or1k_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + s = p->sec->output_section; + if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0) + break; + } + + /* If we didn't find any dynamic relocs in sections which needs the + copy reloc, then we'll be keeping the dynamic relocs and avoiding + the copy reloc. */ + if (p == NULL) + { + h->non_got_ref = 0; + return TRUE; + } + + /* We must allocate the symbol in our .dynbss section, which will + become part of the .bss section of the executable. There will be + an entry for this symbol in the .dynsym section. The dynamic + object will contain position independent code, so all references + from the dynamic object to this symbol will go through the global + offset table. The dynamic linker will use the .dynsym entry to + determine the address it must put in the global offset table, so + both the dynamic object and the regular object will refer to the + same memory location for the variable. */ + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + s = htab->sdynbss; + BFD_ASSERT (s != NULL); + + /* We must generate a R_OR1K_COPY reloc to tell the dynamic linker + to copy the initial value out of the dynamic object and into the + runtime process image. We need to remember the offset into the + .rela.bss section we are going to use. */ + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) + { + asection *srel; + + srel = htab->srelbss; + BFD_ASSERT (srel != NULL); + srel->size += sizeof (Elf32_External_Rela); + h->needs_copy = 1; + } + + return _bfd_elf_adjust_dynamic_copy (h, s); +} + +/* Allocate space in .plt, .got and associated reloc sections for + dynamic relocs. */ + +static bfd_boolean +allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) +{ + struct bfd_link_info *info; + struct elf_or1k_link_hash_table *htab; + struct elf_or1k_link_hash_entry *eh; + struct elf_or1k_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_indirect) + return TRUE; + + info = (struct bfd_link_info *) inf; + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + eh = (struct elf_or1k_link_hash_entry *) h; + + if (htab->root.dynamic_sections_created + && h->plt.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) + { + asection *s = htab->splt; + + /* If this is the first .plt entry, make room for the special + first entry. */ + if (s->size == 0) + s->size = PLT_ENTRY_SIZE; + + h->plt.offset = s->size; + + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && !h->def_regular) + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; + } + + /* Make room for this entry. */ + s->size += PLT_ENTRY_SIZE; + + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + htab->sgotplt->size += 4; + + /* We also need to make an entry in the .rel.plt section. */ + htab->srelplt->size += sizeof (Elf32_External_Rela); + } + else + { + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + + if (h->got.refcount > 0) + { + asection *s; + bfd_boolean dyn; + unsigned char tls_type; + + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + s = htab->sgot; + + h->got.offset = s->size; + + tls_type = ((struct elf_or1k_link_hash_entry *) h)->tls_type; + + /* TLS GD requires two GOT and two relocs. */ + if (tls_type == TLS_GD) + s->size += 8; + else + s->size += 4; + dyn = htab->root.dynamic_sections_created; + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)) + { + if (tls_type == TLS_GD) + htab->srelgot->size += 2 * sizeof (Elf32_External_Rela); + else + htab->srelgot->size += sizeof (Elf32_External_Rela); + } + } + else + h->got.offset = (bfd_vma) -1; + + if (eh->dyn_relocs == NULL) + return TRUE; + + /* In the shared -Bsymbolic case, discard space allocated for + dynamic pc-relative relocs against symbols which turn out to be + defined in regular objects. For the normal shared case, discard + space for pc-relative relocs that have become local due to symbol + visibility changes. */ + + if (info->shared) + { + if (SYMBOL_CALLS_LOCAL (info, h)) + { + struct elf_or1k_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) + { + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + } + + /* Also discard relocs on undefined weak syms with non-default + visibility. */ + if (eh->dyn_relocs != NULL + && h->root.type == bfd_link_hash_undefweak) + { + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + eh->dyn_relocs = NULL; + + /* Make sure undefined weak symbols are output as a dynamic + symbol in PIEs. */ + else if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + } + } + else + { + /* For the non-shared case, discard space for relocs against + symbols which turn out to need copy relocs or are not + dynamic. */ + + if (!h->non_got_ref + && ((h->def_dynamic + && !h->def_regular) + || (htab->root.dynamic_sections_created + && (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined)))) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + /* If that succeeded, we know we'll be keeping all the + relocs. */ + if (h->dynindx != -1) + goto keep; + } + + eh->dyn_relocs = NULL; + + keep: ; + } + + /* Finally, allocate space. */ + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *sreloc = elf_section_data (p->sec)->sreloc; + sreloc->size += p->count * sizeof (Elf32_External_Rela); + } + + return TRUE; +} + +/* Find any dynamic relocs that apply to read-only sections. */ + +static bfd_boolean +readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +{ + struct elf_or1k_link_hash_entry *eh; + struct elf_or1k_dyn_relocs *p; + + eh = (struct elf_or1k_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + info->flags |= DF_TEXTREL; + + /* Not an error, just cut short the traversal. */ + return FALSE; + } + } + return TRUE; +} + +/* Set the sizes of the dynamic sections. */ + +static bfd_boolean +or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) +{ + struct elf_or1k_link_hash_table *htab; + bfd *dynobj; + asection *s; + bfd_boolean relocs; + bfd *ibfd; + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + dynobj = htab->root.dynobj; + BFD_ASSERT (dynobj != NULL); + + if (htab->root.dynamic_sections_created) + { + /* Set the contents of the .interp section to the interpreter. */ + if (info->executable) + { + s = bfd_get_section_by_name (dynobj, ".interp"); + BFD_ASSERT (s != NULL); + s->size = sizeof ELF_DYNAMIC_INTERPRETER; + s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; + } + } + + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + { + bfd_signed_vma *local_got; + bfd_signed_vma *end_local_got; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; + unsigned char *local_tls_type; + asection *srel; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) + continue; + + for (s = ibfd->sections; s != NULL; s = s->next) + { + struct elf_or1k_dyn_relocs *p; + + for (p = ((struct elf_or1k_dyn_relocs *) + elf_section_data (s)->local_dynrel); + p != NULL; + p = p->next) + { + if (! bfd_is_abs_section (p->sec) + && bfd_is_abs_section (p->sec->output_section)) + { + /* Input section has been discarded, either because + it is a copy of a linkonce section or due to + linker script /DISCARD/, so we'll be discarding + the relocs too. */ + } + else if (p->count != 0) + { + srel = elf_section_data (p->sec)->sreloc; + srel->size += p->count * sizeof (Elf32_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; + } + } + } + + local_got = elf_local_got_refcounts (ibfd); + if (!local_got) + continue; + + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; + s = htab->sgot; + srel = htab->srelgot; + local_tls_type = (unsigned char *) elf_or1k_local_tls_type (ibfd); + for (; local_got < end_local_got; ++local_got) + { + if (*local_got > 0) + { + *local_got = s->size; + + /* TLS GD requires two GOT and two relocs. */ + if (local_tls_type != NULL && *local_tls_type == TLS_GD) + s->size += 8; + else + s->size += 4; + if (info->shared) + { + if (local_tls_type != NULL && *local_tls_type == TLS_GD) + srel->size += 2 * sizeof (Elf32_External_Rela); + else + srel->size += sizeof (Elf32_External_Rela); + } + } + else + + *local_got = (bfd_vma) -1; + + if (local_tls_type) + ++local_tls_type; + } + } + + /* Allocate global sym .plt and .got entries, and space for global + sym dynamic relocs. */ + elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info); + + /* We now have determined the sizes of the various dynamic sections. + Allocate memory for them. */ + relocs = FALSE; + for (s = dynobj->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LINKER_CREATED) == 0) + continue; + + if (s == htab->splt + || s == htab->sgot + || s == htab->sgotplt + || s == htab->sdynbss) + { + /* Strip this section if we don't need it; see the + comment below. */ + } + else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) + { + if (s->size != 0 && s != htab->srelplt) + relocs = TRUE; + + /* We use the reloc_count field as a counter if we need + to copy relocs into the output file. */ + s->reloc_count = 0; + } + else + /* It's not one of our sections, so don't allocate space. */ + continue; + + if (s->size == 0) + { + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + s->flags |= SEC_EXCLUDE; + continue; + } + + if ((s->flags & SEC_HAS_CONTENTS) == 0) + continue; + + /* Allocate memory for the section contents. We use bfd_zalloc + here in case unused entries are not reclaimed before the + section's contents are written out. This should not happen, + but this way if it does, we get a R_OR1K_NONE reloc instead + of garbage. */ + s->contents = bfd_zalloc (dynobj, s->size); + + if (s->contents == NULL) + return FALSE; + } + + if (htab->root.dynamic_sections_created) + { + /* Add some entries to the .dynamic section. We fill in the + values later, in or1k_elf_finish_dynamic_sections, but we + must add the entries now so that we get the correct size for + the .dynamic section. The DT_DEBUG entry is filled in by the + dynamic linker and used by the debugger. */ +#define add_dynamic_entry(TAG, VAL) \ + _bfd_elf_add_dynamic_entry (info, TAG, VAL) + + if (info->executable) + { + if (! add_dynamic_entry (DT_DEBUG, 0)) + return FALSE; + } + + if (htab->splt->size != 0) + { + if (! add_dynamic_entry (DT_PLTGOT, 0) + || ! add_dynamic_entry (DT_PLTRELSZ, 0) + || ! add_dynamic_entry (DT_PLTREL, DT_RELA) + || ! add_dynamic_entry (DT_JMPREL, 0)) + return FALSE; + } + + if (relocs) + { + if (! add_dynamic_entry (DT_RELA, 0) + || ! add_dynamic_entry (DT_RELASZ, 0) + || ! add_dynamic_entry (DT_RELAENT, + sizeof (Elf32_External_Rela))) + return FALSE; + + /* If any dynamic relocs apply to a read-only section, + then we need a DT_TEXTREL entry. */ + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->root, readonly_dynrelocs, + info); + + if ((info->flags & DF_TEXTREL) != 0) + { + if (! add_dynamic_entry (DT_TEXTREL, 0)) + return FALSE; + } + } + } + +#undef add_dynamic_entry + return TRUE; +} + +/* Create dynamic sections when linking against a dynamic object. */ + +static bfd_boolean +or1k_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) +{ + struct elf_or1k_link_hash_table *htab; + + htab = or1k_elf_hash_table (info); + if (htab == NULL) + return FALSE; + + if (!htab->sgot && !create_got_section (dynobj, info)) + return FALSE; + + if (!_bfd_elf_create_dynamic_sections (dynobj, info)) + return FALSE; + + htab->splt = bfd_get_section_by_name (dynobj, ".plt"); + htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); + if (!info->shared) + htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); + + if (!htab->splt || !htab->srelplt || !htab->sdynbss + || (!info->shared && !htab->srelbss)) + abort (); + + return TRUE; +} + +/* Copy the extra info we tack onto an elf_link_hash_entry. */ + +static void +or1k_elf_copy_indirect_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *dir, + struct elf_link_hash_entry *ind) +{ + struct elf_or1k_link_hash_entry * edir; + struct elf_or1k_link_hash_entry * eind; + + edir = (struct elf_or1k_link_hash_entry *) dir; + eind = (struct elf_or1k_link_hash_entry *) ind; + + if (eind->dyn_relocs != NULL) + { + if (edir->dyn_relocs != NULL) + { + struct elf_or1k_dyn_relocs **pp; + struct elf_or1k_dyn_relocs *p; + + /* Add reloc counts against the indirect sym to the direct sym + list. Merge any entries against the same section. */ + for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) + { + struct elf_or1k_dyn_relocs *q; + + for (q = edir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = edir->dyn_relocs; + } + + edir->dyn_relocs = eind->dyn_relocs; + eind->dyn_relocs = NULL; + } + + if (ind->root.type == bfd_link_hash_indirect) + { + if (dir->got.refcount <= 0) + { + edir->tls_type = eind->tls_type; + eind->tls_type = TLS_UNKNOWN; + } + } + + _bfd_elf_link_hash_copy_indirect (info, dir, ind); +} + +/* Set the right machine number. */ + +static bfd_boolean +or1k_elf_object_p (bfd *abfd) +{ + unsigned long mach = bfd_mach_or1k; + + if (elf_elfheader (abfd)->e_flags & EF_OR1K_NODELAY) + mach = bfd_mach_or1knd; + + return bfd_default_set_arch_mach (abfd, bfd_arch_or1k, mach); +} + +/* Store the machine number in the flags field. */ + +static void +or1k_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) +{ + switch (bfd_get_mach (abfd)) + { + default: + case bfd_mach_or1k: + break; + case bfd_mach_or1knd: + elf_elfheader (abfd)->e_flags |= EF_OR1K_NODELAY; + break; + } +} + +static bfd_boolean +or1k_elf_set_private_flags (bfd *abfd, flagword flags) +{ + BFD_ASSERT (!elf_flags_init (abfd) + || elf_elfheader (abfd)->e_flags == flags); + + elf_elfheader (abfd)->e_flags = flags; + elf_flags_init (abfd) = TRUE; + return TRUE; +} + +/* Make sure all input files are consistent with respect to + EF_OR1K_NODELAY flag setting. */ + +static bfd_boolean +elf32_or1k_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + flagword out_flags; + flagword in_flags; + + in_flags = elf_elfheader (ibfd)->e_flags; + out_flags = elf_elfheader (obfd)->e_flags; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || bfd_get_flavour (obfd) != bfd_target_elf_flavour) + return TRUE; + + if (!elf_flags_init (obfd)) + { + elf_flags_init (obfd) = TRUE; + elf_elfheader (obfd)->e_flags = in_flags; + + return TRUE; + } + + if (in_flags == out_flags) + return TRUE; + + if ((in_flags & EF_OR1K_NODELAY) != (out_flags & EF_OR1K_NODELAY)) + { + (*_bfd_error_handler) + (_("%B: EF_OR1K_NODELAY flag mismatch with previous modules"), ibfd); + + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + return TRUE; + +} + +#define ELF_ARCH bfd_arch_or1k +#define ELF_MACHINE_CODE EM_OR1K +#define ELF_TARGET_ID OR1K_ELF_DATA +#define ELF_MAXPAGESIZE 0x2000 + +#define TARGET_BIG_SYM bfd_elf32_or1k_big_vec +#define TARGET_BIG_NAME "elf32-or1k" + +#define elf_info_to_howto_rel NULL +#define elf_info_to_howto or1k_info_to_howto_rela +#define elf_backend_relocate_section or1k_elf_relocate_section +#define elf_backend_gc_mark_hook or1k_elf_gc_mark_hook +#define elf_backend_gc_sweep_hook or1k_elf_gc_sweep_hook +#define elf_backend_check_relocs or1k_elf_check_relocs +#define elf_backend_reloc_type_class or1k_elf_reloc_type_class +#define elf_backend_can_gc_sections 1 +#define elf_backend_rela_normal 1 + +#define bfd_elf32_mkobject elf_or1k_mkobject + +#define bfd_elf32_bfd_merge_private_bfd_data elf32_or1k_merge_private_bfd_data +#define bfd_elf32_bfd_set_private_flags or1k_elf_set_private_flags +#define bfd_elf32_bfd_reloc_type_lookup or1k_reloc_type_lookup +#define bfd_elf32_bfd_reloc_name_lookup or1k_reloc_name_lookup + +#define elf_backend_object_p or1k_elf_object_p +#define elf_backend_final_write_processing or1k_elf_final_write_processing +#define elf_backend_can_refcount 1 + +#define elf_backend_plt_readonly 1 +#define elf_backend_want_got_plt 1 +#define elf_backend_want_plt_sym 0 +#define elf_backend_got_header_size 12 +#define bfd_elf32_bfd_link_hash_table_create or1k_elf_link_hash_table_create +#define elf_backend_copy_indirect_symbol or1k_elf_copy_indirect_symbol +#define elf_backend_create_dynamic_sections or1k_elf_create_dynamic_sections +#define elf_backend_finish_dynamic_sections or1k_elf_finish_dynamic_sections +#define elf_backend_size_dynamic_sections or1k_elf_size_dynamic_sections +#define elf_backend_adjust_dynamic_symbol or1k_elf_adjust_dynamic_symbol +#define elf_backend_finish_dynamic_symbol or1k_elf_finish_dynamic_symbol + +#include "elf32-target.h" diff -rNU3 dist.orig/bfd/elf32-or32.c dist/bfd/elf32-or32.c --- dist.orig/bfd/elf32-or32.c 2007-07-03 16:26:41.000000000 +0200 +++ dist/bfd/elf32-or32.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,514 +0,0 @@ -/* OR32-specific support for 32-bit ELF - Copyright 2002, 2004, 2005, 2007 Free Software Foundation, Inc. - Contributed by Ivan Guzvinec - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/or32.h" -#include "libiberty.h" - -/* Try to minimize the amount of space occupied by relocation tables - on the ROM (not that the ROM won't be swamped by other ELF overhead). */ -#define USE_REL 1 - -/* Set the right machine number for an OR32 ELF file. */ - -static bfd_boolean -or32_elf_object_p (bfd *abfd) -{ - (void) bfd_default_set_arch_mach (abfd, bfd_arch_or32, 0); - return TRUE; -} - -/* The final processing done just before writing out an OR32 ELF object file. - This gets the OR32 architecture right based on the machine number. */ - -static void -or32_elf_final_write_processing (bfd *abfd, - bfd_boolean linker ATTRIBUTE_UNUSED) -{ - elf_elfheader (abfd)->e_flags &=~ EF_OR32_MACH; -} - -static bfd_reloc_status_type -or32_elf_32_reloc (bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - if (output_bfd != NULL) - { - unsigned long insn; - bfd_size_type addr = reloc_entry->address; - - reloc_entry->address += input_section->output_offset; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + addr); - insn += symbol->section->output_section->vma; - insn += symbol->section->output_offset; - insn += symbol->value; - bfd_put_32 (abfd, insn, (bfd_byte *) data + addr); - - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -static bfd_reloc_status_type -or32_elf_16_reloc (bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - if (output_bfd != NULL) - { - unsigned short insn; - bfd_size_type addr = reloc_entry->address; - - reloc_entry->address += input_section->output_offset; - - insn = bfd_get_16 (abfd, (bfd_byte *) data + addr); - insn += symbol->section->output_section->vma; - insn += symbol->section->output_offset; - insn += symbol->value; - bfd_put_16 (abfd, insn, (bfd_byte *) data + addr); - - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -static bfd_reloc_status_type -or32_elf_8_reloc (bfd *abfd ATTRIBUTE_UNUSED, - arelent *reloc_entry, - asymbol *symbol, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - if (output_bfd != NULL) - { - unsigned char insn; - bfd_size_type addr = reloc_entry->address; - - reloc_entry->address += input_section->output_offset; - - insn = bfd_get_8 (abfd, (bfd_byte *) data + addr); - insn += symbol->section->output_section->vma; - insn += symbol->section->output_offset; - insn += symbol->value; - bfd_put_8 (abfd, insn, (bfd_byte *) data + addr); - - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Do a R_OR32_CONSTH relocation. This has to be done in combination - with a R_OR32_CONST reloc, because there is a carry from the LO16 to - the HI16. Here we just save the information we need; we do the - actual relocation when we see the LO16. OR32 ELF requires that the - LO16 immediately follow the HI16. As a GNU extension, we permit an - arbitrary number of HI16 relocs to be associated with a single LO16 - reloc. This extension permits gcc to output the HI and LO relocs - itself. This code is copied from the elf32-mips.c. */ - -struct or32_consth -{ - struct or32_consth *next; - bfd_byte *addr; - bfd_vma addend; -}; - -/* FIXME: This should not be a static variable. */ - -static struct or32_consth *or32_consth_list; - -static bfd_reloc_status_type -or32_elf_consth_reloc (bfd *abfd ATTRIBUTE_UNUSED, - arelent *reloc_entry, - asymbol *symbol, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - struct or32_consth *n; - - ret = bfd_reloc_ok; - - if (bfd_is_und_section (symbol->section) - && output_bfd == NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - /* Save the information, and let LO16 do the actual relocation. */ - n = bfd_malloc (sizeof *n); - if (n == NULL) - return bfd_reloc_outofrange; - n->addr = (bfd_byte *) data + reloc_entry->address; - n->addend = relocation; - n->next = or32_consth_list; - or32_consth_list = n; - - if (output_bfd != NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a R_OR32_CONST relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_OR32_CONSTH relocation described above. */ - -static bfd_reloc_status_type -or32_elf_const_reloc (bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message) -{ - if (or32_consth_list != NULL) - { - struct or32_consth *l; - - l = or32_consth_list; - while (l != NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - struct or32_consth *next; - - /* Do the HI16 relocation. Note that we actually don't need - to know anything about the LO16 itself, except where to - find the low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (abfd, l->addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += l->addend; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, l->addr); - - next = l->next; - free (l); - l = next; - } - - or32_consth_list = NULL; - } - - if (output_bfd != NULL) - { - unsigned long insn, tmp; - bfd_size_type addr = reloc_entry->address; - - reloc_entry->address += input_section->output_offset; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + addr); - tmp = insn & 0x0000ffff; - tmp += symbol->section->output_section->vma; - tmp += symbol->section->output_offset; - tmp += symbol->value; - insn = (insn & 0xffff0000) | (tmp & 0x0000ffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + addr); - - return bfd_reloc_ok; - } - - /* Now do the LO16 reloc in the usual way. */ - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -static bfd_reloc_status_type -or32_elf_jumptarg_reloc (bfd *abfd, - arelent *reloc_entry, - asymbol *symbol ATTRIBUTE_UNUSED, - void * data, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - if (output_bfd != NULL) - { - unsigned long insn, tmp; - bfd_size_type addr = reloc_entry->address; - - reloc_entry->address += input_section->output_offset; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + addr); - tmp = insn | 0xfc000000; - tmp -= (input_section->output_offset >> 2); - insn = (insn & 0xfc000000) | (tmp & 0x03ffffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + addr); - - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -static reloc_howto_type elf_or32_howto_table[] = -{ - /* This reloc does nothing. */ - HOWTO (R_OR32_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OR32_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 32 bit relocation. */ - HOWTO (R_OR32_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_32_reloc, /* special_function */ - "R_OR32_32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 16 bit relocation. */ - HOWTO (R_OR32_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_16_reloc, /* special_function */ - "R_OR32_16", /* name */ - FALSE, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 8 bit relocation. */ - HOWTO (R_OR32_8, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_8_reloc, /* special_function */ - "R_OR32_8", /* name */ - FALSE, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard low 16 bit relocation. */ - HOWTO (R_OR32_CONST, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - or32_elf_const_reloc, /* special_function */ - "R_OR32_CONST", /* name */ - FALSE, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard high 16 bit relocation. */ - HOWTO (R_OR32_CONSTH, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - or32_elf_consth_reloc, /* special_function */ - "R_OR32_CONSTH", /* name */ - FALSE, /* partial_inplace */ - 0xffff0000, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard branch relocation. */ - HOWTO (R_OR32_JUMPTARG, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 28, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - or32_elf_jumptarg_reloc,/* special_function */ - "R_OR32_JUMPTARG", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0x03ffffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy. */ - HOWTO (R_OR32_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_OR32_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage. */ - HOWTO (R_OR32_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_OR32_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ -}; - -/* Map BFD reloc types to OR32 ELF reloc types. */ - -struct or32_reloc_map -{ - bfd_reloc_code_real_type bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static const struct or32_reloc_map or32_reloc_map[] = -{ - { BFD_RELOC_NONE, R_OR32_NONE }, - { BFD_RELOC_32, R_OR32_32 }, - { BFD_RELOC_16, R_OR32_16 }, - { BFD_RELOC_8, R_OR32_8 }, - { BFD_RELOC_LO16, R_OR32_CONST }, - { BFD_RELOC_HI16, R_OR32_CONSTH }, - { BFD_RELOC_32_GOT_PCREL, R_OR32_JUMPTARG }, - { BFD_RELOC_VTABLE_INHERIT, R_OR32_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_OR32_GNU_VTENTRY }, -}; - -static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, - bfd_reloc_code_real_type code) -{ - unsigned int i; - - for (i = ARRAY_SIZE (or32_reloc_map); i--;) - if (or32_reloc_map[i].bfd_reloc_val == code) - return &elf_or32_howto_table[or32_reloc_map[i].elf_reloc_val]; - - return NULL; -} - -static reloc_howto_type * -bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, - const char *r_name) -{ - unsigned int i; - - for (i = 0; - i < sizeof (elf_or32_howto_table) / sizeof (elf_or32_howto_table[0]); - i++) - if (elf_or32_howto_table[i].name != NULL - && strcasecmp (elf_or32_howto_table[i].name, r_name) == 0) - return &elf_or32_howto_table[i]; - - return NULL; -} - -/* Set the howto pointer for an OR32 ELF reloc. */ - -static void -or32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, - arelent *cache_ptr, - Elf_Internal_Rela *dst) -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_OR32_max); - cache_ptr->howto = &elf_or32_howto_table[r_type]; -} - -#define TARGET_LITTLE_SYM bfd_elf32_or32_little_vec -#define TARGET_LITTLE_NAME "elf32-littleor32" -#define TARGET_BIG_SYM bfd_elf32_or32_big_vec -#define TARGET_BIG_NAME "elf32-or32" -#define ELF_ARCH bfd_arch_or32 -#define ELF_MACHINE_CODE EM_OR32 -#define ELF_MAXPAGESIZE 0x1000 - -#define elf_info_to_howto 0 -#define elf_info_to_howto_rel or32_info_to_howto_rel -#define elf_backend_object_p or32_elf_object_p -#define elf_backend_final_write_processing \ - or32_elf_final_write_processing - -#include "elf32-target.h" diff -rNU3 dist.orig/bfd/elf32-ppc.c dist/bfd/elf32-ppc.c --- dist.orig/bfd/elf32-ppc.c 2013-03-25 09:06:19.000000000 +0100 +++ dist/bfd/elf32-ppc.c 2015-10-18 13:11:12.000000000 +0200 @@ -3898,7 +3898,7 @@ sec->has_tls_get_addr_call = 1; } - switch (r_type) + switch ((int)r_type) { case R_PPC_TLSGD: case R_PPC_TLSLD: @@ -7766,7 +7766,7 @@ howto = NULL; if (r_type < R_PPC_max) howto = ppc_elf_howto_table[r_type]; - switch (r_type) + switch ((int)r_type) { default: info->callbacks->einfo diff -rNU3 dist.orig/bfd/elf32-sh.c dist/bfd/elf32-sh.c --- dist.orig/bfd/elf32-sh.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elf32-sh.c 2015-10-18 13:11:12.000000000 +0200 @@ -2808,6 +2808,7 @@ /* Make sure we know what is going on here. */ BFD_ASSERT (htab->root.dynobj != NULL && (h->needs_plt + || h->type == STT_GNU_IFUNC || h->u.weakdef != NULL || (h->def_dynamic && h->ref_regular @@ -2816,7 +2817,7 @@ /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if ((h->type == STT_FUNC || h->type == STT_GNU_IFUNC) || h->needs_plt) { if (h->plt.refcount <= 0 @@ -3285,6 +3286,10 @@ { struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + h->root.root.string); info->flags |= DF_TEXTREL; /* Not an error, just cut short the traversal. */ diff -rNU3 dist.orig/bfd/elf32-vax.c dist/bfd/elf32-vax.c --- dist.orig/bfd/elf32-vax.c 2012-09-04 15:32:53.000000000 +0200 +++ dist/bfd/elf32-vax.c 2015-10-18 13:11:13.000000000 +0200 @@ -490,6 +490,24 @@ return TRUE; } +/* Copy vax-specific data from one module to another */ +static bfd_boolean +elf32_vax_copy_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + flagword in_flags; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || bfd_get_flavour (obfd) != bfd_target_elf_flavour) + return TRUE; + + in_flags = elf_elfheader (ibfd)->e_flags; + + elf_elfheader (obfd)->e_flags = in_flags; + elf_flags_init (obfd) = TRUE; + + return TRUE; +} + /* Merge backend specific data from an object file to the output object file when linking. */ static bfd_boolean @@ -752,7 +770,13 @@ return FALSE; if (sec->flags & SEC_READONLY) - info->flags |= DF_TEXTREL; + { + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + sec->name); + info->flags |= DF_TEXTREL; + } } sreloc->size += sizeof (Elf32_External_Rela); @@ -922,6 +946,7 @@ /* Make sure we know what is going on here. */ BFD_ASSERT (dynobj != NULL && (h->needs_plt + || h->type == STT_GNU_IFUNC || h->u.weakdef != NULL || (h->def_dynamic && h->ref_regular @@ -930,7 +955,7 @@ /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ - if (h->type == STT_FUNC + if ((h->type == STT_FUNC || h->type == STT_GNU_IFUNC) || h->needs_plt) { if (h->plt.refcount <= 0 @@ -1186,7 +1211,12 @@ continue; /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size); + /* FIXME: This should be a call to bfd_alloc not bfd_zalloc. + Unused entries should be reclaimed before the section's contents + are written out, but at the moment this does not happen. Thus in + order to prevent writing out garbage, we initialise the section's + contents to zero. */ + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); if (s->contents == NULL) return FALSE; } @@ -1285,6 +1315,7 @@ if (!elf_hash_table (info)->dynamic_sections_created || (info->shared && info->symbolic) + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local) { h->got.refcount = 0; @@ -1305,9 +1336,7 @@ dyn = elf_hash_table (info)->dynamic_sections_created; /* Allocate space in the .got and .rela.got sections. */ - if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - && (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) + if (info->shared || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)) { sgot->size += 4; srelgot->size += sizeof (Elf32_External_Rela); @@ -1631,9 +1660,9 @@ { relocate = TRUE; outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); - BFD_ASSERT (bfd_get_signed_32 (input_bfd, - &contents[rel->r_offset]) == 0); - outrel.r_addend = relocation + rel->r_addend; + outrel.r_addend = bfd_get_signed_32(input_bfd, + &contents[rel->r_offset]) + + relocation + rel->r_addend; } else { @@ -1672,6 +1701,9 @@ } } + if (input_section->flags & SEC_CODE) + info->flags |= DF_TEXTREL; + if ((input_section->flags & SEC_CODE) != 0 || (ELF32_R_TYPE (outrel.r_info) != R_VAX_32 && ELF32_R_TYPE (outrel.r_info) != R_VAX_RELATIVE @@ -2051,12 +2083,15 @@ #define TARGET_LITTLE_SYM bfd_elf32_vax_vec #define TARGET_LITTLE_NAME "elf32-vax" #define ELF_MACHINE_CODE EM_VAX -#define ELF_MAXPAGESIZE 0x1000 +#define ELF_MAXPAGESIZE 0x10000 #define elf_backend_create_dynamic_sections \ _bfd_elf_create_dynamic_sections #define bfd_elf32_bfd_link_hash_table_create \ elf_vax_link_hash_table_create +#define bfd_elf32_bfd_copy_private_bfd_data \ + elf32_vax_copy_private_bfd_data + #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link #define elf_backend_check_relocs elf_vax_check_relocs diff -rNU3 dist.orig/bfd/elf64-alpha.c dist/bfd/elf64-alpha.c --- dist.orig/bfd/elf64-alpha.c 2012-07-24 23:06:58.000000000 +0200 +++ dist/bfd/elf64-alpha.c 2015-10-18 13:11:13.000000000 +0200 @@ -100,6 +100,11 @@ #define PLT_ENTRY_SIZE \ (elf64_alpha_use_secureplt ? NEW_PLT_ENTRY_SIZE : OLD_PLT_ENTRY_SIZE) +/* ld --traditional-format uses this older format instead. */ +#define OLD_PLT_ENTRY_WORD1 0x279f0000 /* ldah $28, 0($31) */ +#define OLD_PLT_ENTRY_WORD2 0x239c0000 /* lda $28, 0($28) */ +#define OLD_PLT_ENTRY_WORD3 0xc3e00000 /* br $31, plt0 */ + #define MAX_GOT_SIZE (64*1024) #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so" @@ -4821,6 +4826,32 @@ plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE); } + else if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) + { + long hi, lo; + + /* decompose the reloc offset for the plt for ldah+lda */ + hi = plt_index * sizeof(Elf64_External_Rela); + lo = ((hi & 0xffff) ^ 0x8000) - 0x8000; + hi = (hi - lo) >> 16; + + insn = INSN_ABO (INSN_LDAH, 28, 31, hi); + bfd_put_32 (output_bfd, insn, + splt->contents + gotent->plt_offset); + + insn = INSN_ABO (INSN_LDA, 28, 28, lo); + bfd_put_32 (output_bfd, insn, + splt->contents + gotent->plt_offset + 4); + + disp = -(gotent->plt_offset + 12); + insn = INSN_AD (INSN_BR, 31, disp); + + bfd_put_32 (output_bfd, insn, + splt->contents + gotent->plt_offset + 8); + + plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE) + / OLD_PLT_ENTRY_SIZE); + } else { disp = -(gotent->plt_offset + 4); diff -rNU3 dist.orig/bfd/elf64-mips.c dist/bfd/elf64-mips.c --- dist.orig/bfd/elf64-mips.c 2012-09-04 16:13:07.000000000 +0200 +++ dist/bfd/elf64-mips.c 2015-10-18 13:11:13.000000000 +0200 @@ -123,6 +123,8 @@ (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *); static bfd_boolean mips_elf64_object_p (bfd *); +static bfd_boolean mips_elf64_is_local_label_name + (bfd *, const char *); static irix_compat_t elf64_mips_irix_compat (bfd *); static bfd_boolean elf64_mips_grok_prstatus @@ -3917,7 +3919,18 @@ bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach); return TRUE; } + +/* MIPS ELF local labels start with "$L". */ +static bfd_boolean +mips_elf64_is_local_label_name (bfd *abfd, const char *name) +{ + if (name[0] == '$' && name[1] == 'L') + return TRUE; + /* We accept the generic ELF local label syntax as well. */ + return _bfd_elf_is_local_label_name (abfd, name); +} + /* Depending on the target vector we generate some version of Irix executables or "normal" MIPS ELF ABI executables. */ static irix_compat_t @@ -4141,9 +4154,8 @@ #define elf_backend_write_section _bfd_mips_elf_write_section -/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit - MIPS-specific function only applies to IRIX5, which had no 64-bit - ABI. */ +#define bfd_elf64_bfd_is_local_label_name \ + mips_elf64_is_local_label_name #define bfd_elf64_bfd_is_target_special_symbol \ _bfd_mips_elf_is_target_special_symbol #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line diff -rNU3 dist.orig/bfd/elf64-ppc.c dist/bfd/elf64-ppc.c --- dist.orig/bfd/elf64-ppc.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elf64-ppc.c 2015-10-18 13:11:13.000000000 +0200 @@ -3618,9 +3618,6 @@ struct ppc_link_hash_entry *h; struct plt_entry *plt_ent; - /* And the reloc addend that this was derived from. */ - bfd_vma addend; - /* Where this stub is being called from, or, in the case of combined stub sections, the first input section in the group. */ asection *id_sec; @@ -9112,6 +9109,10 @@ { struct bfd_link_info *info = inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + h->root.root.string); info->flags |= DF_TEXTREL; /* Not an error, just cut short the traversal. */ @@ -9192,7 +9193,13 @@ srel = htab->reliplt; srel->size += p->count * sizeof (Elf64_External_Rela); if ((p->sec->output_section->flags & SEC_READONLY) != 0) - info->flags |= DF_TEXTREL; + { + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + p->sec->output_section->name); + info->flags |= DF_TEXTREL; + } } } } @@ -11659,7 +11666,6 @@ } stub_entry->h = hash; stub_entry->plt_ent = plt_ent; - stub_entry->addend = irela->r_addend; if (stub_entry->h != NULL) htab->stub_globals += 1; @@ -12900,60 +12906,96 @@ { bfd_boolean can_plt_call = FALSE; + /* All of these stubs will modify r2, so there must be a + branch and link followed by a nop. The nop is + replaced by an insn to restore r2. */ if (rel->r_offset + 8 <= input_section->size) { - unsigned long nop; - nop = bfd_get_32 (input_bfd, contents + rel->r_offset + 4); - if (nop == NOP - || nop == CROR_151515 || nop == CROR_313131) - { - if (h != NULL - && (h == htab->tls_get_addr_fd - || h == htab->tls_get_addr) - && !htab->no_tls_get_addr_opt) + unsigned long br; + + br = bfd_get_32 (input_bfd, + contents + rel->r_offset); + if ((br & 1) != 0) + { + unsigned long nop; + + nop = bfd_get_32 (input_bfd, + contents + rel->r_offset + 4); + if (nop == NOP + || nop == CROR_151515 || nop == CROR_313131) { - /* Special stub used, leave nop alone. */ + if (h != NULL + && (h == htab->tls_get_addr_fd + || h == htab->tls_get_addr) + && !htab->no_tls_get_addr_opt) + { + /* Special stub used, leave nop alone. */ + } + else + bfd_put_32 (input_bfd, LD_R2_40R1, + contents + rel->r_offset + 4); + can_plt_call = TRUE; } - else - bfd_put_32 (input_bfd, LD_R2_40R1, - contents + rel->r_offset + 4); - can_plt_call = TRUE; } } - if (!can_plt_call) + if (!can_plt_call && h != NULL) { - if (stub_entry->stub_type == ppc_stub_plt_call - || stub_entry->stub_type == ppc_stub_plt_call_r2save) - { - /* If this is a plain branch rather than a branch - and link, don't require a nop. However, don't - allow tail calls in a shared library as they - will result in r2 being corrupted. */ - unsigned long br; - br = bfd_get_32 (input_bfd, contents + rel->r_offset); - if (info->executable && (br & 1) == 0) - can_plt_call = TRUE; - else - stub_entry = NULL; - } - else if (h != NULL - && strcmp (h->elf.root.root.string, - ".__libc_start_main") == 0) + const char *name = h->elf.root.root.string; + + if (*name == '.') + ++name; + + if (strncmp (name, "__libc_start_main", 17) == 0 + && (name[17] == 0 || name[17] == '@')) { - /* Allow crt1 branch to go via a toc adjusting stub. */ + /* Allow crt1 branch to go via a toc adjusting + stub. Other calls that never return could do + the same, if we could detect such. */ can_plt_call = TRUE; } - else + } + + if (!can_plt_call) + { + /* g++ as of 20130507 emits self-calls without a + following nop. This is arguably wrong since we + have conflicting information. On the one hand a + global symbol and on the other a local call + sequence, but don't error for this special case. + It isn't possible to cheaply verify we have + exactly such a call. Allow all calls to the same + section. */ + asection *code_sec = sec; + + if (get_opd_info (sec) != NULL) { - info->callbacks->einfo - (_("%P: %H: call to `%T' lacks nop, can't restore toc; " - "recompile with -fPIC"), - input_bfd, input_section, rel->r_offset, sym_name); + bfd_vma off = (relocation + addend + - sec->output_section->vma + - sec->output_offset); - bfd_set_error (bfd_error_bad_value); - ret = FALSE; + opd_entry_value (sec, off, &code_sec, NULL, FALSE); } + if (code_sec == input_section) + can_plt_call = TRUE; + } + + if (!can_plt_call) + { + + if (stub_entry->stub_type == ppc_stub_plt_call + || stub_entry->stub_type == ppc_stub_plt_call_r2save) + info->callbacks->einfo + (_("%P: %H: call to `%T' lacks nop, can't restore toc; " + "recompile with -fPIC"), + input_bfd, input_section, rel->r_offset, sym_name); + else + info->callbacks->einfo + (_("%P: %H: call to `%T' lacks nop, can't restore toc; " + "(-mcmodel=small toc adjust stub)"), + input_bfd, input_section, rel->r_offset, sym_name); + bfd_set_error (bfd_error_bad_value); + ret = FALSE; } if (can_plt_call diff -rNU3 dist.orig/bfd/elf64-x86-64.c dist/bfd/elf64-x86-64.c --- dist.orig/bfd/elf64-x86-64.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elf64-x86-64.c 2015-10-18 13:11:13.000000000 +0200 @@ -2589,6 +2589,10 @@ { struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + h->root.root.string); info->flags |= DF_TEXTREL; if (info->warn_shared_textrel && info->shared) diff -rNU3 dist.orig/bfd/elflink.c dist/bfd/elflink.c --- dist.orig/bfd/elflink.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elflink.c 2015-10-18 13:11:13.000000000 +0200 @@ -1442,7 +1442,10 @@ if (!(oldbfd != NULL && (oldbfd->flags & BFD_PLUGIN) != 0 && (abfd->flags & BFD_PLUGIN) == 0)) - *skip = TRUE; + { + newdef = FALSE; + *skip = TRUE; + } /* Merge st_other. If the symbol already has a dynamic index, but visibility says it should not be visible, turn it into a @@ -10183,7 +10186,14 @@ if (bed->s->arch_size == 32) irel[0].r_info = ELF32_R_INFO (indx, howto->type); else - irel[0].r_info = ELF64_R_INFO (indx, howto->type); +#ifdef BFD64 + { + bfd_uint64_t indx64 = indx; + irel[0].r_info = ELF64_R_INFO (indx64, howto->type); + } +#else + BFD_FAIL(); +#endif rel_hdr = reldata->hdr; erel = rel_hdr->contents; diff -rNU3 dist.orig/bfd/elfn32-mips.c dist/bfd/elfn32-mips.c --- dist.orig/bfd/elfn32-mips.c 2012-09-04 16:13:08.000000000 +0200 +++ dist/bfd/elfn32-mips.c 2015-10-18 13:11:13.000000000 +0200 @@ -81,6 +81,8 @@ (bfd *, Elf_Internal_Note *); static bfd_boolean elf32_mips_grok_psinfo (bfd *, Elf_Internal_Note *); +static bfd_boolean mips_elf_n32_is_local_label_name + (bfd *, const char *); static irix_compat_t elf_n32_mips_irix_compat (bfd *); @@ -3241,6 +3243,17 @@ return TRUE; } +/* MIPS ELF local labels start with "$L". */ +static bfd_boolean +mips_elf_n32_is_local_label_name (bfd *abfd, const char *name) +{ + if (name[0] == '$' && name[1] == 'L') + return TRUE; + + /* We accept the generic ELF local label syntax as well. */ + return _bfd_elf_is_local_label_name (abfd, name); +} + /* Depending on the target vector we generate some version of Irix executables or "normal" MIPS ELF ABI executables. */ static irix_compat_t @@ -3364,6 +3377,9 @@ #define elf_backend_write_section _bfd_mips_elf_write_section #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto + +#define bfd_elf32_bfd_is_local_label_name \ + mips_elf_n32_is_local_label_name #define bfd_elf32_bfd_is_target_special_symbol \ _bfd_mips_elf_is_target_special_symbol #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line diff -rNU3 dist.orig/bfd/elfnn-riscv.c dist/bfd/elfnn-riscv.c --- dist.orig/bfd/elfnn-riscv.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/elfnn-riscv.c 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,2957 @@ +/* RISC-V-specific support for NN-bit ELF. + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on TILE-Gx and MIPS targets. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + + +/* This file handles RISC-V ELF targets. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "bfdlink.h" +#include "genlink.h" +#include "elf-bfd.h" +#include "elfxx-riscv.h" +#include "elf/riscv.h" +#include "opcode/riscv.h" + +#define ARCH_SIZE NN + +#define MINUS_ONE ((bfd_vma)0 - 1) + +#define RISCV_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3) + +#define RISCV_ELF_WORD_BYTES (1 << RISCV_ELF_LOG_WORD_BYTES) + +/* The name of the dynamic interpreter. This is put in the .interp + section. */ + +#define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1" +#define ELF32_DYNAMIC_INTERPRETER "/lib32/ld.so.1" + +/* The RISC-V linker needs to keep track of the number of relocs that it + decides to copy as dynamic relocs in check_relocs for each symbol. + This is so that it can later discard them if they are found to be + unnecessary. We store the information in a field extending the + regular ELF linker hash table. */ + +struct riscv_elf_dyn_relocs +{ + struct riscv_elf_dyn_relocs *next; + + /* The input section of the reloc. */ + asection *sec; + + /* Total number of relocs copied for the input section. */ + bfd_size_type count; + + /* Number of pc-relative relocs copied for the input section. */ + bfd_size_type pc_count; +}; + +/* RISC-V ELF linker hash entry. */ + +struct riscv_elf_link_hash_entry +{ + struct elf_link_hash_entry elf; + + /* Track dynamic relocs copied for this symbol. */ + struct riscv_elf_dyn_relocs *dyn_relocs; + +#define GOT_UNKNOWN 0 +#define GOT_NORMAL 1 +#define GOT_TLS_GD 2 +#define GOT_TLS_IE 4 +#define GOT_TLS_LE 8 + char tls_type; +}; + +#define riscv_elf_hash_entry(ent) \ + ((struct riscv_elf_link_hash_entry *)(ent)) + +struct _bfd_riscv_elf_obj_tdata +{ + struct elf_obj_tdata root; + + /* tls_type for each local got entry. */ + char *local_got_tls_type; +}; + +#define _bfd_riscv_elf_tdata(abfd) \ + ((struct _bfd_riscv_elf_obj_tdata *) (abfd)->tdata.any) + +#define _bfd_riscv_elf_local_got_tls_type(abfd) \ + (_bfd_riscv_elf_tdata (abfd)->local_got_tls_type) + +#define _bfd_riscv_elf_tls_type(abfd, h, symndx) \ + (*((h) != NULL ? &riscv_elf_hash_entry(h)->tls_type \ + : &_bfd_riscv_elf_local_got_tls_type (abfd) [symndx])) + +#define is_riscv_elf(bfd) \ + (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ + && elf_tdata (bfd) != NULL \ + && elf_object_id (bfd) == RISCV_ELF_DATA) + +#include "elf/common.h" +#include "elf/internal.h" + +struct riscv_elf_link_hash_table +{ + struct elf_link_hash_table elf; + + /* Short-cuts to get to dynamic linker sections. */ + asection *sdynbss; + asection *srelbss; + asection *sdyntdata; + + /* Small local sym to section mapping cache. */ + struct sym_cache sym_cache; +}; + + +/* Get the RISC-V ELF linker hash table from a link_info structure. */ +#define riscv_elf_hash_table(p) \ + (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ + == RISCV_ELF_DATA ? ((struct riscv_elf_link_hash_table *) ((p)->hash)) : NULL) + +static void +riscv_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) +{ + cache_ptr->howto = riscv_elf_rtype_to_howto (ELFNN_R_TYPE (dst->r_info)); +} + +static void +riscv_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel) +{ + const struct elf_backend_data *bed; + bfd_byte *loc; + + bed = get_elf_backend_data (abfd); + loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela); + bed->s->swap_reloca_out (abfd, rel, loc); +} + +/* PLT/GOT stuff */ + +#define PLT_HEADER_INSNS 8 +#define PLT_ENTRY_INSNS 4 +#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4) +#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4) + +#define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES + +#define GOTPLT_HEADER_SIZE (2 * GOT_ENTRY_SIZE) + +#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset) + +static bfd_vma +riscv_elf_got_plt_val (bfd_vma plt_index, struct bfd_link_info *info) +{ + return sec_addr (riscv_elf_hash_table (info)->elf.sgotplt) + + GOTPLT_HEADER_SIZE + (plt_index * GOT_ENTRY_SIZE); +} + +#if ARCH_SIZE == 32 +# define MATCH_LREG MATCH_LW +#else +# define MATCH_LREG MATCH_LD +#endif + +/* The format of the first PLT entry. */ + +static void +riscv_make_plt0_entry(bfd_vma gotplt_addr, bfd_vma addr, uint32_t *entry) +{ + /* auipc t2, %hi(.got.plt) + sub t1, t1, t0 # shifted .got.plt offset + hdr size + 12 + l[w|d] t3, %lo(.got.plt)(t2) # _dl_runtime_resolve + addi t1, t1, -(hdr size + 12) # shifted .got.plt offset + addi t0, t2, %lo(.got.plt) # &.got.plt + srli t1, t1, log2(16/PTRSIZE) # .got.plt offset + l[w|d] t0, PTRSIZE(t0) # link map + jr t3 */ + + entry[0] = RISCV_UTYPE (AUIPC, X_T2, RISCV_PCREL_HIGH_PART (gotplt_addr, addr)); + entry[1] = RISCV_RTYPE (SUB, X_T1, X_T1, X_T0); + entry[2] = RISCV_ITYPE (LREG, X_T3, X_T2, RISCV_PCREL_LOW_PART (gotplt_addr, addr)); + entry[3] = RISCV_ITYPE (ADDI, X_T1, X_T1, -(PLT_HEADER_SIZE + 12)); + entry[4] = RISCV_ITYPE (ADDI, X_T0, X_T2, RISCV_PCREL_LOW_PART (gotplt_addr, addr)); + entry[5] = RISCV_ITYPE (SRLI, X_T1, X_T1, 4 - RISCV_ELF_LOG_WORD_BYTES); + entry[6] = RISCV_ITYPE (LREG, X_T0, X_T0, RISCV_ELF_WORD_BYTES); + entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0); +} + +/* The format of subsequent PLT entries. */ + +static void +riscv_make_plt_entry(bfd_vma got_address, bfd_vma addr, uint32_t *entry) +{ + /* auipc t1, %hi(.got.plt entry) + l[w|d] t0, %lo(.got.plt entry)(t1) + jalr t1, t0 + nop */ + + entry[0] = RISCV_UTYPE (AUIPC, X_T1, RISCV_PCREL_HIGH_PART (got_address, addr)); + entry[1] = RISCV_ITYPE (LREG, X_T0, X_T1, RISCV_PCREL_LOW_PART(got_address, addr)); + entry[2] = RISCV_ITYPE (JALR, X_T1, X_T0, 0); + entry[3] = RISCV_NOP; +} + +/* Create an entry in an RISC-V ELF linker hash table. */ + +static struct bfd_hash_entry * +link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, const char *string) +{ + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (entry == NULL) + { + entry = + bfd_hash_allocate (table, + sizeof (struct riscv_elf_link_hash_entry)); + if (entry == NULL) + return entry; + } + + /* Call the allocation method of the superclass. */ + entry = _bfd_elf_link_hash_newfunc (entry, table, string); + if (entry != NULL) + { + struct riscv_elf_link_hash_entry *eh; + + eh = (struct riscv_elf_link_hash_entry *) entry; + eh->dyn_relocs = NULL; + eh->tls_type = GOT_UNKNOWN; + } + + return entry; +} + +/* Create a RISC-V ELF linker hash table. */ + +static struct bfd_link_hash_table * +riscv_elf_link_hash_table_create (bfd *abfd) +{ + struct riscv_elf_link_hash_table *ret; + bfd_size_type amt = sizeof (struct riscv_elf_link_hash_table); + + ret = (struct riscv_elf_link_hash_table *) bfd_zmalloc (amt); + if (ret == NULL) + return NULL; + + if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc, + sizeof (struct riscv_elf_link_hash_entry), + RISCV_ELF_DATA)) + { + free (ret); + return NULL; + } + + return &ret->elf.root; +} + +/* Create the .got section. */ + +static bfd_boolean +riscv_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) +{ + flagword flags; + asection *s, *s_got; + struct elf_link_hash_entry *h; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + struct elf_link_hash_table *htab = elf_hash_table (info); + + /* This function may be called more than once. */ + s = bfd_get_linker_section (abfd, ".got"); + if (s != NULL) + return TRUE; + + flags = bed->dynamic_sec_flags; + + s = bfd_make_section_anyway_with_flags (abfd, + (bed->rela_plts_and_copies_p + ? ".rela.got" : ".rel.got"), + (bed->dynamic_sec_flags + | SEC_READONLY)); + if (s == NULL + || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) + return FALSE; + htab->srelgot = s; + + s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags); + if (s == NULL + || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) + return FALSE; + htab->sgot = s; + + /* The first bit of the global offset table is the header. */ + s->size += bed->got_header_size; + + if (bed->want_got_plt) + { + s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); + if (s == NULL + || !bfd_set_section_alignment (abfd, s, + bed->s->log_file_align)) + return FALSE; + htab->sgotplt = s; + + /* Reserve room for the header. */ + s->size += GOTPLT_HEADER_SIZE; + } + + if (bed->want_got_sym) + { + /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got + section. We don't do this in the linker script because we don't want + to define the symbol if we are not creating a global offset + table. */ + h = _bfd_elf_define_linkage_sym (abfd, info, s_got, + "_GLOBAL_OFFSET_TABLE_"); + elf_hash_table (info)->hgot = h; + if (h == NULL) + return FALSE; + } + + return TRUE; +} + +/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and + .rela.bss sections in DYNOBJ, and set up shortcuts to them in our + hash table. */ + +static bfd_boolean +riscv_elf_create_dynamic_sections (bfd *dynobj, + struct bfd_link_info *info) +{ + struct riscv_elf_link_hash_table *htab; + + htab = riscv_elf_hash_table (info); + BFD_ASSERT (htab != NULL); + + if (!riscv_elf_create_got_section (dynobj, info)) + return FALSE; + + if (!_bfd_elf_create_dynamic_sections (dynobj, info)) + return FALSE; + + htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); + if (!info->shared) + { + htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss"); + htab->sdyntdata = + bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn", + SEC_ALLOC | SEC_THREAD_LOCAL); + } + + if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss + || (!info->shared && (!htab->srelbss || !htab->sdyntdata))) + abort (); + + return TRUE; +} + +/* Copy the extra info we tack onto an elf_link_hash_entry. */ + +static void +riscv_elf_copy_indirect_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *dir, + struct elf_link_hash_entry *ind) +{ + struct riscv_elf_link_hash_entry *edir, *eind; + + edir = (struct riscv_elf_link_hash_entry *) dir; + eind = (struct riscv_elf_link_hash_entry *) ind; + + if (eind->dyn_relocs != NULL) + { + if (edir->dyn_relocs != NULL) + { + struct riscv_elf_dyn_relocs **pp; + struct riscv_elf_dyn_relocs *p; + + /* Add reloc counts against the indirect sym to the direct sym + list. Merge any entries against the same section. */ + for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) + { + struct riscv_elf_dyn_relocs *q; + + for (q = edir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = edir->dyn_relocs; + } + + edir->dyn_relocs = eind->dyn_relocs; + eind->dyn_relocs = NULL; + } + + if (ind->root.type == bfd_link_hash_indirect + && dir->got.refcount <= 0) + { + edir->tls_type = eind->tls_type; + eind->tls_type = GOT_UNKNOWN; + } + _bfd_elf_link_hash_copy_indirect (info, dir, ind); +} + +static bfd_boolean +riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h, + unsigned long symndx, char tls_type) +{ + char *new_tls_type = &_bfd_riscv_elf_tls_type (abfd, h, symndx); + *new_tls_type |= tls_type; + if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL)) + { + (*_bfd_error_handler) + (_("%B: `%s' accessed both as normal and thread local symbol"), + abfd, h ? h->root.root.string : ""); + return FALSE; + } + return TRUE; +} + +static bfd_boolean +riscv_elf_record_got_reference (bfd *abfd, struct bfd_link_info *info, + struct elf_link_hash_entry *h, long symndx) +{ + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + + if (htab->elf.sgot == NULL) + { + if (!riscv_elf_create_got_section (htab->elf.dynobj, info)) + return FALSE; + } + + if (h != NULL) + { + h->got.refcount += 1; + return TRUE; + } + + /* This is a global offset table entry for a local symbol. */ + if (elf_local_got_refcounts (abfd) == NULL) + { + bfd_size_type size = symtab_hdr->sh_info * (sizeof (bfd_vma) + 1); + if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size))) + return FALSE; + _bfd_riscv_elf_local_got_tls_type (abfd) + = (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info); + } + elf_local_got_refcounts (abfd) [symndx] += 1; + + return TRUE; +} + +static bfd_boolean +bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h) +{ + (*_bfd_error_handler) + (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), + abfd, riscv_elf_rtype_to_howto (r_type)->name, + h != NULL ? h->root.root.string : "a local symbol"); + bfd_set_error (bfd_error_bad_value); + return FALSE; +} +/* Look through the relocs for a section during the first phase, and + allocate space in the global offset table or procedure linkage + table. */ + +static bfd_boolean +riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, + asection *sec, const Elf_Internal_Rela *relocs) +{ + struct riscv_elf_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel; + asection *sreloc = NULL; + + if (info->relocatable) + return TRUE; + + htab = riscv_elf_hash_table (info); + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + + for (rel = relocs; rel < relocs + sec->reloc_count; rel++) + { + unsigned int r_type; + unsigned long r_symndx; + struct elf_link_hash_entry *h; + + r_symndx = ELFNN_R_SYM (rel->r_info); + r_type = ELFNN_R_TYPE (rel->r_info); + + if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) + { + (*_bfd_error_handler) (_("%B: bad symbol index: %d"), + abfd, r_symndx); + return FALSE; + } + + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* PR15323, ref flags aren't set for references in the same + object. */ + h->root.non_ir_ref = 1; + } + + switch (r_type) + { + case R_RISCV_TLS_GD_HI20: + if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx) + || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_GD)) + return FALSE; + break; + + case R_RISCV_TLS_GOT_HI20: + if (info->shared) + info->flags |= DF_STATIC_TLS; + if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx) + || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE)) + return FALSE; + break; + + case R_RISCV_GOT_HI20: + if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx) + || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_NORMAL)) + return FALSE; + break; + + case R_RISCV_CALL_PLT: + /* This symbol requires a procedure linkage table entry. We + actually build the entry in adjust_dynamic_symbol, + because this might be a case of linking PIC code without + linking in any dynamic objects, in which case we don't + need to generate a procedure linkage table after all. */ + + if (h != NULL) + { + h->needs_plt = 1; + h->plt.refcount += 1; + } + break; + + case R_RISCV_CALL: + case R_RISCV_JAL: + case R_RISCV_BRANCH: + case R_RISCV_PCREL_HI20: + /* In shared libs, these relocs are known to bind locally. */ + if (info->shared) + break; + goto static_reloc; + + case R_RISCV_TPREL_HI20: + if (!info->executable) + return bad_static_reloc (abfd, r_type, h); + if (h != NULL) + riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE); + goto static_reloc; + + case R_RISCV_HI20: + if (info->shared) + return bad_static_reloc (abfd, r_type, h); + /* Fall through. */ + + case R_RISCV_COPY: + case R_RISCV_JUMP_SLOT: + case R_RISCV_RELATIVE: + case R_RISCV_64: + case R_RISCV_32: + /* Fall through. */ + + static_reloc: + if (h != NULL) + h->non_got_ref = 1; + + if (h != NULL && !info->shared) + { + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; + } + + /* If we are creating a shared library, and this is a reloc + against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc + into the shared library. However, if we are linking with + -Bsymbolic, we do not need to copy a reloc against a + global symbol which is defined in an object we are + including in the link (i.e., DEF_REGULAR is set). At + this point we have not seen all the input files, so it is + possible that DEF_REGULAR is not set now but will be set + later (it is never cleared). In case of a weak definition, + DEF_REGULAR may be cleared later by a strong definition in + a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash + table entry. A similar situation occurs when creating + shared libraries and symbol visibility changes render the + symbol local. + + If on the other hand, we are creating an executable, we + may need to keep relocations for symbols satisfied by a + dynamic library if we manage to avoid copy relocs for the + symbol. */ + if ((info->shared + && (sec->flags & SEC_ALLOC) != 0 + && (! riscv_elf_rtype_to_howto (r_type)->pc_relative + || (h != NULL + && (! info->symbolic + || h->root.type == bfd_link_hash_defweak + || !h->def_regular)))) + || (!info->shared + && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak + || !h->def_regular))) + { + struct riscv_elf_dyn_relocs *p; + struct riscv_elf_dyn_relocs **head; + + /* When creating a shared object, we must copy these + relocs into the output file. We create a reloc + section in dynobj and make room for the reloc. */ + if (sreloc == NULL) + { + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, RISCV_ELF_LOG_WORD_BYTES, + abfd, /*rela?*/ TRUE); + + if (sreloc == NULL) + return FALSE; + } + + /* If this is a global symbol, we count the number of + relocations we need for this symbol. */ + if (h != NULL) + head = &((struct riscv_elf_link_hash_entry *) h)->dyn_relocs; + else + { + /* Track dynamic relocs needed for local syms too. + We really need local syms available to do this + easily. Oh well. */ + + asection *s; + void *vpp; + Elf_Internal_Sym *isym; + + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + + vpp = &elf_section_data (s)->local_dynrel; + head = (struct riscv_elf_dyn_relocs **) vpp; + } + + p = *head; + if (p == NULL || p->sec != sec) + { + bfd_size_type amt = sizeof *p; + p = ((struct riscv_elf_dyn_relocs *) + bfd_alloc (htab->elf.dynobj, amt)); + if (p == NULL) + return FALSE; + p->next = *head; + *head = p; + p->sec = sec; + p->count = 0; + p->pc_count = 0; + } + + p->count += 1; + p->pc_count += riscv_elf_rtype_to_howto (r_type)->pc_relative; + } + + break; + + case R_RISCV_GNU_VTINHERIT: + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return FALSE; + break; + + case R_RISCV_GNU_VTENTRY: + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return FALSE; + break; + + default: + break; + } + } + + return TRUE; +} + +static asection * +riscv_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + if (h != NULL) + switch (ELFNN_R_TYPE (rel->r_info)) + { + case R_RISCV_GNU_VTINHERIT: + case R_RISCV_GNU_VTENTRY: + return NULL; + } + + return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); +} + +/* Update the got entry reference counts for the section being removed. */ +static bfd_boolean +riscv_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, + asection *sec, const Elf_Internal_Rela *relocs) +{ + const Elf_Internal_Rela *rel, *relend; + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd); + struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); + bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd); + + if (info->relocatable) + return TRUE; + + elf_section_data (sec)->local_dynrel = NULL; + + for (rel = relocs, relend = relocs + sec->reloc_count; rel < relend; rel++) + { + unsigned long r_symndx; + struct elf_link_hash_entry *h = NULL; + + r_symndx = ELFNN_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + struct riscv_elf_link_hash_entry *eh; + struct riscv_elf_dyn_relocs **pp; + struct riscv_elf_dyn_relocs *p; + + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + eh = (struct riscv_elf_link_hash_entry *) h; + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) + if (p->sec == sec) + { + /* Everything must go for SEC. */ + *pp = p->next; + break; + } + } + + switch (ELFNN_R_TYPE (rel->r_info)) + { + case R_RISCV_GOT_HI20: + case R_RISCV_TLS_GOT_HI20: + case R_RISCV_TLS_GD_HI20: + if (h != NULL) + { + if (h->got.refcount > 0) + h->got.refcount--; + } + else + { + if (local_got_refcounts && + local_got_refcounts[r_symndx] > 0) + local_got_refcounts[r_symndx]--; + } + break; + + case R_RISCV_HI20: + case R_RISCV_PCREL_HI20: + case R_RISCV_COPY: + case R_RISCV_JUMP_SLOT: + case R_RISCV_RELATIVE: + case R_RISCV_64: + case R_RISCV_32: + case R_RISCV_BRANCH: + case R_RISCV_CALL: + case R_RISCV_JAL: + if (info->shared) + break; + /* Fall through. */ + + case R_RISCV_CALL_PLT: + if (h != NULL) + { + if (h->plt.refcount > 0) + h->plt.refcount--; + } + break; + + default: + break; + } + } + + return TRUE; +} + +/* Adjust a symbol defined by a dynamic object and referenced by a + regular object. The current definition is in some section of the + dynamic object, but we're not including those sections. We have to + change the definition to something the rest of the link can + understand. */ + +static bfd_boolean +riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + struct riscv_elf_link_hash_table *htab; + struct riscv_elf_link_hash_entry * eh; + struct riscv_elf_dyn_relocs *p; + bfd *dynobj; + asection *s; + + htab = riscv_elf_hash_table (info); + BFD_ASSERT (htab != NULL); + + dynobj = htab->elf.dynobj; + + /* Make sure we know what is going on here. */ + BFD_ASSERT (dynobj != NULL + && (h->needs_plt + || h->type == STT_GNU_IFUNC + || h->u.weakdef != NULL + || (h->def_dynamic + && h->ref_regular + && !h->def_regular))); + + /* If this is a function, put it in the procedure linkage table. We + will fill in the contents of the procedure linkage table later + (although we could actually do it here). */ + if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt) + { + if (h->plt.refcount <= 0 + || SYMBOL_CALLS_LOCAL (info, h) + || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + && h->root.type == bfd_link_hash_undefweak)) + { + /* This case can occur if we saw a R_RISCV_CALL_PLT reloc in an + input file, but the symbol was never referred to by a dynamic + object, or if all references were garbage collected. In such + a case, we don't actually need to build a PLT entry. */ + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + + return TRUE; + } + else + h->plt.offset = (bfd_vma) -1; + + /* If this is a weak symbol, and there is a real definition, the + processor independent code will have arranged for us to see the + real definition first, and we can just use the same value. */ + if (h->u.weakdef != NULL) + { + BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined + || h->u.weakdef->root.type == bfd_link_hash_defweak); + h->root.u.def.section = h->u.weakdef->root.u.def.section; + h->root.u.def.value = h->u.weakdef->root.u.def.value; + return TRUE; + } + + /* This is a reference to a symbol defined by a dynamic object which + is not a function. */ + + /* If we are creating a shared library, we must presume that the + only references to the symbol are via the global offset table. + For such cases we need not do anything here; the relocations will + be handled correctly by relocate_section. */ + if (info->shared) + return TRUE; + + /* If there are no references to this symbol that do not use the + GOT, we don't need to generate a copy reloc. */ + if (!h->non_got_ref) + return TRUE; + + /* If -z nocopyreloc was given, we won't generate them either. */ + if (info->nocopyreloc) + { + h->non_got_ref = 0; + return TRUE; + } + + eh = (struct riscv_elf_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + s = p->sec->output_section; + if (s != NULL && (s->flags & SEC_READONLY) != 0) + break; + } + + /* If we didn't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ + if (p == NULL) + { + h->non_got_ref = 0; + return TRUE; + } + + /* We must allocate the symbol in our .dynbss section, which will + become part of the .bss section of the executable. There will be + an entry for this symbol in the .dynsym section. The dynamic + object will contain position independent code, so all references + from the dynamic object to this symbol will go through the global + offset table. The dynamic linker will use the .dynsym entry to + determine the address it must put in the global offset table, so + both the dynamic object and the regular object will refer to the + same memory location for the variable. */ + + /* We must generate a R_RISCV_COPY reloc to tell the dynamic linker + to copy the initial value out of the dynamic object and into the + runtime process image. We need to remember the offset into the + .rel.bss section we are going to use. */ + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) + { + htab->srelbss->size += sizeof (ElfNN_External_Rela); + h->needs_copy = 1; + } + + if (eh->tls_type & ~GOT_NORMAL) + return _bfd_elf_adjust_dynamic_copy (h, htab->sdyntdata); + + return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss); +} + +/* Allocate space in .plt, .got and associated reloc sections for + dynamic relocs. */ + +static bfd_boolean +allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) +{ + struct bfd_link_info *info; + struct riscv_elf_link_hash_table *htab; + struct riscv_elf_link_hash_entry *eh; + struct riscv_elf_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_indirect) + return TRUE; + + info = (struct bfd_link_info *) inf; + htab = riscv_elf_hash_table (info); + BFD_ASSERT (htab != NULL); + + if (htab->elf.dynamic_sections_created + && h->plt.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) + { + asection *s = htab->elf.splt; + + if (s->size == 0) + s->size = PLT_HEADER_SIZE; + + h->plt.offset = s->size; + + /* Make room for this entry. */ + s->size += PLT_ENTRY_SIZE; + + /* We also need to make an entry in the .got.plt section. */ + htab->elf.sgotplt->size += GOT_ENTRY_SIZE; + + /* We also need to make an entry in the .rela.plt section. */ + htab->elf.srelplt->size += sizeof (ElfNN_External_Rela); + + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && !h->def_regular) + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->needs_plt = 0; + } + + if (h->got.refcount > 0) + { + asection *s; + bfd_boolean dyn; + int tls_type = riscv_elf_hash_entry(h)->tls_type; + + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + s = htab->elf.sgot; + h->got.offset = s->size; + dyn = htab->elf.dynamic_sections_created; + if (tls_type & (GOT_TLS_GD | GOT_TLS_IE)) + { + /* TLS_GD needs two dynamic relocs and two GOT slots. */ + if (tls_type & GOT_TLS_GD) + { + s->size += 2 * RISCV_ELF_WORD_BYTES; + htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); + } + + /* TLS_IE needs one dynamic reloc and one GOT slot. */ + if (tls_type & GOT_TLS_IE) + { + s->size += RISCV_ELF_WORD_BYTES; + htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); + } + } + else + { + s->size += RISCV_ELF_WORD_BYTES; + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)) + htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); + } + } + else + h->got.offset = (bfd_vma) -1; + + eh = (struct riscv_elf_link_hash_entry *) h; + if (eh->dyn_relocs == NULL) + return TRUE; + + /* In the shared -Bsymbolic case, discard space allocated for + dynamic pc-relative relocs against symbols which turn out to be + defined in regular objects. For the normal shared case, discard + space for pc-relative relocs that have become local due to symbol + visibility changes. */ + + if (info->shared) + { + if (SYMBOL_CALLS_LOCAL (info, h)) + { + struct riscv_elf_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + } + + /* Also discard relocs on undefined weak syms with non-default + visibility. */ + if (eh->dyn_relocs != NULL + && h->root.type == bfd_link_hash_undefweak) + { + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + eh->dyn_relocs = NULL; + + /* Make sure undefined weak symbols are output as a dynamic + symbol in PIEs. */ + else if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + } + } + else + { + /* For the non-shared case, discard space for relocs against + symbols which turn out to need copy relocs or are not + dynamic. */ + + if (!h->non_got_ref + && ((h->def_dynamic + && !h->def_regular) + || (htab->elf.dynamic_sections_created + && (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined)))) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + + /* If that succeeded, we know we'll be keeping all the + relocs. */ + if (h->dynindx != -1) + goto keep; + } + + eh->dyn_relocs = NULL; + + keep: ; + } + + /* Finally, allocate space. */ + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *sreloc = elf_section_data (p->sec)->sreloc; + sreloc->size += p->count * sizeof (ElfNN_External_Rela); + } + + return TRUE; +} + +/* Find any dynamic relocs that apply to read-only sections. */ + +static bfd_boolean +readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +{ + struct riscv_elf_link_hash_entry *eh; + struct riscv_elf_dyn_relocs *p; + + eh = (struct riscv_elf_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + { + ((struct bfd_link_info *) inf)->flags |= DF_TEXTREL; + + /* Short-circuit the traversal. */ + return FALSE; + } + } + return TRUE; +} + +static bfd_boolean +riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) +{ + struct riscv_elf_link_hash_table *htab; + bfd *dynobj; + asection *s; + bfd *ibfd; + + htab = riscv_elf_hash_table (info); + BFD_ASSERT (htab != NULL); + dynobj = htab->elf.dynobj; + BFD_ASSERT (dynobj != NULL); + + if (elf_hash_table (info)->dynamic_sections_created) + { + /* Set the contents of the .interp section to the interpreter. */ + if (info->executable) + { + s = bfd_get_linker_section (dynobj, ".interp"); + BFD_ASSERT (s != NULL); + s->size = strlen (ELFNN_DYNAMIC_INTERPRETER) + 1; + s->contents = (unsigned char *) ELFNN_DYNAMIC_INTERPRETER; + } + } + + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + { + bfd_signed_vma *local_got; + bfd_signed_vma *end_local_got; + char *local_tls_type; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; + asection *srel; + + if (! is_riscv_elf (ibfd)) + continue; + + for (s = ibfd->sections; s != NULL; s = s->next) + { + struct riscv_elf_dyn_relocs *p; + + for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) + { + if (!bfd_is_abs_section (p->sec) + && bfd_is_abs_section (p->sec->output_section)) + { + /* Input section has been discarded, either because + it is a copy of a linkonce section or due to + linker script /DISCARD/, so we'll be discarding + the relocs too. */ + } + else if (p->count != 0) + { + srel = elf_section_data (p->sec)->sreloc; + srel->size += p->count * sizeof (ElfNN_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; + } + } + } + + local_got = elf_local_got_refcounts (ibfd); + if (!local_got) + continue; + + symtab_hdr = &elf_symtab_hdr (ibfd); + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; + local_tls_type = _bfd_riscv_elf_local_got_tls_type (ibfd); + s = htab->elf.sgot; + srel = htab->elf.srelgot; + for (; local_got < end_local_got; ++local_got, ++local_tls_type) + { + if (*local_got > 0) + { + *local_got = s->size; + s->size += RISCV_ELF_WORD_BYTES; + if (*local_tls_type & GOT_TLS_GD) + s->size += RISCV_ELF_WORD_BYTES; + if (info->shared + || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))) + srel->size += sizeof (ElfNN_External_Rela); + } + else + *local_got = (bfd_vma) -1; + } + } + + /* Allocate global sym .plt and .got entries, and space for global + sym dynamic relocs. */ + elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); + + if (htab->elf.sgotplt) + { + struct elf_link_hash_entry *got; + got = elf_link_hash_lookup (elf_hash_table (info), + "_GLOBAL_OFFSET_TABLE_", + FALSE, FALSE, FALSE); + + /* Don't allocate .got.plt section if there are no GOT nor PLT + entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */ + if ((got == NULL + || !got->ref_regular_nonweak) + && (htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE) + && (htab->elf.splt == NULL + || htab->elf.splt->size == 0) + && (htab->elf.sgot == NULL + || (htab->elf.sgot->size + == get_elf_backend_data (output_bfd)->got_header_size))) + htab->elf.sgotplt->size = 0; + } + + /* The check_relocs and adjust_dynamic_symbol entry points have + determined the sizes of the various dynamic sections. Allocate + memory for them. */ + for (s = dynobj->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LINKER_CREATED) == 0) + continue; + + if (s == htab->elf.splt + || s == htab->elf.sgot + || s == htab->elf.sgotplt + || s == htab->sdynbss) + { + /* Strip this section if we don't need it; see the + comment below. */ + } + else if (strncmp (s->name, ".rela", 5) == 0) + { + if (s->size != 0) + { + /* We use the reloc_count field as a counter if we need + to copy relocs into the output file. */ + s->reloc_count = 0; + } + } + else + { + /* It's not one of our sections. */ + continue; + } + + if (s->size == 0) + { + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + s->flags |= SEC_EXCLUDE; + continue; + } + + if ((s->flags & SEC_HAS_CONTENTS) == 0) + continue; + + /* Allocate memory for the section contents. Zero the memory + for the benefit of .rela.plt, which has 4 unused entries + at the beginning, and we don't want garbage. */ + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); + if (s->contents == NULL) + return FALSE; + } + + if (elf_hash_table (info)->dynamic_sections_created) + { + /* Add some entries to the .dynamic section. We fill in the + values later, in riscv_elf_finish_dynamic_sections, but we + must add the entries now so that we get the correct size for + the .dynamic section. The DT_DEBUG entry is filled in by the + dynamic linker and used by the debugger. */ +#define add_dynamic_entry(TAG, VAL) \ + _bfd_elf_add_dynamic_entry (info, TAG, VAL) + + if (info->executable) + { + if (!add_dynamic_entry (DT_DEBUG, 0)) + return FALSE; + } + + if (htab->elf.srelplt->size != 0) + { + if (!add_dynamic_entry (DT_PLTGOT, 0) + || !add_dynamic_entry (DT_PLTRELSZ, 0) + || !add_dynamic_entry (DT_PLTREL, DT_RELA) + || !add_dynamic_entry (DT_JMPREL, 0)) + return FALSE; + } + + if (!add_dynamic_entry (DT_RELA, 0) + || !add_dynamic_entry (DT_RELASZ, 0) + || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela))) + return FALSE; + + /* If any dynamic relocs apply to a read-only section, + then we need a DT_TEXTREL entry. */ + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + + if (info->flags & DF_TEXTREL) + { + if (!add_dynamic_entry (DT_TEXTREL, 0)) + return FALSE; + } + } +#undef add_dynamic_entry + + return TRUE; +} + +#define TP_OFFSET 0 +#define DTP_OFFSET 0x800 + +/* Return the relocation value for a TLS dtp-relative reloc. */ + +static bfd_vma +dtpoff (struct bfd_link_info *info, bfd_vma address) +{ + /* If tls_sec is NULL, we should have signalled an error already. */ + if (elf_hash_table (info)->tls_sec == NULL) + return 0; + return address - elf_hash_table (info)->tls_sec->vma - DTP_OFFSET; +} + +/* Return the relocation value for a static TLS tp-relative relocation. */ + +static bfd_vma +tpoff (struct bfd_link_info *info, bfd_vma address) +{ + /* If tls_sec is NULL, we should have signalled an error already. */ + if (elf_hash_table (info)->tls_sec == NULL) + return 0; + return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET; +} + +/* Return the global pointer's value, or 0 if it is not in use. */ + +static bfd_vma +riscv_global_pointer_value (struct bfd_link_info *info) +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE); + if (h == NULL || h->type != bfd_link_hash_defined) + return 0; + + return h->u.def.value + sec_addr (h->u.def.section); +} + +/* Emplace a static relocation. */ + +static bfd_reloc_status_type +perform_relocation (const reloc_howto_type *howto, + const Elf_Internal_Rela *rel, + bfd_vma value, + asection *input_section, + bfd *input_bfd, + bfd_byte *contents) +{ + if (howto->pc_relative) + value -= sec_addr (input_section) + rel->r_offset; + value += rel->r_addend; + + switch (ELFNN_R_TYPE (rel->r_info)) + { + case R_RISCV_HI20: + case R_RISCV_TPREL_HI20: + case R_RISCV_PCREL_HI20: + case R_RISCV_GOT_HI20: + case R_RISCV_TLS_GOT_HI20: + case R_RISCV_TLS_GD_HI20: + value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)); + break; + + case R_RISCV_LO12_I: + case R_RISCV_TPREL_LO12_I: + case R_RISCV_PCREL_LO12_I: + value = ENCODE_ITYPE_IMM (value); + break; + + case R_RISCV_LO12_S: + case R_RISCV_TPREL_LO12_S: + case R_RISCV_PCREL_LO12_S: + value = ENCODE_STYPE_IMM (value); + break; + + case R_RISCV_CALL: + case R_RISCV_CALL_PLT: + if (!VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))) + return bfd_reloc_overflow; + value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)) + | (ENCODE_ITYPE_IMM (value) << 32); + break; + + case R_RISCV_JAL: + if (!VALID_UJTYPE_IMM (value)) + return bfd_reloc_overflow; + value = ENCODE_UJTYPE_IMM (value); + break; + + case R_RISCV_BRANCH: + if (!VALID_SBTYPE_IMM (value)) + return bfd_reloc_overflow; + value = ENCODE_SBTYPE_IMM (value); + break; + + case R_RISCV_32: + case R_RISCV_64: + case R_RISCV_ADD8: + case R_RISCV_ADD16: + case R_RISCV_ADD32: + case R_RISCV_ADD64: + case R_RISCV_SUB8: + case R_RISCV_SUB16: + case R_RISCV_SUB32: + case R_RISCV_SUB64: + case R_RISCV_TLS_DTPREL32: + case R_RISCV_TLS_DTPREL64: + break; + + default: + return bfd_reloc_notsupported; + } + + bfd_vma word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset); + word = (word & ~howto->dst_mask) | (value & howto->dst_mask); + bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset); + + return bfd_reloc_ok; +} + +/* Remember all PC-relative high-part relocs we've encountered to help us + later resolve the corresponding low-part relocs. */ + +typedef struct { + bfd_vma address; + bfd_vma value; +} riscv_pcrel_hi_reloc; + +typedef struct riscv_pcrel_lo_reloc { + asection *input_section; + struct bfd_link_info *info; + reloc_howto_type *howto; + const Elf_Internal_Rela *reloc; + bfd_vma addr; + const char *name; + bfd_byte *contents; + struct riscv_pcrel_lo_reloc *next; +} riscv_pcrel_lo_reloc; + +typedef struct { + htab_t hi_relocs; + riscv_pcrel_lo_reloc *lo_relocs; +} riscv_pcrel_relocs; + +static hashval_t +riscv_pcrel_reloc_hash (const void *entry) +{ + const riscv_pcrel_hi_reloc *e = entry; + return (hashval_t)(e->address >> 2); +} + +static bfd_boolean +riscv_pcrel_reloc_eq (const void *entry1, const void *entry2) +{ + const riscv_pcrel_hi_reloc *e1 = entry1, *e2 = entry2; + return e1->address == e2->address; +} + +static bfd_boolean +riscv_init_pcrel_relocs (riscv_pcrel_relocs *p) +{ + + p->lo_relocs = NULL; + p->hi_relocs = htab_create (1024, riscv_pcrel_reloc_hash, + riscv_pcrel_reloc_eq, free); + return p->hi_relocs != NULL; +} + +static void +riscv_free_pcrel_relocs (riscv_pcrel_relocs *p) +{ + riscv_pcrel_lo_reloc *cur = p->lo_relocs; + while (cur != NULL) + { + riscv_pcrel_lo_reloc *next = cur->next; + free (cur); + cur = next; + } + + htab_delete (p->hi_relocs); +} + +static bfd_boolean +riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p, bfd_vma addr, bfd_vma value) +{ + riscv_pcrel_hi_reloc entry = {addr, value - addr}; + riscv_pcrel_hi_reloc **slot = + (riscv_pcrel_hi_reloc **) htab_find_slot (p->hi_relocs, &entry, INSERT); + BFD_ASSERT (*slot == NULL); + *slot = (riscv_pcrel_hi_reloc *) bfd_malloc (sizeof (riscv_pcrel_hi_reloc)); + if (*slot == NULL) + return FALSE; + **slot = entry; + return TRUE; +} + +static bfd_boolean +riscv_record_pcrel_lo_reloc (riscv_pcrel_relocs *p, + asection *input_section, + struct bfd_link_info *info, + reloc_howto_type *howto, + const Elf_Internal_Rela *reloc, + bfd_vma addr, + const char *name, + bfd_byte *contents) +{ + riscv_pcrel_lo_reloc *entry; + entry = (riscv_pcrel_lo_reloc *) bfd_malloc (sizeof (riscv_pcrel_lo_reloc)); + if (entry == NULL) + return FALSE; + *entry = (riscv_pcrel_lo_reloc) {input_section, info, howto, reloc, addr, + name, contents, p->lo_relocs}; + p->lo_relocs = entry; + return TRUE; +} + +static bfd_boolean +riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p) +{ + riscv_pcrel_lo_reloc *r; + for (r = p->lo_relocs; r != NULL; r = r->next) + { + bfd *input_bfd = r->input_section->owner; + riscv_pcrel_hi_reloc search = {r->addr, 0}; + riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search); + if (entry == NULL) + return ((*r->info->callbacks->reloc_overflow) + (r->info, NULL, r->name, r->howto->name, (bfd_vma) 0, + input_bfd, r->input_section, r->reloc->r_offset)); + + perform_relocation (r->howto, r->reloc, entry->value, r->input_section, + input_bfd, r->contents); + } + + return TRUE; +} + +/* Relocate a RISC-V ELF section. + + The RELOCATE_SECTION function is called by the new ELF backend linker + to handle the relocations for a section. + + The relocs are always passed as Rela structures. + + This function is responsible for adjusting the section contents as + necessary, and (if generating a relocatable output file) adjusting + the reloc addend as necessary. + + This function does not have to worry about setting the reloc + address or the reloc symbol index. + + LOCAL_SYMS is a pointer to the swapped in local symbols. + + LOCAL_SECTIONS is an array giving the section in the input file + corresponding to the st_shndx field of each local symbol. + + The global hash table entry for the global symbols can be found + via elf_sym_hashes (input_bfd). + + When generating relocatable output, this function must handle + STB_LOCAL/STT_SECTION symbols specially. The output symbol is + going to be the section symbol corresponding to the output + section, which means that the addend must be adjusted + accordingly. */ + +static bfd_boolean +riscv_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, + bfd *input_bfd, asection *input_section, + bfd_byte *contents, Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) +{ + Elf_Internal_Rela *rel; + Elf_Internal_Rela *relend; + riscv_pcrel_relocs pcrel_relocs; + bfd_boolean ret = FALSE; + asection *sreloc = elf_section_data (input_section)->sreloc; + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd); + struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); + bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd); + + if (!riscv_init_pcrel_relocs (&pcrel_relocs)) + return FALSE; + + relend = relocs + input_section->reloc_count; + for (rel = relocs; rel < relend; rel++) + { + unsigned long r_symndx; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; + asection *sec; + bfd_vma relocation; + bfd_reloc_status_type r = bfd_reloc_ok; + const char *name; + bfd_vma off, ie_off; + bfd_boolean unresolved_reloc, is_ie = FALSE; + bfd_vma pc = sec_addr (input_section) + rel->r_offset; + int r_type = ELFNN_R_TYPE (rel->r_info), tls_type; + reloc_howto_type *howto = riscv_elf_rtype_to_howto (r_type); + const char *msg = NULL; + + if (r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY) + continue; + + /* This is a final link. */ + r_symndx = ELFNN_R_SYM (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + unresolved_reloc = FALSE; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + } + else + { + bfd_boolean warned; + /* bfd_boolean ignored; */ + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, warned /*, ignored */); + if (warned) + { + /* To avoid generating warning messages about truncated + relocations, set the relocation's address to be the same as + the start of this section. */ + if (input_section->output_section != NULL) + relocation = input_section->output_section->vma; + else + relocation = 0; + } + } + + if (sec != NULL && discarded_section (sec)) + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, 1, relend, howto, 0, contents); + + if (info->relocatable) + continue; + + if (h != NULL) + name = h->root.root.string; + else + { + name = (bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, sym->st_name)); + if (name == NULL || *name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + switch (r_type) + { + case R_RISCV_NONE: + case R_RISCV_TPREL_ADD: + case R_RISCV_COPY: + case R_RISCV_JUMP_SLOT: + case R_RISCV_RELATIVE: + /* These require nothing of us at all. */ + continue; + + case R_RISCV_BRANCH: + case R_RISCV_HI20: + /* These require no special handling beyond perform_relocation. */ + break; + + case R_RISCV_GOT_HI20: + if (h != NULL) + { + bfd_boolean dyn; + + off = h->got.offset; + BFD_ASSERT (off != (bfd_vma) -1); + dyn = elf_hash_table (info)->dynamic_sections_created; + + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) + || (info->shared + && SYMBOL_REFERENCES_LOCAL (info, h))) + { + /* This is actually a static link, or it is a + -Bsymbolic link and the symbol is defined + locally, or the symbol was forced to be local + because of a version file. We must initialize + this entry in the global offset table. Since the + offset must always be a multiple of the word size, + we use the least significant bit to record whether + we have initialized it already. + + When doing a dynamic link, we create a .rela.got + relocation entry to initialize the value. This + is done in the finish_dynamic_symbol routine. */ + if ((off & 1) != 0) + off &= ~1; + else + { + bfd_put_NN (output_bfd, relocation, + htab->elf.sgot->contents + off); + h->got.offset |= 1; + } + } + else + unresolved_reloc = FALSE; + } + else + { + BFD_ASSERT (local_got_offsets != NULL + && local_got_offsets[r_symndx] != (bfd_vma) -1); + + off = local_got_offsets[r_symndx]; + + /* The offset must always be a multiple of 8 on 64-bit. + We use the least significant bit to record + whether we have already processed this entry. */ + if ((off & 1) != 0) + off &= ~1; + else + { + if (info->shared) + { + asection *s; + Elf_Internal_Rela outrel; + + /* We need to generate a R_RISCV_RELATIVE reloc + for the dynamic linker. */ + s = htab->elf.srelgot; + BFD_ASSERT (s != NULL); + + outrel.r_offset = sec_addr (htab->elf.sgot) + off; + outrel.r_info = + ELFNN_R_INFO (0, R_RISCV_RELATIVE); + outrel.r_addend = relocation; + relocation = 0; + riscv_elf_append_rela (output_bfd, s, &outrel); + } + + bfd_put_NN (output_bfd, relocation, + htab->elf.sgot->contents + off); + local_got_offsets[r_symndx] |= 1; + } + } + relocation = sec_addr (htab->elf.sgot) + off; + if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, relocation)) + r = bfd_reloc_overflow; + break; + + case R_RISCV_ADD8: + case R_RISCV_ADD16: + case R_RISCV_ADD32: + case R_RISCV_ADD64: + { + bfd_vma old_value = bfd_get (howto->bitsize, input_bfd, + contents + rel->r_offset); + relocation = old_value + relocation; + } + break; + + case R_RISCV_SUB8: + case R_RISCV_SUB16: + case R_RISCV_SUB32: + case R_RISCV_SUB64: + { + bfd_vma old_value = bfd_get (howto->bitsize, input_bfd, + contents + rel->r_offset); + relocation = old_value - relocation; + } + break; + + case R_RISCV_CALL_PLT: + case R_RISCV_CALL: + case R_RISCV_JAL: + if (info->shared && h != NULL && h->plt.offset != MINUS_ONE) + { + /* Refer to the PLT entry. */ + relocation = sec_addr (htab->elf.splt) + h->plt.offset; + unresolved_reloc = FALSE; + } + break; + + case R_RISCV_TPREL_HI20: + relocation = tpoff (info, relocation); + break; + + case R_RISCV_TPREL_LO12_I: + case R_RISCV_TPREL_LO12_S: + relocation = tpoff (info, relocation); + if (VALID_ITYPE_IMM (relocation + rel->r_addend)) + { + /* We can use tp as the base register. */ + bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset); + insn &= ~(OP_MASK_RS1 << OP_SH_RS1); + insn |= X_TP << OP_SH_RS1; + bfd_put_32 (input_bfd, insn, contents + rel->r_offset); + } + break; + + case R_RISCV_LO12_I: + case R_RISCV_LO12_S: + { + bfd_vma gp = riscv_global_pointer_value (info); + bfd_boolean x0_base = VALID_ITYPE_IMM (relocation + rel->r_addend); + if (x0_base || VALID_ITYPE_IMM (relocation + rel->r_addend - gp)) + { + /* We can use x0 or gp as the base register. */ + bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset); + insn &= ~(OP_MASK_RS1 << OP_SH_RS1); + if (!x0_base) + { + rel->r_addend -= gp; + insn |= X_GP << OP_SH_RS1; + } + bfd_put_32 (input_bfd, insn, contents + rel->r_offset); + } + break; + } + + case R_RISCV_PCREL_HI20: + if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, + relocation + rel->r_addend)) + r = bfd_reloc_overflow; + break; + + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, input_section, info, + howto, rel, relocation, name, + contents)) + continue; + r = bfd_reloc_overflow; + break; + + case R_RISCV_TLS_DTPREL32: + case R_RISCV_TLS_DTPREL64: + relocation = dtpoff (info, relocation); + break; + + case R_RISCV_32: + case R_RISCV_64: + if ((input_section->flags & SEC_ALLOC) == 0) + break; + + if ((info->shared + && (h == NULL + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) + && (! howto->pc_relative + || !SYMBOL_CALLS_LOCAL (info, h))) + || (!info->shared + && h != NULL + && h->dynindx != -1 + && !h->non_got_ref + && ((h->def_dynamic + && !h->def_regular) + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined))) + { + Elf_Internal_Rela outrel; + bfd_boolean skip_static_relocation, skip_dynamic_relocation; + + /* When generating a shared object, these relocations + are copied into the output file to be resolved at run + time. */ + + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + skip_static_relocation = outrel.r_offset != (bfd_vma) -2; + skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2; + outrel.r_offset += sec_addr (input_section); + + if (skip_dynamic_relocation) + memset (&outrel, 0, sizeof outrel); + else if (h != NULL && h->dynindx != -1 + && !(info->shared + && SYMBOLIC_BIND (info, h) + && h->def_regular)) + { + outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); + outrel.r_addend = rel->r_addend; + } + else + { + outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; + } + + riscv_elf_append_rela (output_bfd, sreloc, &outrel); + if (skip_static_relocation) + continue; + } + break; + + case R_RISCV_TLS_GOT_HI20: + is_ie = TRUE; + /* Fall through. */ + + case R_RISCV_TLS_GD_HI20: + if (h != NULL) + { + off = h->got.offset; + h->got.offset |= 1; + } + else + { + off = local_got_offsets[r_symndx]; + local_got_offsets[r_symndx] |= 1; + } + + tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx); + BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD)); + /* If this symbol is referenced by both GD and IE TLS, the IE + reference's GOT slot follows the GD reference's slots. */ + ie_off = 0; + if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) + ie_off = 2 * GOT_ENTRY_SIZE; + + if ((off & 1) != 0) + off &= ~1; + else + { + Elf_Internal_Rela outrel; + int indx = 0; + bfd_boolean need_relocs = FALSE; + + if (htab->elf.srelgot == NULL) + abort (); + + if (h != NULL) + { + bfd_boolean dyn; + dyn = htab->elf.dynamic_sections_created; + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) + && (!info->shared + || !SYMBOL_REFERENCES_LOCAL (info, h))) + { + indx = h->dynindx; + } + } + + /* The GOT entries have not been initialized yet. Do it + now, and emit any relocations. */ + if ((info->shared || indx != 0) + && (h == NULL + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) + need_relocs = TRUE; + + if (tls_type & GOT_TLS_GD) + { + if (need_relocs) + { + outrel.r_offset = sec_addr (htab->elf.sgot) + off; + outrel.r_addend = 0; + outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPMODNN); + bfd_put_NN (output_bfd, 0, + htab->elf.sgot->contents + off); + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel); + if (indx == 0) + { + BFD_ASSERT (! unresolved_reloc); + bfd_put_NN (output_bfd, + dtpoff (info, relocation), + (htab->elf.sgot->contents + off + + RISCV_ELF_WORD_BYTES)); + } + else + { + bfd_put_NN (output_bfd, 0, + (htab->elf.sgot->contents + off + + RISCV_ELF_WORD_BYTES)); + outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPRELNN); + outrel.r_offset += RISCV_ELF_WORD_BYTES; + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel); + } + } + else + { + /* If we are not emitting relocations for a + general dynamic reference, then we must be in a + static link or an executable link with the + symbol binding locally. Mark it as belonging + to module 1, the executable. */ + bfd_put_NN (output_bfd, 1, + htab->elf.sgot->contents + off); + bfd_put_NN (output_bfd, + dtpoff (info, relocation), + (htab->elf.sgot->contents + off + + RISCV_ELF_WORD_BYTES)); + } + } + + if (tls_type & GOT_TLS_IE) + { + if (need_relocs) + { + bfd_put_NN (output_bfd, 0, + htab->elf.sgot->contents + off + ie_off); + outrel.r_offset = sec_addr (htab->elf.sgot) + + off + ie_off; + outrel.r_addend = 0; + if (indx == 0) + outrel.r_addend = tpoff (info, relocation); + outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_TPRELNN); + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel); + } + else + { + bfd_put_NN (output_bfd, tpoff (info, relocation), + htab->elf.sgot->contents + off + ie_off); + } + } + } + + BFD_ASSERT (off < (bfd_vma) -2); + relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0); + if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, relocation)) + r = bfd_reloc_overflow; + unresolved_reloc = FALSE; + break; + + default: + r = bfd_reloc_notsupported; + } + + /* Dynamic relocs are not propagated for SEC_DEBUGGING sections + because such sections are not SEC_ALLOC and thus ld.so will + not process them. */ + if (unresolved_reloc + && !((input_section->flags & SEC_DEBUGGING) != 0 + && h->def_dynamic) + && _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset) != (bfd_vma) -1) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), + input_bfd, + input_section, + (long) rel->r_offset, + howto->name, + h->root.root.string); + continue; + } + + if (r == bfd_reloc_ok) + r = perform_relocation (howto, rel, relocation, input_section, + input_bfd, contents); + + switch (r) + { + case bfd_reloc_ok: + continue; + + case bfd_reloc_overflow: + r = info->callbacks->reloc_overflow + (info, (h ? &h->root : NULL), name, howto->name, + (bfd_vma) 0, input_bfd, input_section, rel->r_offset); + break; + + case bfd_reloc_undefined: + r = info->callbacks->undefined_symbol + (info, name, input_bfd, input_section, rel->r_offset, + TRUE); + break; + + case bfd_reloc_outofrange: + msg = _("internal error: out of range error"); + break; + + case bfd_reloc_notsupported: + msg = _("internal error: unsupported relocation error"); + break; + + case bfd_reloc_dangerous: + msg = _("internal error: dangerous relocation"); + break; + + default: + msg = _("internal error: unknown error"); + break; + } + + if (msg) + r = info->callbacks->warning + (info, msg, name, input_bfd, input_section, rel->r_offset); + goto out; + } + + ret = riscv_resolve_pcrel_lo_relocs (&pcrel_relocs); +out: + riscv_free_pcrel_relocs (&pcrel_relocs); + return ret; +} + +/* Finish up dynamic symbol handling. We set the contents of various + dynamic sections here. */ + +static bfd_boolean +riscv_elf_finish_dynamic_symbol (bfd *output_bfd, + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + + if (h->plt.offset != (bfd_vma) -1) + { + /* We've decided to create a PLT entry for this symbol. */ + bfd_byte *loc; + bfd_vma i, header_address, plt_idx, got_address; + uint32_t plt_entry[PLT_ENTRY_INSNS]; + Elf_Internal_Rela rela; + + BFD_ASSERT (h->dynindx != -1); + + /* Calculate the address of the PLT header. */ + header_address = sec_addr (htab->elf.splt); + + /* Calculate the index of the entry. */ + plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; + + /* Calculate the address of the .got.plt entry. */ + got_address = riscv_elf_got_plt_val (plt_idx, info); + + /* Find out where the .plt entry should go. */ + loc = htab->elf.splt->contents + h->plt.offset; + + /* Fill in the PLT entry itself. */ + riscv_make_plt_entry (got_address, header_address + h->plt.offset, + plt_entry); + for (i = 0; i < PLT_ENTRY_INSNS; i++) + bfd_put_32 (output_bfd, plt_entry[i], loc + 4*i); + + /* Fill in the initial value of the .got.plt entry. */ + loc = htab->elf.sgotplt->contents + + (got_address - sec_addr (htab->elf.sgotplt)); + bfd_put_NN (output_bfd, sec_addr (htab->elf.splt), loc); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = got_address; + rela.r_addend = 0; + rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_JUMP_SLOT); + + loc = htab->elf.srelplt->contents + plt_idx * sizeof (ElfNN_External_Rela); + bed->s->swap_reloca_out (output_bfd, &rela, loc); + + if (!h->def_regular) + { + /* Mark the symbol as undefined, rather than as defined in + the .plt section. Leave the value alone. */ + sym->st_shndx = SHN_UNDEF; + /* If the symbol is weak, we do need to clear the value. + Otherwise, the PLT entry would provide a definition for + the symbol even if the symbol wasn't defined anywhere, + and so the symbol would never be NULL. */ + if (!h->ref_regular_nonweak) + sym->st_value = 0; + } + } + + if (h->got.offset != (bfd_vma) -1 + && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))) + { + asection *sgot; + asection *srela; + Elf_Internal_Rela rela; + + /* This symbol has an entry in the GOT. Set it up. */ + + sgot = htab->elf.sgot; + srela = htab->elf.srelgot; + BFD_ASSERT (sgot != NULL && srela != NULL); + + rela.r_offset = sec_addr (sgot) + (h->got.offset &~ (bfd_vma) 1); + + /* If this is a -Bsymbolic link, and the symbol is defined + locally, we just want to emit a RELATIVE reloc. Likewise if + the symbol was forced to be local because of a version file. + The entry in the global offset table will already have been + initialized in the relocate_section function. */ + if (info->shared + && (info->symbolic || h->dynindx == -1) + && h->def_regular) + { + asection *sec = h->root.u.def.section; + rela.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE); + rela.r_addend = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); + } + else + { + BFD_ASSERT (h->dynindx != -1); + rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_NN); + rela.r_addend = 0; + } + + bfd_put_NN (output_bfd, 0, + sgot->contents + (h->got.offset & ~(bfd_vma) 1)); + riscv_elf_append_rela (output_bfd, srela, &rela); + } + + if (h->needs_copy) + { + Elf_Internal_Rela rela; + + /* This symbols needs a copy reloc. Set it up. */ + BFD_ASSERT (h->dynindx != -1); + + rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value; + rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_COPY); + rela.r_addend = 0; + riscv_elf_append_rela (output_bfd, htab->srelbss, &rela); + } + + /* Mark some specially defined symbols as absolute. */ + if (/*h == htab->elf.hdynamic*/ + strcmp (h->root.root.string, "_DYNAMIC") == 0 + || (h == htab->elf.hgot || h == htab->elf.hplt)) + sym->st_shndx = SHN_ABS; + + return TRUE; +} + +/* Finish up the dynamic sections. */ + +static bfd_boolean +riscv_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, + bfd *dynobj, asection *sdyn) +{ + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + size_t dynsize = bed->s->sizeof_dyn; + bfd_byte *dyncon, *dynconend; + + dynconend = sdyn->contents + sdyn->size; + for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize) + { + Elf_Internal_Dyn dyn; + asection *s; + + bed->s->swap_dyn_in (dynobj, dyncon, &dyn); + + switch (dyn.d_tag) + { + case DT_PLTGOT: + s = htab->elf.sgotplt; + dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; + break; + case DT_JMPREL: + s = htab->elf.srelplt; + dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; + break; + case DT_PLTRELSZ: + s = htab->elf.srelplt; + dyn.d_un.d_val = s->size; + break; + default: + continue; + } + + bed->s->swap_dyn_out (output_bfd, &dyn, dyncon); + } + return TRUE; +} + +static bfd_boolean +riscv_elf_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) +{ + bfd *dynobj; + asection *sdyn; + struct riscv_elf_link_hash_table *htab; + + htab = riscv_elf_hash_table (info); + BFD_ASSERT (htab != NULL); + dynobj = htab->elf.dynobj; + + sdyn = bfd_get_linker_section (dynobj, ".dynamic"); + + if (elf_hash_table (info)->dynamic_sections_created) + { + asection *splt; + bfd_boolean ret; + + splt = htab->elf.splt; + BFD_ASSERT (splt != NULL && sdyn != NULL); + + ret = riscv_finish_dyn (output_bfd, info, dynobj, sdyn); + + if (ret != TRUE) + return ret; + + /* Fill in the head and tail entries in the procedure linkage table. */ + if (splt->size > 0) + { + int i; + uint32_t plt_header[PLT_HEADER_INSNS]; + riscv_make_plt0_entry (sec_addr (htab->elf.sgotplt), + sec_addr (splt), plt_header); + + for (i = 0; i < PLT_HEADER_INSNS; i++) + bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i); + } + + elf_section_data (splt->output_section)->this_hdr.sh_entsize + = PLT_ENTRY_SIZE; + } + + if (htab->elf.sgotplt) + { + if (bfd_is_abs_section (htab->elf.sgotplt->output_section)) + { + (*_bfd_error_handler) + (_("discarded output section: `%A'"), htab->elf.sgotplt); + return FALSE; + } + + if (htab->elf.sgotplt->size > 0) + { + /* Write the first two entries in .got.plt, needed for the dynamic + linker. */ + bfd_put_NN (output_bfd, (bfd_vma) -1, htab->elf.sgotplt->contents); + bfd_put_NN (output_bfd, (bfd_vma) 0, + htab->elf.sgotplt->contents + GOT_ENTRY_SIZE); + } + + elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = + GOT_ENTRY_SIZE; + } + + if (htab->elf.sgot) + { + if (htab->elf.sgot->size > 0) + { + /* Set the first entry in the global offset table to the address of + the dynamic section. */ + bfd_vma val = sdyn ? sec_addr (sdyn) : 0; + bfd_put_NN (output_bfd, val, htab->elf.sgot->contents); + } + + elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = + GOT_ENTRY_SIZE; + } + + return TRUE; +} + +/* Return address for Ith PLT stub in section PLT, for relocation REL + or (bfd_vma) -1 if it should not be included. */ + +static bfd_vma +riscv_elf_plt_sym_val (bfd_vma i, const asection *plt, + const arelent *rel ATTRIBUTE_UNUSED) +{ + return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE; +} + +static enum elf_reloc_type_class +riscv_reloc_type_class (/*const struct bfd_link_info *info ATTRIBUTE_UNUSED, + const asection *rel_sec ATTRIBUTE_UNUSED,*/ + const Elf_Internal_Rela *rela) +{ + switch (ELFNN_R_TYPE (rela->r_info)) + { + case R_RISCV_RELATIVE: + return reloc_class_relative; + case R_RISCV_JUMP_SLOT: + return reloc_class_plt; + case R_RISCV_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + +/* Return true if bfd machine EXTENSION is an extension of machine BASE. */ + +static bfd_boolean +riscv_mach_extends_p (unsigned long base, unsigned long extension) +{ + return extension == base; +} + +/* Merge backend specific data from an object file to the output + object file when linking. */ + +static bfd_boolean +_bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + flagword old_flags; + flagword new_flags; + + if (!is_riscv_elf (ibfd) || !is_riscv_elf (obfd)) + return TRUE; + + if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0) + { + (*_bfd_error_handler) + (_("%B: ABI is incompatible with that of the selected emulation"), + ibfd); + return FALSE; + } + + if (!_bfd_elf_merge_object_attributes (ibfd, obfd)) + return FALSE; + + new_flags = elf_elfheader (ibfd)->e_flags; + old_flags = elf_elfheader (obfd)->e_flags; + + if (! elf_flags_init (obfd)) + { + elf_flags_init (obfd) = TRUE; + elf_elfheader (obfd)->e_flags = new_flags; + elf_elfheader (obfd)->e_ident[EI_CLASS] + = elf_elfheader (ibfd)->e_ident[EI_CLASS]; + + if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) + && (bfd_get_arch_info (obfd)->the_default + || riscv_mach_extends_p (bfd_get_mach (obfd), + bfd_get_mach (ibfd)))) + { + if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), + bfd_get_mach (ibfd))) + return FALSE; + } + + return TRUE; + } + + /* Check flag compatibility. */ + + if (new_flags == old_flags) + return TRUE; + + /* Don't link RV32 and RV64. */ + if (elf_elfheader (ibfd)->e_ident[EI_CLASS] + != elf_elfheader (obfd)->e_ident[EI_CLASS]) + { + (*_bfd_error_handler) + (_("%B: ELF class mismatch: can't link 32- and 64-bit modules"), ibfd); + goto fail; + } + + /* Warn about any other mismatches. */ + if (new_flags != old_flags) + { + if (!EF_IS_RISCV_EXT_Xcustom (new_flags) && + !EF_IS_RISCV_EXT_Xcustom (old_flags)) + { + (*_bfd_error_handler) + (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), + ibfd, (unsigned long) new_flags, + (unsigned long) old_flags); + goto fail; + } + else if (EF_IS_RISCV_EXT_Xcustom(new_flags)) + EF_SET_RISCV_EXT (elf_elfheader (obfd)->e_flags, + EF_GET_RISCV_EXT (old_flags)); + } + + return TRUE; + +fail: + bfd_set_error (bfd_error_bad_value); + return FALSE; +} + +/* Delete some bytes from a section while relaxing. */ + +static bfd_boolean +riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count) +{ + unsigned int i, symcount; + bfd_vma toaddr = sec->size; + struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); + Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); + struct bfd_elf_section_data *data = elf_section_data (sec); + bfd_byte *contents = data->this_hdr.contents; + + /* Actually delete the bytes. */ + sec->size -= count; + memmove (contents + addr, contents + addr + count, toaddr - addr - count); + + /* Adjust the location of all of the relocs. Note that we need not + adjust the addends, since all PC-relative references must be against + symbols, which we will adjust below. */ + for (i = 0; i < sec->reloc_count; i++) + if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr) + data->relocs[i].r_offset -= count; + + /* Adjust the local symbols defined in this section. */ + for (i = 0; i < symtab_hdr->sh_info; i++) + { + Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i; + if (sym->st_shndx == sec_shndx) + { + /* If the symbol is in the range of memory we just moved, we + have to adjust its value. */ + if (sym->st_value > addr && sym->st_value <= toaddr) + sym->st_value -= count; + + /* If the symbol *spans* the bytes we just deleted (i.e. its + *end* is in the moved bytes but its *start* isn't), then we + must adjust its size. */ + if (sym->st_value <= addr + && sym->st_value + sym->st_size > addr + && sym->st_value + sym->st_size <= toaddr) + sym->st_size -= count; + } + } + + /* Now adjust the global symbols defined in this section. */ + symcount = ((symtab_hdr->sh_size / sizeof(ElfNN_External_Sym)) + - symtab_hdr->sh_info); + + for (i = 0; i < symcount; i++) + { + struct elf_link_hash_entry *sym_hash = sym_hashes[i]; + + if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) + { + /* As above, adjust the value if needed. */ + if (sym_hash->root.u.def.value > addr + && sym_hash->root.u.def.value <= toaddr) + sym_hash->root.u.def.value -= count; + + /* As above, adjust the size if needed. */ + if (sym_hash->root.u.def.value <= addr + && sym_hash->root.u.def.value + sym_hash->size > addr + && sym_hash->root.u.def.value + sym_hash->size <= toaddr) + sym_hash->size -= count; + } + } + + return TRUE; +} + +/* Relax AUIPC + JALR into JAL. */ + +static bfd_boolean +_bfd_riscv_relax_call (bfd *abfd, asection *sec, + struct bfd_link_info *link_info, + Elf_Internal_Rela *rel, + bfd_vma symval, + bfd_boolean *again) +{ + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; + bfd_signed_vma foff = symval - (sec_addr (sec) + rel->r_offset); + bfd_boolean near_zero = (symval + RISCV_IMM_REACH/2) < RISCV_IMM_REACH; + bfd_vma auipc, jalr; + int r_type; + + /* See if this function call can be shortened. */ + if (!VALID_UJTYPE_IMM (foff) && !(!link_info->shared && near_zero)) + return TRUE; + + /* Shorten the function call. */ + BFD_ASSERT (rel->r_offset + 8 <= sec->size); + + auipc = bfd_get_32 (abfd, contents + rel->r_offset); + jalr = bfd_get_32 (abfd, contents + rel->r_offset + 4); + + if (VALID_UJTYPE_IMM (foff)) + { + /* Relax to JAL rd, addr. */ + r_type = R_RISCV_JAL; + auipc = (jalr & (OP_MASK_RD << OP_SH_RD)) | MATCH_JAL; + } + else /* near_zero */ + { + /* Relax to JALR rd, x0, addr. */ + r_type = R_RISCV_LO12_I; + auipc = (jalr & (OP_MASK_RD << OP_SH_RD)) | MATCH_JALR; + } + + /* Replace the R_RISCV_CALL reloc. */ + rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), r_type); + /* Replace the AUIPC. */ + bfd_put_32 (abfd, auipc, contents + rel->r_offset); + + /* Delete unnecessary JALR. */ + *again = TRUE; + return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4); +} + +/* Relax non-PIC global variable references. */ + +static bfd_boolean +_bfd_riscv_relax_lui (bfd *abfd, asection *sec, + struct bfd_link_info *link_info, + Elf_Internal_Rela *rel, + bfd_vma symval, + bfd_boolean *again) +{ + bfd_vma gp = riscv_global_pointer_value (link_info); + + /* Bail out if this symbol isn't in range of either gp or x0. */ + if (!VALID_ITYPE_IMM (symval - gp) && !(symval < RISCV_IMM_REACH/2)) + return TRUE; + + /* We can delete the unnecessary AUIPC. The corresponding LO12 reloc + will be converted to GPREL during relocation. */ + BFD_ASSERT (rel->r_offset + 4 <= sec->size); + rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE); + + *again = TRUE; + return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4); +} + +/* Relax non-PIC TLS references. */ + +static bfd_boolean +_bfd_riscv_relax_tls_le (bfd *abfd, asection *sec, + struct bfd_link_info *link_info, + Elf_Internal_Rela *rel, + bfd_vma symval, + bfd_boolean *again) +{ + /* See if this symbol is in range of tp. */ + if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0) + return TRUE; + + /* We can delete the unnecessary LUI and tp add. The LO12 reloc will be + made directly tp-relative. */ + BFD_ASSERT (rel->r_offset + 4 <= sec->size); + rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE); + + *again = TRUE; + return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4); +} + +/* Implement R_RISCV_ALIGN by deleting excess alignment NOPs. */ + +static bfd_boolean +_bfd_riscv_relax_align (bfd *abfd, asection *sec, + struct bfd_link_info *link_info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + bfd_vma symval, + bfd_boolean *again ATTRIBUTE_UNUSED) +{ + bfd_vma alignment = 1; + while (alignment <= rel->r_addend) + alignment *= 2; + + symval -= rel->r_addend; + bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment; + bfd_vma nop_bytes_needed = aligned_addr - symval; + + /* Make sure there are enough NOPs to actually achieve the alignment. */ + if (rel->r_addend < nop_bytes_needed) + return FALSE; + + /* Delete the reloc. */ + rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE); + + /* If the number of NOPs is already correct, there's nothing to do. */ + if (nop_bytes_needed == rel->r_addend) + return TRUE; + + /* Delete the excess NOPs. */ + return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, + rel->r_addend - nop_bytes_needed); +} + +/* Relax a section. Pass 0 shortens code sequences unless disabled. + Pass 1, which cannot be disabled, handles code alignment directives. */ + +static bfd_boolean +_bfd_riscv_relax_section (bfd *abfd, asection *sec, + struct bfd_link_info *info, bfd_boolean *again) +{ + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd); + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + struct bfd_elf_section_data *data = elf_section_data (sec); + Elf_Internal_Rela *relocs; + bfd_boolean ret = FALSE; + unsigned int i; + + *again = FALSE; + + if (info->relocatable + || (sec->flags & SEC_RELOC) == 0 + || sec->reloc_count == 0 + || (/*info->disable_target_specific_optimizations*/ 0 + && info->relax_pass == 0)) + return TRUE; + + /* Read this BFD's relocs if we haven't done so already. */ + if (data->relocs) + relocs = data->relocs; + else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, + info->keep_memory))) + goto fail; + + /* Examine and consider relaxing each reloc. */ + for (i = 0; i < sec->reloc_count; i++) + { + Elf_Internal_Rela *rel = data->relocs + i; + typeof(&_bfd_riscv_relax_call) relax_func = NULL; + int type = ELFNN_R_TYPE (rel->r_info); + bfd_vma symval; + + if (info->relax_pass == 0) + { + if (type == R_RISCV_CALL || type == R_RISCV_CALL_PLT) + relax_func = _bfd_riscv_relax_call; + else if (type == R_RISCV_HI20) + relax_func = _bfd_riscv_relax_lui; + else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD) + relax_func = _bfd_riscv_relax_tls_le; + } + else if (type == R_RISCV_ALIGN) + relax_func = _bfd_riscv_relax_align; + + if (!relax_func) + continue; + + data->relocs = relocs; + + /* Read this BFD's contents if we haven't done so already. */ + if (!data->this_hdr.contents + && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents)) + goto fail; + + /* Read this BFD's symbols if we haven't done so already. */ + if (symtab_hdr->sh_info != 0 + && !symtab_hdr->contents + && !(symtab_hdr->contents = + (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, + 0, NULL, NULL, NULL))) + goto fail; + + /* Get the value of the symbol referred to by the reloc. */ + if (ELFNN_R_SYM (rel->r_info) < symtab_hdr->sh_info) + { + /* A local symbol. */ + Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents + + ELFNN_R_SYM (rel->r_info)); + + if (isym->st_shndx == SHN_UNDEF) + symval = sec_addr (sec) + rel->r_offset; + else + { + asection *isec; + BFD_ASSERT (isym->st_shndx < elf_numsections (abfd)); + isec = elf_elfsections (abfd)[isym->st_shndx]->bfd_section; + if (sec_addr (isec) == 0) + continue; + symval = sec_addr (isec) + isym->st_value; + } + } + else + { + unsigned long indx; + struct elf_link_hash_entry *h; + + indx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info; + h = elf_sym_hashes (abfd)[indx]; + + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->plt.offset != MINUS_ONE) + symval = sec_addr (htab->elf.splt) + h->plt.offset; + else if (h->root.type == bfd_link_hash_undefweak) + symval = 0; + else if (h->root.u.def.section->output_section == NULL + || (h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak)) + continue; + else + symval = sec_addr (h->root.u.def.section) + h->root.u.def.value; + } + + symval += rel->r_addend; + + if (!relax_func (abfd, sec, info, rel, symval, again)) + goto fail; + } + + ret = TRUE; + +fail: + if (relocs != data->relocs) + free (relocs); + + return ret; +} + +#define ELF_ARCH bfd_arch_riscv +#define ELF_TARGET_ID RISCV_ELF_DATA +#define ELF_MACHINE_CODE EM_RISCV +#define ELF_MAXPAGESIZE 0x2000 +#define ELF_COMMONPAGESIZE 0x2000 + +#define TARGET_LITTLE_SYM bfd_elfNN_riscv_vec +#define TARGET_LITTLE_NAME "elfNN-littleriscv" + +#define elf_backend_reloc_type_class riscv_reloc_type_class + +#define bfd_elfNN_bfd_reloc_name_lookup riscv_reloc_name_lookup +#define bfd_elfNN_bfd_link_hash_table_create riscv_elf_link_hash_table_create +#define bfd_elfNN_bfd_reloc_type_lookup riscv_reloc_type_lookup +#define bfd_elfNN_bfd_merge_private_bfd_data \ + _bfd_riscv_elf_merge_private_bfd_data + +#define elf_backend_copy_indirect_symbol riscv_elf_copy_indirect_symbol +#define elf_backend_create_dynamic_sections riscv_elf_create_dynamic_sections +#define elf_backend_check_relocs riscv_elf_check_relocs +#define elf_backend_adjust_dynamic_symbol riscv_elf_adjust_dynamic_symbol +#define elf_backend_size_dynamic_sections riscv_elf_size_dynamic_sections +#define elf_backend_relocate_section riscv_elf_relocate_section +#define elf_backend_finish_dynamic_symbol riscv_elf_finish_dynamic_symbol +#define elf_backend_finish_dynamic_sections riscv_elf_finish_dynamic_sections +#define elf_backend_gc_mark_hook riscv_elf_gc_mark_hook +#define elf_backend_gc_sweep_hook riscv_elf_gc_sweep_hook +#define elf_backend_plt_sym_val riscv_elf_plt_sym_val +#define elf_info_to_howto_rel NULL +#define elf_info_to_howto riscv_info_to_howto_rela +#define bfd_elfNN_bfd_relax_section _bfd_riscv_relax_section + +#define elf_backend_init_index_section _bfd_elf_init_1_index_section + +#define elf_backend_can_gc_sections 1 +#define elf_backend_can_refcount 1 +#define elf_backend_want_got_plt 1 +#define elf_backend_plt_readonly 1 +#define elf_backend_plt_alignment 4 +#define elf_backend_want_plt_sym 1 +#define elf_backend_got_header_size (ARCH_SIZE / 8) +#define elf_backend_rela_normal 1 +#define elf_backend_default_execstack 0 + +#include "elfNN-target.h" diff -rNU3 dist.orig/bfd/elfxx-mips.c dist/bfd/elfxx-mips.c --- dist.orig/bfd/elfxx-mips.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elfxx-mips.c 2015-10-18 13:11:13.000000000 +0200 @@ -8191,10 +8191,24 @@ reloc types into the output file as R_MIPS_REL32 relocs. Make room for this reloc in .rel(a).dyn. */ mips_elf_allocate_dynamic_relocations (dynobj, info, 1); - if (MIPS_ELF_READONLY_SECTION (sec)) - /* We tell the dynamic linker that there are - relocations against the text segment. */ - info->flags |= DF_TEXTREL; + /* In the N32 and 64-bit ABIs there may be multiple + consecutive relocations for the same offset. If we have + a R_MIPS_GPREL32 followed by a R_MIPS_64 then that + relocation is complete and needs no futher adjustment. */ + if ((rel == relocs + || rel[-1].r_offset != rel->r_offset + || r_type != R_MIPS_64 + || ELF_R_TYPE(abfd, rel[-1].r_info) != R_MIPS_GPREL32) + && MIPS_ELF_READONLY_SECTION (sec)) + { + /* We tell the dynamic linker that there are + relocations against the text segment. */ + info->flags |= DF_TEXTREL; + info->callbacks->warning + (info, + _("relocation emitted against readonly section"), + NULL, abfd, sec, rel->r_offset); + } } else { @@ -8612,6 +8626,7 @@ /* Make sure we know what is going on here. */ BFD_ASSERT (dynobj != NULL && (h->needs_plt + || h->type == STT_GNU_IFUNC || h->u.weakdef != NULL || (h->def_dynamic && h->ref_regular diff -rNU3 dist.orig/bfd/elfxx-riscv.c dist/bfd/elfxx-riscv.c --- dist.orig/bfd/elfxx-riscv.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/elfxx-riscv.c 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,730 @@ +/* RISC-V-specific support for ELF. + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on TILE-Gx and MIPS targets. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elf/riscv.h" +#include "opcode/riscv.h" +#include "libiberty.h" +#include "elfxx-riscv.h" +#include + +#define MINUS_ONE ((bfd_vma)0 - 1) + +/* The relocation table used for SHT_RELA sections. */ + +static reloc_howto_type howto_table[] = +{ + /* No relocation. */ + HOWTO (R_RISCV_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_NONE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_RISCV_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_32", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 64 bit relocation. */ + HOWTO (R_RISCV_64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_64", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Relocation against a local symbol in a shared object. */ + HOWTO (R_RISCV_RELATIVE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_RELATIVE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_COPY, /* type */ + 0, /* rightshift */ + 0, /* this one is variable size */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_COPY", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_JUMP_SLOT, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_JUMP_SLOT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Dynamic TLS relocations. */ + HOWTO (R_RISCV_TLS_DTPMOD32, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_DTPMOD32", /* name */ + FALSE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_TLS_DTPMOD64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_DTPMOD64", /* name */ + FALSE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_TLS_DTPREL32, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_DTPREL32", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_TLS_DTPREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_DTPREL64", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_TLS_TPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_TPREL32", /* name */ + FALSE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_RISCV_TLS_TPREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_TPREL64", /* name */ + FALSE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + EMPTY_HOWTO (12), + EMPTY_HOWTO (13), + EMPTY_HOWTO (14), + EMPTY_HOWTO (15), + + /* 12-bit PC-relative branch offset. */ + HOWTO (R_RISCV_BRANCH, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_BRANCH", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_SBTYPE_IMM(-1U),/* dst_mask */ + TRUE), /* pcrel_offset */ + + /* 20-bit PC-relative jump offset. */ + HOWTO (R_RISCV_JAL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper 36 + bits must match the PC + 4. */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_JAL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UJTYPE_IMM(-1U), /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* 32-bit PC-relative function call (AUIPC/JALR). */ + HOWTO (R_RISCV_CALL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_CALL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U) | ((bfd_vma) ENCODE_ITYPE_IMM(-1U) << 32), /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* 32-bit PC-relative function call (AUIPC/JALR). */ + HOWTO (R_RISCV_CALL_PLT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_CALL_PLT", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U) | ((bfd_vma) ENCODE_ITYPE_IMM(-1U) << 32), /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* High 20 bits of 32-bit PC-relative GOT access. */ + HOWTO (R_RISCV_GOT_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_GOT_HI20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */ + HOWTO (R_RISCV_TLS_GOT_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_GOT_HI20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */ + HOWTO (R_RISCV_TLS_GD_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TLS_GD_HI20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 20 bits of 32-bit PC-relative reference. */ + HOWTO (R_RISCV_PCREL_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_PCREL_HI20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* Low 12 bits of a 32-bit PC-relative load or add. */ + HOWTO (R_RISCV_PCREL_LO12_I, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_PCREL_LO12_I",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_ITYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 12 bits of a 32-bit PC-relative store. */ + HOWTO (R_RISCV_PCREL_LO12_S, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_PCREL_LO12_S",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_STYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 20 bits of 32-bit absolute address. */ + HOWTO (R_RISCV_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_HI20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 12 bits of 32-bit load or add. */ + HOWTO (R_RISCV_LO12_I, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_LO12_I", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_ITYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 12 bits of 32-bit store. */ + HOWTO (R_RISCV_LO12_S, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_LO12_S", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_STYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 20 bits of TLS LE thread pointer offset. */ + HOWTO (R_RISCV_TPREL_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_HI20", /* name */ + TRUE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_UTYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */ + HOWTO (R_RISCV_TPREL_LO12_I, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_LO12_I",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_ITYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 12 bits of TLS LE thread pointer offset for stores. */ + HOWTO (R_RISCV_TPREL_LO12_S, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_LO12_S",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ENCODE_STYPE_IMM(-1U), /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS LE thread pointer usage. */ + HOWTO (R_RISCV_TPREL_ADD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_TPREL_ADD", /* name */ + TRUE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 8-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_ADD8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_ADD8", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 16-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_ADD16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_ADD16", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_ADD32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_ADD32", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 64-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_ADD64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_ADD64", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 8-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_SUB8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_SUB8", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 16-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_SUB16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_SUB16", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_SUB32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_SUB32", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 64-bit in-place addition, for local label subtraction. */ + HOWTO (R_RISCV_SUB64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_SUB64", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable hierarchy */ + HOWTO (R_RISCV_GNU_VTINHERIT, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + NULL, /* special_function */ + "R_RISCV_GNU_VTINHERIT", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable member usage */ + HOWTO (R_RISCV_GNU_VTENTRY, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + _bfd_elf_rel_vtable_reloc_fn, /* special_function */ + "R_RISCV_GNU_VTENTRY", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Indicates an alignment statement. The addend field encodes how many + bytes of NOPs follow the statement. The desired alignment is the + addend rounded up to the next power of two. */ + HOWTO (R_RISCV_ALIGN, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_ALIGN", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + TRUE), /* pcrel_offset */ +}; + +/* A mapping from BFD reloc types to RISC-V ELF reloc types. */ + +struct elf_reloc_map { + bfd_reloc_code_real_type bfd_val; + enum elf_riscv_reloc_type elf_val; +}; + +static const struct elf_reloc_map riscv_reloc_map[] = +{ + { BFD_RELOC_NONE, R_RISCV_NONE }, + { BFD_RELOC_32, R_RISCV_32 }, + { BFD_RELOC_64, R_RISCV_64 }, + { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 }, + { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 }, + { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 }, + { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 }, + { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 }, + { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 }, + { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 }, + { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 }, + { BFD_RELOC_CTOR, R_RISCV_64 }, + { BFD_RELOC_12_PCREL, R_RISCV_BRANCH }, + { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 }, + { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I }, + { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S }, + { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I }, + { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S }, + { BFD_RELOC_RISCV_CALL, R_RISCV_CALL }, + { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT }, + { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 }, + { BFD_RELOC_RISCV_JMP, R_RISCV_JAL }, + { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 }, + { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 }, + { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 }, + { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 }, + { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 }, + { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 }, + { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 }, + { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 }, + { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD }, + { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S }, + { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I }, + { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 }, + { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 }, + { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN }, +}; + +/* Given a BFD reloc type, return a howto structure. */ + +reloc_howto_type * +riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++) + if (riscv_reloc_map[i].bfd_val == code) + return &howto_table[(int) riscv_reloc_map[i].elf_val]; + + bfd_set_error (bfd_error_bad_value); + return NULL; +} + +reloc_howto_type * +riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (howto_table); i++) + if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; + + return NULL; +} + +reloc_howto_type * +riscv_elf_rtype_to_howto (unsigned int r_type) +{ + if ((unsigned int)r_type >= ARRAY_SIZE (howto_table)) + { + (*_bfd_error_handler)(_("unrecognized relocation (0x%x)"), r_type); + bfd_set_error (bfd_error_bad_value); + return NULL; + } + return &howto_table[r_type]; +} diff -rNU3 dist.orig/bfd/elfxx-riscv.h dist/bfd/elfxx-riscv.h --- dist.orig/bfd/elfxx-riscv.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/bfd/elfxx-riscv.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,34 @@ +/* RISC-V ELF specific backend routines. + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "elf/common.h" +#include "elf/internal.h" + +extern reloc_howto_type * +riscv_reloc_name_lookup (bfd *, const char *); + +extern reloc_howto_type * +riscv_reloc_type_lookup (bfd *, bfd_reloc_code_real_type); + +extern reloc_howto_type * +riscv_elf_rtype_to_howto (unsigned int r_type); diff -rNU3 dist.orig/bfd/elfxx-sparc.c dist/bfd/elfxx-sparc.c --- dist.orig/bfd/elfxx-sparc.c 2013-03-25 09:06:20.000000000 +0100 +++ dist/bfd/elfxx-sparc.c 2015-10-18 13:11:13.000000000 +0200 @@ -2508,6 +2508,10 @@ { struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (info->warn_shared_textrel) + (*_bfd_error_handler) + (_("warning: dynamic relocation in readonly section `%s'"), + h->root.root.string); info->flags |= DF_TEXTREL; /* Not an error, just cut short the traversal. */ @@ -3460,10 +3464,8 @@ memset (&outrel, 0, sizeof outrel); /* h->dynindx may be -1 if the symbol was marked to become local. */ - else if (h != NULL && - h->dynindx != -1 - && (! is_plt - || !info->shared + else if (h != NULL && h->dynindx != -1 && ! is_plt + && (!info->shared || !SYMBOLIC_BIND (info, h) || !h->def_regular)) { diff -rNU3 dist.orig/bfd/libbfd.h dist/bfd/libbfd.h --- dist.orig/bfd/libbfd.h 2012-09-04 14:53:42.000000000 +0200 +++ dist/bfd/libbfd.h 2015-10-18 13:11:13.000000000 +0200 @@ -2295,8 +2295,65 @@ "BFD_RELOC_860_HIGH", "BFD_RELOC_860_HIGOT", "BFD_RELOC_860_HIGOTOFF", - "BFD_RELOC_OPENRISC_ABS_26", - "BFD_RELOC_OPENRISC_REL_26", + "BFD_RELOC_OR1K_REL_26", + "BFD_RELOC_OR1K_GOTPC_HI16", + "BFD_RELOC_OR1K_GOTPC_LO16", + "BFD_RELOC_OR1K_GOT16", + "BFD_RELOC_OR1K_PLT26", + "BFD_RELOC_OR1K_GOTOFF_HI16", + "BFD_RELOC_OR1K_GOTOFF_LO16", + "BFD_RELOC_OR1K_COPY", + "BFD_RELOC_OR1K_GLOB_DAT", + "BFD_RELOC_OR1K_JMP_SLOT", + "BFD_RELOC_OR1K_RELATIVE", + "BFD_RELOC_OR1K_TLS_GD_HI16", + "BFD_RELOC_OR1K_TLS_GD_LO16", + "BFD_RELOC_OR1K_TLS_LDM_HI16", + "BFD_RELOC_OR1K_TLS_LDM_LO16", + "BFD_RELOC_OR1K_TLS_LDO_HI16", + "BFD_RELOC_OR1K_TLS_LDO_LO16", + "BFD_RELOC_OR1K_TLS_IE_HI16", + "BFD_RELOC_OR1K_TLS_IE_LO16", + "BFD_RELOC_OR1K_TLS_LE_HI16", + "BFD_RELOC_OR1K_TLS_LE_LO16", + "BFD_RELOC_OR1K_TLS_TPOFF", + "BFD_RELOC_OR1K_TLS_DTPOFF", + "BFD_RELOC_OR1K_TLS_DTPMOD", + "BFD_RELOC_RISCV_ADD32", + "BFD_RELOC_RISCV_ADD64", + "BFD_RELOC_RISCV_SUB32", + "BFD_RELOC_RISCV_SUB64", + "BFD_RELOC_RISCV_HI20", + "BFD_RELOC_RISCV_LO12_I", + "BFD_RELOC_RISCV_LO12_S", + "BFD_RELOC_RISCV_PCREL_LO12_I", + "BFD_RELOC_RISCV_PCREL_LO12_S", + "BFD_RELOC_RISCV_CALL", + "BFD_RELOC_RISCV_CALL_PLT", + "BFD_RELOC_RISCV_PCREL_HI20", + "BFD_RELOC_RISCV_JMP", + "BFD_RELOC_RISCV_GOT_HI20", + "BFD_RELOC_RISCV_GOT_LO12", + "BFD_RELOC_RISCV_TLS_DTPMOD32", + "BFD_RELOC_RISCV_TLS_DTPREL32", + "BFD_RELOC_RISCV_TLS_DTPMOD64", + "BFD_RELOC_RISCV_TLS_DTPREL64", + "BFD_RELOC_RISCV_TLS_TPREL32", + "BFD_RELOC_RISCV_TLS_TPREL64", + "BFD_RELOC_RISCV_TPREL_HI20", + "BFD_RELOC_RISCV_TPREL_ADD", + "BFD_RELOC_RISCV_TPREL_LO12_S", + "BFD_RELOC_RISCV_TPREL_LO12_I", + "BFD_RELOC_RISCV_TLS_IE_HI20", + "BFD_RELOC_RISCV_TLS_IE_LO12", + "BFD_RELOC_RISCV_TLS_IE_ADD", + "BFD_RELOC_RISCV_TLS_IE_LO12_S", + "BFD_RELOC_RISCV_TLS_IE_LO12_I", + "BFD_RELOC_RISCV_TLS_GOT_HI20", + "BFD_RELOC_RISCV_TLS_GOT_LO12", + "BFD_RELOC_RISCV_TLS_GD_HI20", + "BFD_RELOC_RISCV_TLS_GD_LO12", + "BFD_RELOC_RISCV_TLS_PCREL_LO12", "BFD_RELOC_H8_DIR16A8", "BFD_RELOC_H8_DIR16R8", "BFD_RELOC_H8_DIR24A8", @@ -2313,6 +2370,7 @@ "BFD_RELOC_XC16X_SEG", "BFD_RELOC_XC16X_SOF", "BFD_RELOC_VAX_GLOB_DAT", + "BFD_RELOC_VAX_GLOB_REF", "BFD_RELOC_VAX_JMP_SLOT", "BFD_RELOC_VAX_RELATIVE", "BFD_RELOC_MT_PC16", diff -rNU3 dist.orig/bfd/reloc.c dist/bfd/reloc.c --- dist.orig/bfd/reloc.c 2012-09-04 14:53:42.000000000 +0200 +++ dist/bfd/reloc.c 2015-10-18 13:11:13.000000000 +0200 @@ -1776,6 +1776,17 @@ Relocations used by 68K ELF. ENUM + BFD_RELOC_VAX_GLOB_DAT +ENUMX + BFD_RELOC_VAX_GLOB_REF +ENUMX + BFD_RELOC_VAX_JMP_SLOT +ENUMX + BFD_RELOC_VAX_RELATIVE +ENUMDOC + Relocations used by VAX ELF. + +ENUM BFD_RELOC_32_BASEREL ENUMX BFD_RELOC_16_BASEREL diff -rNU3 dist.orig/bfd/targets.c dist/bfd/targets.c --- dist.orig/bfd/targets.c 2012-09-04 14:53:42.000000000 +0200 +++ dist/bfd/targets.c 2015-10-18 13:11:13.000000000 +0200 @@ -670,13 +670,14 @@ extern const bfd_target bfd_elf32_ntradbigmips_freebsd_vec; extern const bfd_target bfd_elf32_ntradlittlemips_freebsd_vec; extern const bfd_target bfd_elf32_openrisc_vec; -extern const bfd_target bfd_elf32_or32_big_vec; +extern const bfd_target bfd_elf32_or1k_big_vec; extern const bfd_target bfd_elf32_pj_vec; extern const bfd_target bfd_elf32_pjl_vec; extern const bfd_target bfd_elf32_powerpc_vec; extern const bfd_target bfd_elf32_powerpcle_vec; extern const bfd_target bfd_elf32_powerpc_freebsd_vec; extern const bfd_target bfd_elf32_powerpc_vxworks_vec; +extern const bfd_target bfd_elf32_riscv_vec; extern const bfd_target bfd_elf32_rl78_vec; extern const bfd_target bfd_elf32_rx_le_vec; extern const bfd_target bfd_elf32_rx_be_vec; @@ -729,8 +730,8 @@ extern const bfd_target bfd_elf64_alpha_freebsd_vec; extern const bfd_target bfd_elf64_alpha_vec; extern const bfd_target bfd_elf64_big_generic_vec; -extern const bfd_target bfd_elf64_bigmips_vec; extern const bfd_target bfd_elf64_bigaarch64_vec; +extern const bfd_target bfd_elf64_bigmips_vec; extern const bfd_target bfd_elf64_hppa_linux_vec; extern const bfd_target bfd_elf64_hppa_vec; extern const bfd_target bfd_elf64_ia64_big_vec; @@ -738,12 +739,13 @@ extern const bfd_target bfd_elf64_ia64_little_vec; extern const bfd_target bfd_elf64_ia64_vms_vec; extern const bfd_target bfd_elf64_little_generic_vec; -extern const bfd_target bfd_elf64_littlemips_vec; extern const bfd_target bfd_elf64_littleaarch64_vec; +extern const bfd_target bfd_elf64_littlemips_vec; extern const bfd_target bfd_elf64_mmix_vec; extern const bfd_target bfd_elf64_powerpc_vec; extern const bfd_target bfd_elf64_powerpcle_vec; extern const bfd_target bfd_elf64_powerpc_freebsd_vec; +extern const bfd_target bfd_elf64_riscv_vec; extern const bfd_target bfd_elf64_s390_vec; extern const bfd_target bfd_elf64_sh64_vec; extern const bfd_target bfd_elf64_sh64l_vec; @@ -833,7 +835,7 @@ extern const bfd_target nlm32_powerpc_vec; extern const bfd_target nlm32_sparc_vec; extern const bfd_target oasys_vec; -extern const bfd_target or32coff_big_vec; +extern const bfd_target or1kcoff_big_vec; extern const bfd_target pc532machaout_vec; extern const bfd_target pc532netbsd_vec; extern const bfd_target pdp11_aout_vec; @@ -1046,13 +1048,14 @@ &bfd_elf32_ntradlittlemips_freebsd_vec, #endif &bfd_elf32_openrisc_vec, - &bfd_elf32_or32_big_vec, + &bfd_elf32_or1k_big_vec, &bfd_elf32_pj_vec, &bfd_elf32_pjl_vec, &bfd_elf32_powerpc_vec, &bfd_elf32_powerpc_vxworks_vec, &bfd_elf32_powerpcle_vec, &bfd_elf32_powerpc_freebsd_vec, + &bfd_elf32_riscv_vec, &bfd_elf32_rl78_vec, &bfd_elf32_rx_be_vec, &bfd_elf32_rx_be_ns_vec, @@ -1106,8 +1109,8 @@ &bfd_elf64_alpha_freebsd_vec, &bfd_elf64_alpha_vec, &bfd_elf64_big_generic_vec, - &bfd_elf64_bigmips_vec, &bfd_elf64_bigaarch64_vec, + &bfd_elf64_bigmips_vec, &bfd_elf64_hppa_linux_vec, &bfd_elf64_hppa_vec, &bfd_elf64_ia64_big_vec, @@ -1115,12 +1118,13 @@ &bfd_elf64_ia64_little_vec, &bfd_elf64_ia64_vms_vec, &bfd_elf64_little_generic_vec, - &bfd_elf64_littlemips_vec, &bfd_elf64_littleaarch64_vec, + &bfd_elf64_littlemips_vec, &bfd_elf64_mmix_vec, &bfd_elf64_powerpc_vec, &bfd_elf64_powerpcle_vec, &bfd_elf64_powerpc_freebsd_vec, + &bfd_elf64_riscv_vec, &bfd_elf64_s390_vec, &bfd_elf64_sh64_vec, &bfd_elf64_sh64l_vec, @@ -1252,7 +1256,7 @@ &oasys_vec, #endif /* Entry for the OpenRISC family. */ - &or32coff_big_vec, + &or1kcoff_big_vec, &pc532machaout_vec, &pc532netbsd_vec, diff -rNU3 dist.orig/binutils/Makefile.in dist/binutils/Makefile.in --- dist.orig/binutils/Makefile.in 2012-05-18 00:23:39.000000000 +0200 +++ dist/binutils/Makefile.in 2015-10-18 13:11:13.000000000 +0200 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -49,10 +49,12 @@ DIST_COMMON = NEWS README ChangeLog $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(srcdir)/config.in \ - $(srcdir)/../mkinstalldirs $(top_srcdir)/po/Make-in arparse.h \ - arparse.c arlex.c defparse.h defparse.c deflex.c nlmheader.h \ - nlmheader.c arparse.h arparse.c arlex.c mcparse.h mcparse.c \ - rcparse.h rcparse.c $(srcdir)/../depcomp $(srcdir)/../ylwrap + $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs \ + $(top_srcdir)/po/Make-in arparse.h arparse.c arlex.c \ + defparse.h defparse.c deflex.c nlmheader.h nlmheader.c \ + arparse.h arparse.c arlex.c mcparse.h mcparse.c rcparse.h \ + rcparse.c $(srcdir)/../depcomp $(srcdir)/../depcomp \ + $(srcdir)/../ylwrap $(srcdir)/../ylwrap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/zlib.m4 \ @@ -385,6 +387,7 @@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -931,7 +934,7 @@ # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ + @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -956,7 +959,7 @@ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ + @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ diff -rNU3 dist.orig/binutils/aclocal.m4 dist/binutils/aclocal.m4 --- dist.orig/binutils/aclocal.m4 2012-05-18 00:23:39.000000000 +0200 +++ dist/binutils/aclocal.m4 2015-10-18 13:11:13.000000000 +0200 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.11 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. @@ -19,6 +19,31 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) + # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation @@ -34,7 +59,7 @@ [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.1], [], +m4_if([$1], [1.11], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -50,7 +75,7 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.1])dnl +[AM_AUTOMAKE_VERSION([1.11])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) diff -rNU3 dist.orig/binutils/bucomm.c dist/binutils/bucomm.c --- dist.orig/binutils/bucomm.c 2012-06-29 14:59:49.000000000 +0200 +++ dist/binutils/bucomm.c 2015-10-18 13:11:13.000000000 +0200 @@ -580,7 +580,14 @@ file_name, strerror (errno)); } else if (! S_ISREG (statbuf.st_mode)) - non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); + { + if (!S_ISCHR(statbuf.st_mode)) + { + non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); + return 0; + } + return statbuf.st_size ? statbuf.st_size : 1; + } else if (statbuf.st_size < 0) non_fatal (_("Warning: '%s' has negative size, probably it is too large"), file_name); diff -rNU3 dist.orig/binutils/doc/Makefile.am dist/binutils/doc/Makefile.am --- dist.orig/binutils/doc/Makefile.am 2010-01-06 17:52:14.000000000 +0100 +++ dist/binutils/doc/Makefile.am 2015-10-18 13:11:13.000000000 +0200 @@ -42,6 +42,8 @@ # Man page generation from texinfo addr2line.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_addr2line.1: touch $@ -$(TEXI2POD) $(MANCONF) -Daddr2line < $(binutils_TEXI) > addr2line.pod -($(POD2MAN) addr2line.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -49,6 +51,8 @@ rm -f addr2line.pod ar.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ar.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dar < $(binutils_TEXI) > ar.pod -($(POD2MAN) ar.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -56,6 +60,8 @@ rm -f ar.pod dlltool.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_dlltool.1: touch $@ -$(TEXI2POD) $(MANCONF) -Ddlltool < $(binutils_TEXI) > dlltool.pod -($(POD2MAN) dlltool.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -63,6 +69,8 @@ rm -f dlltool.pod nlmconv.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_nlmconv.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dnlmconv < $(binutils_TEXI) > nlmconv.pod -($(POD2MAN) nlmconv.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -70,6 +78,8 @@ rm -f nlmconv.pod nm.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_nm.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dnm < $(binutils_TEXI) > nm.pod -($(POD2MAN) nm.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -77,6 +87,8 @@ rm -f nm.pod objcopy.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_objcopy.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dobjcopy < $(binutils_TEXI) > objcopy.pod -($(POD2MAN) objcopy.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -84,6 +96,8 @@ rm -f objcopy.pod objdump.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_objdump.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dobjdump < $(binutils_TEXI) > objdump.pod -($(POD2MAN) objdump.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -91,6 +105,8 @@ rm -f objdump.pod ranlib.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ranlib.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dranlib < $(binutils_TEXI) > ranlib.pod -($(POD2MAN) ranlib.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -98,6 +114,8 @@ rm -f ranlib.pod readelf.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_readelf.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dreadelf < $(binutils_TEXI) > readelf.pod -($(POD2MAN) readelf.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -105,6 +123,8 @@ rm -f readelf.pod size.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_size.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dsize < $(binutils_TEXI) > size.pod -($(POD2MAN) size.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -112,6 +132,8 @@ rm -f size.pod strings.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_strings.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dstrings < $(binutils_TEXI) > strings.pod -($(POD2MAN) strings.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -119,6 +141,8 @@ rm -f strings.pod strip.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_strip.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dstrip < $(binutils_TEXI) > strip.pod -($(POD2MAN) strip.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -133,6 +157,8 @@ rm -f elfedit.pod windres.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_windres.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dwindres < $(binutils_TEXI) > windres.pod -($(POD2MAN) windres.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -140,6 +166,8 @@ rm -f windres.pod windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_windmc.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -147,6 +175,8 @@ rm -f windmc.pod cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_cxxfilt.man: touch $@ -$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod -($(POD2MAN) $(DEMANGLER_NAME).pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ diff -rNU3 dist.orig/binutils/doc/Makefile.in dist/binutils/doc/Makefile.in --- dist.orig/binutils/doc/Makefile.in 2012-09-04 14:53:44.000000000 +0200 +++ dist/binutils/doc/Makefile.in 2015-10-18 13:11:13.000000000 +0200 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -242,6 +242,7 @@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -349,6 +350,8 @@ -rm -rf .libs _libs binutils.info: binutils.texi + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_binutils.info: binutils.texi restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ @@ -735,6 +738,8 @@ # Man page generation from texinfo addr2line.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_addr2line.1: touch $@ -$(TEXI2POD) $(MANCONF) -Daddr2line < $(binutils_TEXI) > addr2line.pod -($(POD2MAN) addr2line.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -742,6 +747,8 @@ rm -f addr2line.pod ar.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ar.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dar < $(binutils_TEXI) > ar.pod -($(POD2MAN) ar.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -749,6 +756,8 @@ rm -f ar.pod dlltool.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_dlltool.1: touch $@ -$(TEXI2POD) $(MANCONF) -Ddlltool < $(binutils_TEXI) > dlltool.pod -($(POD2MAN) dlltool.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -756,6 +765,8 @@ rm -f dlltool.pod nlmconv.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_nlmconv.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dnlmconv < $(binutils_TEXI) > nlmconv.pod -($(POD2MAN) nlmconv.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -763,6 +774,8 @@ rm -f nlmconv.pod nm.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_nm.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dnm < $(binutils_TEXI) > nm.pod -($(POD2MAN) nm.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -770,6 +783,8 @@ rm -f nm.pod objcopy.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_objcopy.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dobjcopy < $(binutils_TEXI) > objcopy.pod -($(POD2MAN) objcopy.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -777,6 +792,8 @@ rm -f objcopy.pod objdump.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_objdump.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dobjdump < $(binutils_TEXI) > objdump.pod -($(POD2MAN) objdump.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -784,6 +801,8 @@ rm -f objdump.pod ranlib.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ranlib.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dranlib < $(binutils_TEXI) > ranlib.pod -($(POD2MAN) ranlib.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -791,6 +810,8 @@ rm -f ranlib.pod readelf.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_readelf.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dreadelf < $(binutils_TEXI) > readelf.pod -($(POD2MAN) readelf.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -798,6 +819,8 @@ rm -f readelf.pod size.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_size.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dsize < $(binutils_TEXI) > size.pod -($(POD2MAN) size.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -805,6 +828,8 @@ rm -f size.pod strings.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_strings.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dstrings < $(binutils_TEXI) > strings.pod -($(POD2MAN) strings.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -812,6 +837,8 @@ rm -f strings.pod strip.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_strip.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dstrip < $(binutils_TEXI) > strip.pod -($(POD2MAN) strip.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -819,6 +846,8 @@ rm -f strip.pod elfedit.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_elfedit.1: touch $@ -$(TEXI2POD) $(MANCONF) -Delfedit < $(binutils_TEXI) > elfedit.pod -($(POD2MAN) elfedit.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -826,6 +855,8 @@ rm -f elfedit.pod windres.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_windres.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dwindres < $(binutils_TEXI) > windres.pod -($(POD2MAN) windres.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -833,6 +864,8 @@ rm -f windres.pod windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_windmc.1: touch $@ -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ @@ -840,6 +873,8 @@ rm -f windmc.pod cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_cxxfilt.man: touch $@ -$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod -($(POD2MAN) $(DEMANGLER_NAME).pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ diff -rNU3 dist.orig/binutils/doc/readelf.1 dist/binutils/doc/readelf.1 --- dist.orig/binutils/doc/readelf.1 2013-03-25 10:10:25.000000000 +0100 +++ dist/binutils/doc/readelf.1 2015-10-18 13:11:13.000000000 +0200 @@ -146,6 +146,7 @@ [\fB\-r\fR|\fB\-\-relocs\fR] [\fB\-u\fR|\fB\-\-unwind\fR] [\fB\-d\fR|\fB\-\-dynamic\fR] + [\fB\-f\fR|\fB\-\-special-files\fR] [\fB\-V\fR|\fB\-\-version\-info\fR] [\fB\-A\fR|\fB\-\-arch\-specific\fR] [\fB\-D\fR|\fB\-\-use\-dynamic\fR] @@ -282,6 +283,13 @@ .IX Item "--dynamic" .PD Displays the contents of the file's dynamic section, if it has one. +.IP "\fB\-f\fR" 4 +.IX Item "-f" +.PD 0 +.IP "\fB\-\-special-files\fR" 4 +.IX Item "--special-files" +.PD +Allows processing of non-plain files. .IP "\fB\-V\fR" 4 .IX Item "-V" .PD 0 diff -rNU3 dist.orig/binutils/doc/strings.1 dist/binutils/doc/strings.1 --- dist.orig/binutils/doc/strings.1 2013-03-25 10:10:26.000000000 +0100 +++ dist/binutils/doc/strings.1 2015-10-18 13:11:13.000000000 +0200 @@ -208,7 +208,7 @@ characters (\s-1ASCII\s0, \s-1ISO\s0 8859, etc., default), \fBS\fR = single\-8\-bit\-byte characters, \fBb\fR = 16\-bit bigendian, \fBl\fR = 16\-bit littleendian, \fBB\fR = 32\-bit bigendian, \fBL\fR = 32\-bit -littleendian. Useful for finding wide character strings. (\fBl\fR +littleendian. Useful for finding wide-character strings. (\fBl\fR and \fBb\fR apply to, for example, Unicode \s-1UTF\-16/UCS\-2\s0 encodings). .IP "\fB\-T\fR \fIbfdname\fR" 4 .IX Item "-T bfdname" diff -rNU3 dist.orig/binutils/objcopy.c dist/binutils/objcopy.c --- dist.orig/binutils/objcopy.c 2013-03-25 09:06:21.000000000 +0100 +++ dist/binutils/objcopy.c 2015-10-18 13:11:13.000000000 +0200 @@ -30,6 +30,8 @@ #include "filenames.h" #include "fnmatch.h" #include "elf-bfd.h" +#include +#include #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" diff -rNU3 dist.orig/binutils/readelf.c dist/binutils/readelf.c --- dist.orig/binutils/readelf.c 2013-03-25 09:06:21.000000000 +0100 +++ dist/binutils/readelf.c 2015-10-18 13:11:13.000000000 +0200 @@ -126,13 +126,14 @@ #include "elf/mep.h" #include "elf/microblaze.h" #include "elf/mips.h" +#include "elf/riscv.h" #include "elf/mmix.h" #include "elf/mn10200.h" #include "elf/mn10300.h" #include "elf/moxie.h" #include "elf/mt.h" #include "elf/msp430.h" -#include "elf/or32.h" +#include "elf/or1k.h" #include "elf/pj.h" #include "elf/ppc.h" #include "elf/ppc64.h" @@ -184,6 +185,7 @@ static Elf_Internal_Dyn * dynamic_section; static Elf_Internal_Shdr * symtab_shndx_hdr; static int show_name; +static int do_special_files; static int do_dynamic; static int do_syms; static int do_dyn_syms; @@ -555,8 +557,7 @@ case EM_MIPS: case EM_MIPS_RS3_LE: case EM_CYGNUS_M32R: - case EM_OPENRISC: - case EM_OR32: + case EM_OR1K: case EM_SCORE: case EM_XGATE: return FALSE; @@ -604,6 +605,7 @@ case EM_NIOS32: case EM_PPC64: case EM_PPC: + case EM_RISCV: case EM_RL78: case EM_RX: case EM_S390: @@ -1134,9 +1136,8 @@ rtype = elf_h8_reloc_type (type); break; - case EM_OPENRISC: - case EM_OR32: - rtype = elf_or32_reloc_type (type); + case EM_OR1K: + rtype = elf_or1k_reloc_type (type); break; case EM_PJ: @@ -1234,6 +1235,10 @@ rtype = elf_microblaze_reloc_type (type); break; + case EM_RISCV: + rtype = elf_riscv_reloc_type (type); + break; + case EM_RL78: rtype = elf_rl78_reloc_type (type); break; @@ -1941,8 +1946,7 @@ case EM_S390: return "IBM S/390"; case EM_SCORE: return "SUNPLUS S+Core"; case EM_XSTORMY16: return "Sanyo XStormy16 CPU core"; - case EM_OPENRISC: - case EM_OR32: return "OpenRISC"; + case EM_OR1K: return "OpenRISC"; case EM_ARC_A5: return "ARC International ARCompact processor"; case EM_CRX: return "National Semiconductor CRX microprocessor"; case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY"; @@ -2005,6 +2009,7 @@ case EM_CR16: case EM_MICROBLAZE: case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze"; + case EM_RISCV: return "RISC-V"; case EM_RL78: return "Renesas RL78"; case EM_RX: return "Renesas RX"; case EM_METAG: return "Imagination Technologies META processor architecture"; @@ -2488,6 +2493,14 @@ strcat (buf, ", fdpic"); break; + case EM_RISCV: + { + unsigned int riscv_extension = EF_GET_RISCV_EXT(e_flags); + strcat (buf, ", "); + strcat (buf, riscv_elf_flag_to_name (riscv_extension)); + } + break; + case EM_SH: switch ((e_flags & EF_SH_MACH_MASK)) { @@ -3198,6 +3211,7 @@ {"relocs", no_argument, 0, 'r'}, {"notes", no_argument, 0, 'n'}, {"dynamic", no_argument, 0, 'd'}, + {"special-files", no_argument, 0, 'f'}, {"arch-specific", no_argument, 0, 'A'}, {"version-info", no_argument, 0, 'V'}, {"use-dynamic", no_argument, 0, 'D'}, @@ -3243,6 +3257,7 @@ -r --relocs Display the relocations (if present)\n\ -u --unwind Display the unwind info (if present)\n\ -d --dynamic Display the dynamic section (if present)\n\ + -f --special-files Process non-plain files too\n\ -V --version-info Display the version sections (if present)\n\ -A --arch-specific Display architecture specific information (if any)\n\ -c --archive-index Display the symbol/file index in an archive\n\ @@ -3362,7 +3377,7 @@ usage (stderr); while ((c = getopt_long - (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF) + (argc, argv, "ADHINR:SVWacdefghi:lnp:rstuvw::x:", options, NULL)) != EOF) { switch (c) { @@ -3412,6 +3427,9 @@ case 'u': do_unwind++; break; + case 'f': + do_special_files++; + break; case 'h': do_header++; break; @@ -3801,7 +3819,7 @@ if (elf_header.e_phnum > 1) printf (_("\nProgram Headers:\n")); else - printf (_("\nProgram Headers:\n")); + printf (_("\nProgram Header:\n")); if (is_32bit_elf) printf @@ -6974,6 +6992,11 @@ remaining = 4; } + else + { + addr.section = SHN_UNDEF; + addr.offset = 0; + } if ((word & 0x80000000) == 0) { @@ -8842,6 +8865,20 @@ } static const char * +get_alpha_symbol_other (unsigned int other) +{ + switch (other) + { + case STO_ALPHA_NOPV: + return "NOPV"; + case STO_ALPHA_STD_GPLOAD: + return "STD GPLOAD"; + default: + return NULL; + } +} + +static const char * get_mips_symbol_other (unsigned int other) { switch (other) @@ -8935,6 +8972,9 @@ switch (elf_header.e_machine) { + case EM_ALPHA: + result = get_alpha_symbol_other (other); + break; case EM_MIPS: result = get_mips_symbol_other (other); break; @@ -9902,9 +9942,8 @@ case EM_ALTERA_NIOS2: case EM_NIOS32: return reloc_type == 1; /* R_NIOS_32. */ - case EM_OPENRISC: - case EM_OR32: - return reloc_type == 1; /* R_OR32_32. */ + case EM_OR1K: + return reloc_type == 1; /* R_OR1K_32. */ case EM_PARISC: return (reloc_type == 1 /* R_PARISC_DIR32. */ || reloc_type == 41); /* R_PARISC_SECREL32. */ @@ -9915,6 +9954,8 @@ return reloc_type == 1; /* R_PPC64_ADDR32. */ case EM_PPC: return reloc_type == 1; /* R_PPC_ADDR32. */ + case EM_RISCV: + return reloc_type == 1; /* R_RISCV_32. */ case EM_RL78: return reloc_type == 1; /* R_RL78_DIR32. */ case EM_RX: @@ -10015,6 +10056,8 @@ case EM_L1OM: case EM_K1OM: return reloc_type == 2; /* R_X86_64_PC32. */ + case EM_VAX: + return reloc_type == 4; /* R_VAX_PCREL32. */ case EM_XTENSA_OLD: case EM_XTENSA: return reloc_type == 14; /* R_XTENSA_32_PCREL. */ @@ -10046,6 +10089,8 @@ return reloc_type == 80; /* R_PARISC_DIR64. */ case EM_PPC64: return reloc_type == 38; /* R_PPC64_ADDR64. */ + case EM_RISCV: + return reloc_type == 2; /* R_RISCV_64. */ case EM_SPARC32PLUS: case EM_SPARCV9: case EM_SPARC: @@ -10187,6 +10232,7 @@ case EM_ADAPTEVA_EPIPHANY: case EM_PPC: /* R_PPC_NONE. */ case EM_PPC64: /* R_PPC64_NONE. */ + case EM_RISCV: /* R_RISCV_NONE. */ case EM_ARM: /* R_ARM_NONE. */ case EM_IA_64: /* R_IA64_NONE. */ case EM_SH: /* R_SH_NONE. */ @@ -12665,6 +12711,48 @@ return buff; } +static int +process_netbsd_elf_note (Elf_Internal_Note * pnote) +{ + unsigned int version; + + switch (pnote->type) + { + case NT_NETBSD_IDENT: + version = byte_get((unsigned char *)pnote->descdata, sizeof(version)); + if ((version / 10000) % 100) + printf (" NetBSD\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz, + version, version / 100000000, (version / 1000000) % 100, + (version / 10000) % 100 > 26 ? "Z" : "", + 'A' + (version / 10000) % 26); + else + printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz, + version, version / 100000000, (version / 1000000) % 100, + (version / 100) % 100); + return 1; + case NT_NETBSD_MARCH: + printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz, + pnote->descdata); + return 1; + case NT_NETBSD_PAX: + version = byte_get((unsigned char *)pnote->descdata, sizeof(version)); + printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz, + ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""), + ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""), + ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""), + ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""), + ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""), + ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : "")); + return 1; + default: + break; + } + + printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz, + pnote->type); + return 1; +} + static int print_gnu_note (Elf_Internal_Note *pnote) { @@ -12765,6 +12853,23 @@ } break; + /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5. + There's also old PT___GETREGS40 == mach + 1 for old reg + structure which lacks GBR. */ + case EM_SH: + switch (e_type) + { + case NT_NETBSDCORE_FIRSTMACH + 1: + return _("PT___GETREGS40 (old reg structure)"); + case NT_NETBSDCORE_FIRSTMACH + 3: + return _("PT_GETREGS (reg structure)"); + case NT_NETBSDCORE_FIRSTMACH + 5: + return _("PT_GETFPREGS (fpreg structure)"); + default: + break; + } + break; + /* On all other arch's, PT_GETREGS == mach+1 and PT_GETFPREGS == mach+3. */ default: @@ -12971,6 +13076,14 @@ /* GNU-specific object file notes. */ nt = get_gnu_elf_note_type (pnote->type); + else if (const_strneq (pnote->namedata, "NetBSD")) + /* NetBSD-specific core file notes. */ + return process_netbsd_elf_note (pnote); + + else if (const_strneq (pnote->namedata, "PaX")) + /* NetBSD-specific core file notes. */ + return process_netbsd_elf_note (pnote); + else if (const_strneq (pnote->namedata, "NetBSD-CORE")) /* NetBSD-specific core file notes. */ nt = get_netbsd_elfcore_note_type (pnote->type); @@ -13710,7 +13823,7 @@ return 1; } - if (! S_ISREG (statbuf.st_mode)) + if (!do_special_files && ! S_ISREG (statbuf.st_mode)) { error (_("'%s' is not an ordinary file\n"), file_name); return 1; diff -rNU3 dist.orig/binutils/strings.c dist/binutils/strings.c --- dist.orig/binutils/strings.c 2012-02-09 05:51:44.000000000 +0100 +++ dist/binutils/strings.c 2015-10-18 13:11:13.000000000 +0200 @@ -598,7 +598,7 @@ else #elif !BFD_HOST_64BIT_LONG if (start != (unsigned long) start) - printf ("++%7ld ", (unsigned long) start); + printf ("++%7llu ", (unsigned long) start); else #endif printf ("%7ld ", (long) start); diff -rNU3 dist.orig/config.guess dist/config.guess --- dist.orig/config.guess 2011-06-06 12:36:06.000000000 +0200 +++ dist/config.guess 2015-10-18 13:11:13.000000000 +0200 @@ -160,14 +160,28 @@ case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; + coldfire) machine=m5407-unknown ;; + earm*eb*) machine=armeb-unknown ;; + earm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently, or will in the future and ABI. case "${UNAME_MACHINE_ARCH}" in + coldfire) os=netbsdelf ;; + earm*) + eval $set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + os=netbsdelf-eabi + else + os=netbsdelf-eabihf + fi + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ diff -rNU3 dist.orig/config.sub dist/config.sub --- dist.orig/config.sub 2012-04-25 17:53:25.000000000 +0200 +++ dist/config.sub 2015-10-18 13:11:13.000000000 +0200 @@ -122,9 +122,9 @@ # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | \ + netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -300,7 +300,7 @@ | nios | nios2 \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or1knd \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -332,12 +332,21 @@ basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | m5407 \ + | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; + riscv32-*) + basic_machine=riscv32-ucb + ;; + + riscv*-*) + basic_machine=riscv-ucb + ;; + strongarm | thumb | xscale) basic_machine=arm-unknown ;; @@ -375,7 +384,7 @@ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ @@ -388,6 +397,7 @@ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ + | m5200-* | m5407-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ @@ -528,15 +538,6 @@ basic_machine=powerpc-ibm os=-cnk ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; c90) basic_machine=c90-cray os=-unicos @@ -916,8 +917,11 @@ basic_machine=hppa1.1-oki os=-proelf ;; - openrisc | openrisc-*) - basic_machine=or32-unknown + or1k | or1k-*) + basic_machine=or1k-unknown + ;; + or1knd | or1knd-*) + basic_machine=or1knd-unknown ;; os400) basic_machine=powerpc-ibm @@ -1543,15 +1547,6 @@ c4x-* | tic4x-*) os=-coff ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1583,8 +1578,11 @@ mips*-*) os=-elf ;; - or32-*) - os=-coff + or1k-*) + os=-elf + ;; + or1knd-*) + os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 diff -rNU3 dist.orig/cpu/openrisc.cpu dist/cpu/openrisc.cpu --- dist.orig/cpu/openrisc.cpu 2011-08-22 17:25:07.000000000 +0200 +++ dist/cpu/openrisc.cpu 1970-01-01 01:00:00.000000000 +0100 @@ -1,774 +0,0 @@ -; OpenRISC family. -*- Scheme -*- -; Copyright 2000, 2001, 2011 Free Software Foundation, Inc. -; Contributed by Johan Rydberg, jrydberg@opencores.org -; -; 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. - -(include "simplify.inc") - -; OpenRISC 1000 is an architecture of a family of open source, -; synthesizeable RISC microprocessor cores. It is a 32-bit load -; and store RISC architecture designed with emphasis on speed, -; compact instruction set and scalability. OpenRISC 1000 targets -; wide range of embedded environments. - -(define-arch - (name openrisc) - (comment "OpenRISC 1000") - (insn-lsb0? #t) - (machs openrisc or1300) - (isas or32) -) - - -; Attributes - -; An attribute to describe if a model has insn and/or data caches. -(define-attr - (for model) - (type enum) - (name HAS-CACHE) - (comment "if this model has caches") - (values DATA-CACHE INSN-CACHE) -) - -; An attribute to describe if an insn can be in the delay slot or not. -(define-attr - (for insn) - (type boolean) - (name NOT-IN-DELAY-SLOT) - (comment "insn can't go in delay slot") -) - -; IDOC attribute for instruction documentation. - -(define-attr - (for insn) - (type enum) - (name IDOC) - (comment "insn kind for documentation") - (attrs META) - (values - (MEM - () "Memory") - (ALU - () "ALU") - (FPU - () "FPU") - (BR - () "Branch") - (PRIV - () "Priviledged") - (MISC - () "Miscellaneous") - ) -) - -; Enum for exception vectors. -(define-enum - (name e-exception) - (comment "exception vectors") - (attrs) - (prefix E_) - (values (("RESET") ("BUSERR" -) ("DPF" -) ("IPF" -) ("EXTINT" -) ("ALIGN" -) - ("ILLEGAL" -) ("PEINT" -) ("DTLBMISS" -) ("ITLBMISS" -) ("RRANGE" -) - ("SYSCALL" -) ("BREAK" -) ("RESERVED" -))) -) - - -; Instruction set parameters. - -(define-isa - ; Name of the ISA. - (name or32) - - ; Base insturction length. The insns is always 32 bits wide. - (base-insn-bitsize 32) - - ; Address of insn in delay slot - (setup-semantics (set-quiet (reg h-delay-insn) (add pc 4))) -) - - -; CPU family definitions. - -(define-cpu - ; CPU names must be distinct from the architecture name and machine names. - ; The "b" suffix stands for "base" and is the convention. - ; The "f" suffix stands for "family" and is the convention. - (name openriscbf) - (comment "OpenRISC base family") - (endian big) - (word-bitsize 32) -) - -; Generic machine -(define-mach - (name openrisc) - (comment "Generic OpenRISC cpu") - (cpu openriscbf) - (bfd-name "openrisc") -) - -; OpenRISC 1300 machine -(define-mach - (name or1300) - (comment "OpenRISC 1300") - (cpu openriscbf) - (bfd-name "openrisc:1300") -) - - -; Model descriptions - -; Generic OpenRISC model -(define-model - (name openrisc-1) (comment "OpenRISC generic model") (attrs) - (mach openrisc) - - ; Nothing special about this. - (unit u-exec "Execution Unit" () 1 1 () () () ()) -) - -; OpenRISC 1320 -(define-model - (name or1320-1) (comment "OpenRISC 1320 model") - - ; This model has both instruction and data cache - (attrs (HAS-CACHE INSN-CACHE,DATA-CACHE)) - (mach or1300) - - ; Nothing special about this. - (unit u-exec "Execution Unit" () 1 1 () () () ()) -) - - -; Instruction fields. - -; Attributes: -; . PCREL-ADDR pc relative value (for reloc and disassembly purposes) -; . ABS-ADDR absolute address (for reloc and disassembly purposes?) -; . RESERVED bits are not used to decode insn, must be all 0 - -; Instruction classes. -(dnf f-class "insn class" () 31 2) -(dnf f-sub "sub class" () 29 4) - -; Register fields. -(dnf f-r1 "r1" () 25 5) -(dnf f-r2 "r2" () 20 5) -(dnf f-r3 "r3" () 15 5) - -; Immediates. -(df f-simm16 "signed imm (16)" () 15 16 INT #f #f) -(dnf f-uimm16 "unsigned imm (16)" () 15 16) -(dnf f-uimm5 "unsigned imm (5)" () 4 5) -(df f-hi16 "high 16" () 15 16 INT #f #f) -(df f-lo16 "low 16" () 15 16 INT #f #f) - -; Sub fields -(dnf f-op1 "op1" () 31 2) -(dnf f-op2 "op2" () 29 4) -(dnf f-op3 "op3" () 25 2) -(dnf f-op4 "op4" () 23 3) -(dnf f-op5 "op3" () 25 5) -(dnf f-op6 "op4" () 7 3) -(dnf f-op7 "op5" () 3 4) - -(dnf f-i16-1 "uimm16-1" () 10 11) -(dnf f-i16-2 "uimm16-2" () 25 5) - -; PC relative, 26-bit (2 shifted to right) -(df f-disp26 "disp26" (PCREL-ADDR) 25 26 INT - ((value pc) (sra WI (sub WI value pc) (const 2))) - ((value pc) (add WI (sll WI value (const 2)) pc))) - -; absolute, 26-bit (2 shifted to right) -(df f-abs26 "abs26" (ABS-ADDR) 25 26 INT - ((value pc) (sra WI pc (const 2))) - ((value pc) (sll WI value (const 2)))) - -(define-multi-ifield - (name f-i16nc) - (comment "16 bit signed") - (attrs SIGN-OPT) - (mode HI) - (subfields f-i16-1 f-i16-2) - (insert (sequence () - (set (ifield f-i16-2) (and (sra (ifield f-i16nc) - (const 11)) - (const #x1f))) - (set (ifield f-i16-1) (and (ifield f-i16nc) - (const #x7ff))))) - (extract (sequence () - (set (ifield f-i16nc) (c-raw-call SI "@arch@_sign_extend_16bit" - (or (sll (ifield f-i16-2) - (const 11)) - (ifield f-i16-1)))))) -) - - -; Enums. - -; insn-class: bits 31-30 -(define-normal-insn-enum insn-class "FIXME" () OP1_ f-class - (.map .str (.iota 4)) -) - -(define-normal-insn-enum insn-sub "FIXME" () OP2_ f-sub - (.map .str (.iota 16)) -) - -(define-normal-insn-enum insn-op3 "FIXME" () OP3_ f-op3 - (.map .str (.iota 4)) -) - -(define-normal-insn-enum insn-op4 "FIXME" () OP4_ f-op4 - (.map .str (.iota 8)) -) - -(define-normal-insn-enum insn-op5 "FIXME" () OP5_ f-op5 - (.map .str (.iota 32)) -) - -(define-normal-insn-enum insn-op6 "FIXME" () OP6_ f-op6 - (.map .str (.iota 8)) -) - -(define-normal-insn-enum insn-op7 "FIXME" () OP7_ f-op7 - (.map .str (.iota 16)) -) - - - -; Hardware pieces. -; These entries list the elements of the raw hardware. -; They're also used to provide tables and other elements of the assembly -; language. - -(dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) - -(define-hardware - (name h-gr) (comment "general registers") (attrs PROFILE) - (type register WI (32)) - (indices keyword "" - ((r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) (r7 7) - (r8 8) (r9 9) (r10 10) (r11 11) (r12 12) (r13 13) (r14 14) - (r15 15) (r16 16) (r17 17) (r18 18) (r19 19) (r20 20) - (r21 21) (r22 22) (r23 23) (r24 24) (r25 25) (r26 26) - (r27 27) (r28 28) (r29 29) (r30 30) (r31 31) (lr 11) - (sp 1) (fp 2))) -) - -(define-hardware - (name h-sr) (comment "special registers") - (type register WI (#x20000)) - (get (index) (c-call SI "@arch@_h_sr_get_handler" index)) - (set (index newval) (c-call VOID "@arch@_h_sr_set_handler" index newval)) -) - -(dnh h-hi16 "high 16 bits" () (immediate (INT 16)) () () ()) -(dnh h-lo16 "low 16 bits" () (immediate (INT 16)) () () ()) - -(dsh h-cbit "condition bit" () (register BI)) -(dsh h-delay-insn "delay insn addr" () (register SI)) - - -; Instruction operands. - -(dnop sr "special register" (SEM-ONLY) h-sr f-nil) -(dnop cbit "condition bit" (SEM-ONLY) h-cbit f-nil) -(dnop simm-16 "16 bit signed immediate" () h-sint f-simm16) -(dnop uimm-16 "16 bit unsigned immediate" () h-uint f-uimm16) -(dnop disp-26 "pc-rel 26 bit" () h-iaddr f-disp26) -(dnop abs-26 "abs 26 bit" () h-iaddr f-abs26) -(dnop uimm-5 "imm5" () h-uint f-uimm5) - -(dnop rD "destination register" () h-gr f-r1) -(dnop rA "source register A" () h-gr f-r2) -(dnop rB "source register B" () h-gr f-r3) - -(dnop op-f-23 "f-op23" () h-uint f-op4) -(dnop op-f-3 "f-op3" () h-uint f-op5) - -; For hi(foo). -(define-operand - (name hi16) (comment "high 16 bit immediate, sign optional") - (attrs SIGN-OPT) - (type h-hi16) - (index f-simm16) - (handlers (parse "hi16")) -) - -; For lo(foo) -(define-operand - (name lo16) (comment "low 16 bit immediate, sign optional") - (attrs SIGN-OPT) - (type h-lo16) - (index f-lo16) - (handlers (parse "lo16")) -) - -(define-operand - (name ui16nc) - (comment "16 bit immediate, sign optional") - (attrs) - (type h-lo16) - (index f-i16nc) - (handlers (parse "lo16")) -) - - -; Instructions. - -; Branch releated instructions - -(dni l-j "jump (absolute iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.j ${abs-26}" - (+ OP1_0 OP2_0 abs-26) - - ; We execute the delay slot before doin' the real branch - (delay 1 (set pc abs-26)) - () -) - -(dni l-jal "jump and link (absolute iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.jal ${abs-26}" - (+ OP1_0 OP2_1 abs-26) - - ; We execute the delay slot before doin' the real branch - ; Set LR to (delay insn addr + 4) - (sequence () - (set (reg h-gr 11) (add (reg h-delay-insn) 4)) - (delay 1 (set pc abs-26))) - () -) - -(dni l-jr "jump register (absolute iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.jr $rA" - (+ OP1_0 OP2_5 OP3_0 OP4_0 rA uimm-16) - - ; We execute the delay slot before doin' the real branch - (delay 1 (set pc rA)) - () -) - -(dni l-jalr "jump register and link (absolute iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.jalr $rA" - (+ OP1_0 OP2_5 OP3_0 OP4_1 rA uimm-16) - - ; We save the value of rA in a temporary slot before setting - ; the link register. This because "l.jalr r11" would cause - ; a forever-and-ever loop otherwise. - ; - ; We execute the delay slot before doin' the real branch - (sequence ((WI tmp-slot)) - (set tmp-slot rA) - (set (reg h-gr 11) (add (reg h-delay-insn) 4)) - (delay 1 (set pc tmp-slot))) - () -) - -(dni l-bal "branch and link (pc relative iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.bal ${disp-26}" - (+ OP1_0 OP2_2 disp-26) - - ; We execute the delay slot before doin' the real branch - ; Set LR to (delay insn addr + 4) - (sequence () - (set (reg h-gr 11) (add (reg h-delay-insn) 4)) - (delay 1 (set pc disp-26))) - () -) - -(dni l-bnf "branch if condition bit not set (pc relative iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.bnf ${disp-26}" - (+ OP1_0 OP2_3 disp-26) - - ; We execute the delay slot before doin' the real branch - (if (eq cbit 0) - (sequence () - (delay 1 (set pc disp-26)))) - () -) - -(dni l-bf "branch if condition bit is set (pc relative iaddr)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.bf ${disp-26}" - (+ OP1_0 OP2_4 disp-26) - - ; We execute the delay slot before doin' the real branch - (if (eq cbit 1) - (sequence () - (delay 1 (set pc disp-26)))) - () -) - -(dni l-brk "break (exception)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.brk ${uimm-16}" - (+ OP1_0 OP2_5 OP3_3 OP4_0 rA uimm-16) - - ; FIXME should we do it like this ?? - (c-call VOID "@cpu@_cpu_brk" uimm-16) - () -) - -(dni l-rfe "return from exception" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.rfe $rA" - (+ OP1_0 OP2_5 OP3_0 OP4_2 rA uimm-16) - (sequence () - (delay 1 (set pc (c-call SI "@cpu@_cpu_rfe" rA)))) - () -) - -(dni l-sys "syscall (exception)" - ; This function may not be in delay slot - (NOT-IN-DELAY-SLOT) - - "l.sys ${uimm-16}" - (+ OP1_0 OP2_5 OP3_2 OP4_0 rA uimm-16) - (sequence() - (delay 1 (set pc (c-call SI "@cpu@_except" pc - #xc00 uimm-16)))) - () -) - - -; Misc instructions - -(dni l-nop "nop" - () - "l.nop" - (+ OP1_0 OP2_5 OP3_1 OP4_0 rA uimm-16) - (nop) - () -) - -(dnmi l-ret "ret" () - "l.ret" - (emit l-jr (rA 11) (uimm-16 0)) -) - -(dni l-movhi "movhi" - (DELAY-SLOT) - "l.movhi $rD,$hi16" - (+ OP1_0 OP2_6 hi16 rD rA) - (set rD (sll WI hi16 (const 16))) - () -) - - -; System releated instructions - -(dni l-mfsr "mfsr" - (DELAY-SLOT) - "l.mfsr $rD,$rA" - (+ OP1_0 OP2_7 rD rA uimm-16) - (set rD (c-call SI "@cpu@_cpu_mfsr" rA)) - () -) - -(dni l-mtsr "mtsr" - (DELAY-SLOT) - "l.mtsr $rA,$rB" - (+ OP1_1 OP2_0 rA rB rD (f-i16-1 0)) - (c-call VOID "@cpu@_cpu_mtsr" rA rB) - () -) - - - -; Load instructions - -(dni l-lw "load word" - (DELAY-SLOT) - "l.lw $rD,${simm-16}($rA)" - (+ OP1_2 OP2_0 rD rA simm-16) - (set rD (mem SI (add rA simm-16))) - () -) - -(dni l-lbz "load byte (zero extend)" - (DELAY-SLOT) - "l.lbz $rD,${simm-16}($rA)" - (+ OP1_2 OP2_1 rD rA simm-16) - (set rD (zext SI (mem QI (add rA simm-16)))) - () -) - -(dni l-lbs "load byte (sign extend)" - (DELAY-SLOT) - "l.lbs $rD,${simm-16}($rA)" - (+ OP1_2 OP2_2 rD rA simm-16) - (set rD (ext SI (mem QI (add rA simm-16)))) - () -) - -(dni l-lhz "load halfword (zero extend)" - (DELAY-SLOT) - "l.lhz $rD,${simm-16}($rA)" - (+ OP1_2 OP2_3 rD simm-16 rA) - (set rD (zext SI (mem HI (add rA simm-16)))) - () -) - -(dni l-lhs "load halfword (sign extend)" - (DELAY-SLOT) - "l.lhs $rD,${simm-16}($rA)" - (+ OP1_2 OP2_4 rD rA simm-16) - (set rD (ext SI (mem HI (add rA simm-16)))) - () -) - - -; Store instructions -; -; We have to use a multi field since the integer is splited over 2 fields - -(define-pmacro (store-insn mnemonic op2-op mode-op) - (begin - (dni (.sym l- mnemonic) - (.str "l." mnemonic " imm(reg)/reg") - (DELAY-SLOT) - (.str "l." mnemonic " ${ui16nc}($rA),$rB") - (+ OP1_3 op2-op rB rD ui16nc) - (set (mem mode-op (add rA ui16nc)) rB) - () - ) - ) -) - -(store-insn sw OP2_5 SI) -(store-insn sb OP2_6 QI) -(store-insn sh OP2_7 HI) - - - -; Shift and rotate instructions - -; Reserved fields. -(dnf f-f-15-8 "nop" (RESERVED) 15 8) -(dnf f-f-10-3 "nop" (RESERVED) 10 3) -(dnf f-f-4-1 "nop" (RESERVED) 4 1) -(dnf f-f-7-3 "nop" (RESERVED) 7 3) - -(define-pmacro (shift-insn mnemonic op4-op) - (begin - (dni (.sym l- mnemonic) - (.str "l." mnemonic " reg/reg/reg") - () - (.str "l." mnemonic " $rD,$rA,$rB") - (+ OP1_3 OP2_8 rD rA rB (f-f-10-3 0) op4-op (f-f-4-1 0) OP7_8) - (set rD (mnemonic rA rB)) - () - ) - (dni (.sym l- mnemonic "i") - (.str "l." mnemonic " reg/reg/imm") - () - (.str "l." mnemonic "i $rD,$rA,${uimm-5}") - (+ OP1_2 OP2_13 rD rA (f-f-15-8 0) op4-op uimm-5) - (set rD (mnemonic rA uimm-5)) - () - ) - ) -) - -(shift-insn sll OP6_0) -(shift-insn srl OP6_1) -(shift-insn sra OP6_2) -(shift-insn ror OP6_4) - - -; Arethmetic insns - -; Reserved fields. -(dnf f-f-10-7 "nop" (RESERVED) 10 7) - -(define-pmacro (ar-insn-u mnemonic op2-op op5-op) - (begin - (dni (.sym l- mnemonic) - (.str "l." mnemonic " reg/reg/reg") - () - (.str "l." mnemonic " $rD,$rA,$rB") - (+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) op5-op) - (set rD (mnemonic rA rB)) - () - ) - (dni (.sym l- mnemonic "i") - (.str "l." mnemonic " reg/reg/lo16") - () - (.str "l." mnemonic "i $rD,$rA,$lo16") - (+ OP1_2 op2-op rD rA lo16) - (set rD (mnemonic rA (and lo16 #xffff))) - () - ) - ) -) - -(define-pmacro (ar-insn-s mnemonic op2-op op5-op) - (begin - (dni (.sym l- mnemonic) - (.str "l." mnemonic " reg/reg/reg") - () - (.str "l." mnemonic " $rD,$rA,$rB") - (+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) op5-op) - (set rD (mnemonic rA rB)) - () - ) - (dni (.sym l- mnemonic "i") - (.str "l." mnemonic " reg/reg/lo16") - () - (.str "l." mnemonic "i $rD,$rA,$lo16") - (+ OP1_2 op2-op rD rA lo16) - (set rD (mnemonic rA lo16)) - () - ) - ) -) - -(ar-insn-s add OP2_5 OP7_0) -;;(ar-op-s addc OP2_5 OP7_0) -(ar-insn-s sub OP2_7 OP7_2) -(ar-insn-u and OP2_8 OP7_3) -(ar-insn-u or OP2_9 OP7_4) -(ar-insn-u xor OP2_10 OP7_5) -(ar-insn-u mul OP2_11 OP7_6) -;;(ar-op-u mac OP2_12 OP7_7) - - -(dni l-div "divide (signed)" - (DELAY-SLOT) - "l.div $rD,$rA,$rB" - (+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) OP7_9) - (if VOID (eq rB (const 0)) - (c-call VOID "@arch@_cpu_trap" pc (enum SI E_ILLEGAL)) - (set rD (div rA rB))) - () -) - -(dni l-divu "divide (unsigned)" - (DELAY-SLOT) - "l.divu $rD,$rA,$rB" - (+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) OP7_10) - (if VOID (eq rB (const 0)) - (c-call VOID "@arch@_cpu_trap" pc (enum SI E_ILLEGAL)) - (set rD (udiv rA rB))) - () -) - - -; Compare instructions - -; Reserved fields. -(dnf f-f-10-11 "nop" (RESERVED) 10 11) - -; Register compare (both signed and unsigned) -(define-pmacro (sf-insn-r op1-op op2-op op3-op op3-op-2 sem-op) - (begin - (dni (.sym l- "sf" (.sym sem-op "s")) - (.str "l." mnemonic " reg/reg") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) "s $rA,$rB") - (+ op1-op op2-op op3-op-2 rA rB (f-f-10-11 0)) - (set cbit (sem-op rA rB)) - () - ) - (dni (.sym l- "sf" (.sym sem-op "u")) - (.str "l." mnemonic " reg/reg") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) "u $rA,$rB") - (+ op1-op op2-op op3-op rA rB (f-f-10-11 0)) - (set cbit (sem-op rA rB)) - () - ) - ) -) - -; Immediate compare (both signed and unsigned) -(define-pmacro (sf-insn-i op1-op op2-op op3-op op3-op-2 sem-op) - (begin - (dni (.sym l- "sf" (.sym sem-op "si")) - (.str "l." mnemonic "si reg/imm") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) "si $rA,${simm-16}") - (+ op1-op op2-op op3-op-2 rA simm-16) - (set cbit (sem-op rA simm-16)) - () - ) - (dni (.sym l- "sf" (.sym sem-op "ui")) - (.str "l." mnemonic "ui reg/imm") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) "ui $rA,${uimm-16}") - (+ op1-op op2-op op3-op rA uimm-16) - (set cbit (sem-op rA uimm-16)) - () - ) - ) -) - -(define-pmacro (sf-insn op5-op sem-op) - (begin - (dni (.sym l- "sf" sem-op) - (.str "l." mnemonic " reg/reg") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) " $rA,$rB") - (+ OP1_3 OP2_9 op5-op rA rB (f-f-10-11 0)) - (set cbit (sem-op rA rB)) - () - ) - (dni (.sym l- "sf" (.sym sem-op "i")) - (.str "l." mnemonic "i reg/imm") - (DELAY-SLOT) - (.str "l.sf" (.str sem-op) "i $rA,${simm-16}") - (+ OP1_2 OP2_14 op5-op rA simm-16) - (set cbit (sem-op rA simm-16)) - () - ) - ) -) - - -(sf-insn-r OP1_3 OP2_9 OP5_2 OP5_6 gt) -(sf-insn-r OP1_3 OP2_9 OP5_3 OP5_7 ge) -(sf-insn-r OP1_3 OP2_9 OP5_4 OP5_8 lt) -(sf-insn-r OP1_3 OP2_9 OP5_5 OP5_9 le) - -(sf-insn-i OP1_2 OP2_14 OP5_2 OP5_6 gt) -(sf-insn-i OP1_2 OP2_14 OP5_3 OP5_7 ge) -(sf-insn-i OP1_2 OP2_14 OP5_4 OP5_8 lt) -(sf-insn-i OP1_2 OP2_14 OP5_5 OP5_9 le) - -(sf-insn OP5_0 eq) -(sf-insn OP5_1 ne) diff -rNU3 dist.orig/cpu/openrisc.opc dist/cpu/openrisc.opc --- dist.orig/cpu/openrisc.opc 2011-08-22 17:25:07.000000000 +0200 +++ dist/cpu/openrisc.opc 1970-01-01 01:00:00.000000000 +0100 @@ -1,164 +0,0 @@ -/* OpenRISC opcode support. -*- C -*- - Copyright 2000, 2001, 2003, 2005, 2011 Free Software Foundation, Inc. - - Contributed by Red Hat Inc; - - This file is part of the GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* This file is an addendum to or32.cpu. Heavy use of C code isn't - appropriate in .cpu files, so it resides here. This especially applies - to assembly/disassembly where parsing/printing can be quite involved. - Such things aren't really part of the specification of the cpu, per se, - so .cpu files provide the general framework and .opc files handle the - nitty-gritty details as necessary. - - Each section is delimited with start and end markers. - - -opc.h additions use: "-- opc.h" - -opc.c additions use: "-- opc.c" - -asm.c additions use: "-- asm.c" - -dis.c additions use: "-- dis.c" - -ibd.h additions use: "-- ibd.h" */ - -/* -- opc.h */ -#undef CGEN_DIS_HASH_SIZE -#define CGEN_DIS_HASH_SIZE 64 -#undef CGEN_DIS_HASH -#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) - -extern long openrisc_sign_extend_16bit (long); -/* -- */ - -/* -- opc.c */ -/* -- */ - -/* -- asm.c */ - -static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); - -#define CGEN_VERBOSE_ASSEMBLER_ERRORS - -long -openrisc_sign_extend_16bit (long value) -{ - return ((value & 0xffff) ^ 0x8000) - 0x8000; -} - -/* Handle hi(). */ - -static const char * -parse_hi16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) -{ - const char *errmsg; - enum cgen_parse_operand_result result_type; - unsigned long ret; - - if (**strp == '#') - ++*strp; - - if (strncasecmp (*strp, "hi(", 3) == 0) - { - bfd_vma value; - - *strp += 3; - errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, - & result_type, & value); - if (**strp != ')') - return MISSING_CLOSING_PARENTHESIS; - - ++*strp; - if (errmsg == NULL - && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) - value >>= 16; - ret = value; - } - else - { - if (**strp == '-') - { - long value; - - errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); - ret = value; - } - else - { - unsigned long value; - - errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); - ret = value; - } - } - - *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; - return errmsg; -} - -/* Handle lo(). */ - -static const char * -parse_lo16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) -{ - const char *errmsg; - enum cgen_parse_operand_result result_type; - unsigned long ret; - - if (**strp == '#') - ++*strp; - - if (strncasecmp (*strp, "lo(", 3) == 0) - { - bfd_vma value; - - *strp += 3; - errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, - & result_type, & value); - if (**strp != ')') - return MISSING_CLOSING_PARENTHESIS; - - ++*strp; - ret = value; - } - else - { - if (**strp == '-') - { - long value; - - errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); - ret = value; - } - else - { - unsigned long value; - - errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); - ret = value; - } - } - - *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; - return errmsg; -} - -/* -- */ - -/* -- ibd.h */ -extern long openrisc_sign_extend_16bit (long); - -/* -- */ diff -rNU3 dist.orig/cpu/or1k.cpu dist/cpu/or1k.cpu --- dist.orig/cpu/or1k.cpu 1970-01-01 01:00:00.000000000 +0100 +++ dist/cpu/or1k.cpu 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,131 @@ +; OpenRISC 1000 architecture. -*- Scheme -*- +; Copyright 2000-2014 Free Software Foundation, Inc. +; Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org +; Modified by Julius Baxter, juliusbaxter@gmail.com +; Modified by Peter Gavin, pgavin@gmail.com +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see + +(include "simplify.inc") + +; The OpenRISC family is a set of RISC microprocessor architectures with an +; emphasis on scalability and is targetted at embedded use. +; The CPU RTL development is a collaborative open source effort. +; http://opencores.org/or1k +; http://openrisc.net + +(define-arch + (name or1k) + (comment "OpenRISC 1000") + (default-alignment aligned) + (insn-lsb0? #t) + (machs or32 or32nd or64 or64nd) + (isas openrisc) +) + +; Instruction set parameters. +(define-isa + ; Name of the ISA. + (name openrisc) + ; Base insturction length. The insns are always 32 bits wide. + (base-insn-bitsize 32) + ) + +(define-pmacro OR32-MACHS or32,or32nd) +(define-pmacro OR64-MACHS or64,or64nd) +(define-pmacro ORBIS-MACHS or32,or32nd,or64,or64nd) +(define-pmacro ORFPX-MACHS or32,or32nd,or64,or64nd) +(define-pmacro ORFPX32-MACHS or32,or32nd,or64,or64nd) +(define-pmacro ORFPX64-MACHS or64,or64nd) + +(define-attr + (for model) + (type boolean) + (name NO-DELAY-SLOT) + (comment "does not have delay slots") + ) + +(if (keep-mach? (or32 or32nd)) + (begin + (define-cpu + (name or1k32bf) + (comment "OpenRISC 1000 32-bit CPU family") + (insn-endian big) + (data-endian big) + (word-bitsize 32) + (file-transform "") + ) + + (define-mach + (name or32) + (comment "Generic OpenRISC 1000 32-bit CPU") + (cpu or1k32bf) + (bfd-name "or1k") + ) + + (define-mach + (name or32nd) + (comment "Generic OpenRISC 1000 32-bit CPU") + (cpu or1k32bf) + (bfd-name "or1knd") + ) + + ; OpenRISC 1200 - 32-bit or1k CPU implementation + (define-model + (name or1200) (comment "OpenRISC 1200 model") + (attrs) + (mach or32) + (unit u-exec "Execution Unit" () 1 1 () () () ()) + ) + + ; OpenRISC 1200 - 32-bit or1k CPU implementation + (define-model + (name or1200nd) (comment "OpenRISC 1200 model") + (attrs NO-DELAY-SLOT) + (mach or32nd) + (unit u-exec "Execution Unit" () 1 1 () () () ()) + ) + ) + ) + +(if (keep-mach? (or64 or64nd)) + (begin + (define-cpu + (name or1k64bf) + (comment "OpenRISC 1000 64-bit CPU family") + (insn-endian big) + (data-endian big) + (word-bitsize 64) + (file-transform "64") + ) + + (define-mach + (name or64) + (comment "Generic OpenRISC 1000 64-bit CPU") + (cpu or1k64bf) + (bfd-name "or1k64") + ) + + (define-mach + (name or64nd) + (comment "Generic OpenRISC 1000 ND 64-bit CPU") + (cpu or1k64bf) + (bfd-name "or1k64nd") + ) + ) + ) + +(include "or1kcommon.cpu") +(include "or1korbis.cpu") +(include "or1korfpx.cpu") diff -rNU3 dist.orig/cpu/or1k.opc dist/cpu/or1k.opc --- dist.orig/cpu/or1k.opc 1970-01-01 01:00:00.000000000 +0100 +++ dist/cpu/or1k.opc 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,421 @@ +/* OpenRISC 1000 opcode support. -*- C -*- + Copyright 2000-2014 Free Software Foundation, Inc. + + Originally ontributed for OR32 by Red Hat Inc; + + This file is part of the GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . */ + +/* This file is an addendum to or1k.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + -opc.h additions use: "-- opc.h" + -opc.c additions use: "-- opc.c" + -asm.c additions use: "-- asm.c" + -dis.c additions use: "-- dis.c" + -ibd.h additions use: "-- ibd.h" */ + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 256 +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) + +/* -- */ + +/* -- opc.c */ +/* -- */ + +/* -- asm.c */ + +static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); + +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +static const char * +parse_disp26 (CGEN_CPU_DESC cd, + const char ** strp, + int opindex, + int opinfo, + enum cgen_parse_operand_result * resultp, + bfd_vma * valuep) +{ + const char *errmsg = NULL; + enum cgen_parse_operand_result result_type; + + if (strncasecmp (*strp, "plt(", 4) == 0) + { + bfd_vma value; + + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 2) & 0xffff; + *valuep = value; + return errmsg; + } + return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); +} + +static const char * +parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + long ret; + + if (**strp == '#') + ++*strp; + + if (strncasecmp (*strp, "hi(", 3) == 0) + { + bfd_vma value; + + *strp += 3; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, + & result_type, & value); + if (**strp != ')') + errmsg = MISSING_CLOSING_PARENTHESIS; + ++*strp; + + ret = value; + + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + ret >>= 16; + ret &= 0xffff; + ret = (ret ^ 0x8000) - 0x8000; + } + } + else if (strncasecmp (*strp, "lo(", 3) == 0) + { + bfd_vma value; + + *strp += 3; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + + ret = value; + + if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + ret &= 0xffff; + ret = (ret ^ 0x8000) - 0x8000; + } + } + else if (strncasecmp (*strp, "got(", 4) == 0) + { + bfd_vma value; + + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotpchi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTPC_HI16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotpclo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTPC_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotoffhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTOFF_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotofflo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTOFF_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_GD_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_GD_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDM_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDM_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDO_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "dtpofflo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDO_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0) + { + bfd_vma value; + + *strp += 11; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_IE_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gottpofflo(", 11) == 0) + { + bfd_vma value; + + *strp += 11; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_IE_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tpoffhi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LE_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tpofflo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LE_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else + { + long value; + errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); + ret = value; + } + + if (errmsg == NULL) + *valuep = ret; + + return errmsg; +} + +static const char * +parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep) +{ + const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep); + + if (errmsg == NULL) + *valuep &= 0xffff; + return errmsg; +} + +/* -- */ + +/* -- ibd.h */ + +/* -- */ diff -rNU3 dist.orig/cpu/or1kcommon.cpu dist/cpu/or1kcommon.cpu --- dist.orig/cpu/or1kcommon.cpu 1970-01-01 01:00:00.000000000 +0100 +++ dist/cpu/or1kcommon.cpu 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,360 @@ +; OpenRISC 1000 32-bit CPU hardware description. -*- Scheme -*- +; Copyright 2000-2014 Free Software Foundation, Inc. +; Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org +; Modified by Julius Baxter, juliusbaxter@gmail.com +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see + +; Hardware pieces. +; These entries list the elements of the raw hardware. +; They're also used to provide tables and other elements of the assembly +; language. + +(define-hardware + (name h-pc) + (comment "program counter") + (attrs PC (MACH ORBIS-MACHS)) + (type pc UWI) + ) + +(define-pmacro REG-INDICES + ((r0 0) + (r1 1) + (r2 2) + (r3 3) + (r4 4) + (r5 5) + (r6 6) + (r7 7) + (r8 8) + (r9 9) + (r10 10) + (r11 11) + (r12 12) + (r13 13) + (r14 14) + (r15 15) + (r16 16) + (r17 17) + (r18 18) + (r19 19) + (r20 20) + (r21 21) + (r22 22) + (r23 23) + (r24 24) + (r25 25) + (r26 26) + (r27 27) + (r28 28) + (r29 29) + (r30 30) + (r31 31) + (lr 9) + (sp 1) + (fp 2)) + ) + +(define-hardware + (name h-fsr) + (comment "floating point registers (single, virtual)") + (attrs VIRTUAL (MACH ORFPX32-MACHS)) + (type register SF (32)) + (indices keyword "" REG-INDICES) + (get (index) (subword SF (trunc SI (reg h-gpr index)) 0)) + (set (index newval) (set UWI (reg h-gpr index) (zext UWI (subword SI newval 0)))) + ) + +(define-hardware + (name h-fdr) (comment "floating point registers (double, virtual)") + (attrs VIRTUAL (MACH ORFPX64-MACHS)) + (type register DF (32)) + (indices keyword "" REG-INDICES) + (get (index) (subword DF (trunc DI (reg h-gpr index)) 0)) + (set (index newval) (set UDI (reg h-gpr index) (zext UDI (subword DI newval 0)))) + ) + +(define-hardware + (name h-spr) (comment "special purpose registers") + (attrs VIRTUAL (MACH ORBIS-MACHS)) + (type register UWI (#x20000)) + (get (index) (c-call UWI "@cpu@_h_spr_get_raw" index)) + (set (index newval) (c-call VOID "@cpu@_h_spr_set_raw" index newval)) +) + +(define-pmacro spr-shift 11) +(define-pmacro (spr-address spr-group spr-index) + (or (sll UWI (enum UWI (.sym "SPR-GROUP-" spr-group)) spr-shift) + (enum UWI (.sym "SPR-INDEX-" spr-group "-" spr-index)))) + +(define-hardware + (name h-gpr) (comment "general registers") + (attrs (MACH ORBIS-MACHS)) + (type register UWI (32)) + (indices keyword "" REG-INDICES) + (get (index) (reg UWI h-spr (add index (spr-address SYS GPR0)))) + (set (index newval) (set UWI (reg UWI h-spr (add index (spr-address SYS GPR0))) newval)) + ) + +(define-normal-enum + except-number + "Exception numbers" + () + EXCEPT- + (("NONE" #x00) + ("RESET" #x01) + ("BUSERR" #x02) + ("DPF" #x03) + ("IPF" #x04) + ("TICK" #x05) + ("ALIGN" #x06) + ("ILLEGAL" #x07) + ("INT" #x08) + ("DTLBMISS" #x09) + ("ITLBMISS" #x0a) + ("RANGE" #x0b) + ("SYSCALL" #x0c) + ("FPE" #x0d) + ("TRAP" #x0e) + ) + ) + +(define-pmacro (raise-exception exnum) + (c-call VOID "@cpu@_exception" pc exnum)) + +(define-normal-enum + spr-groups + "special purpose register groups" + () + SPR-GROUP- + (("SYS" #x0) + ("DMMU" #x1) + ("IMMU" #x2) + ("DCACHE" #x3) + ("ICACHE" #x4) + ("MAC" #x5) + ("DEBUG" #x6) + ("PERF" #x7) + ("POWER" #x8) + ("PIC" #x9) + ("TICK" #xa) + ("FPU" #xb) + ) + ) + +(define-pmacro (spr-reg-info) + (.splice + (SYS VR #x000 "version register") + (SYS UPR #x001 "unit present register") + (SYS CPUCFGR #x002 "cpu configuration register") + (SYS DMMUCFGR #x003 "Data MMU configuration register") + (SYS IMMUCFGR #x004 "Insn MMU configuration register") + (SYS DCCFGR #x005 "Data cache configuration register") + (SYS ICCFGR #x006 "Insn cache configuration register") + (SYS DCFGR #x007 "Debug configuration register") + (SYS PCCFGR #x008 "Performance counters configuration register") + (SYS NPC #x010 "Next program counter") + (SYS SR #x011 "Supervision Regsiter") + (SYS PPC #x012 "Previous program counter") + (SYS FPCSR #x014 "Floating point control status register") + (.unsplice + (.map (.pmacro (n) (.splice SYS (.sym "EPCR" n) (.add n #x20) (.str "Exception PC register " n))) + (.iota #x10))) + (.unsplice + (.map (.pmacro (n) (.splice SYS (.sym "EEAR" n) (.add n #x30) (.str "Exception effective address register " n))) + (.iota #x10))) + (.unsplice + (.map (.pmacro (n) (.splice SYS (.sym "ESR" n) (.add n #x40) (.str "Exception supervision register " n))) + (.iota #x10))) + (.unsplice + (.map (.pmacro (n) (.splice SYS (.sym "GPR" n) (.add n #x400) (.str "General purpose register " n))) + (.iota #x200))) + + (MAC MACLO #x001 "Multiply and accumulate result (low)") + (MAC MACHI #x002 "Multiply and accumulate result (high)") + (TICK TTMR #x000 "Tick timer mode register") + ) + ) + +(define-normal-enum + spr-reg-indices + "special purpose register indicies" + () + SPR-INDEX- + (.map (.pmacro (args) + (.apply (.pmacro (group index n comment) + ((.sym group "-" index) n)) + args) + ) + (spr-reg-info) + ) + ) + +(define-pmacro (define-h-spr-reg spr-group spr-index n spr-comment) + (define-hardware + (name (.sym "h-" (.downcase spr-group) "-" (.downcase spr-index))) + (comment spr-comment) + (attrs VIRTUAL (MACH ORBIS-MACHS)) + (type register UWI) + (get () (reg UWI h-spr (spr-address spr-group spr-index))) + (set (newval) (set (reg UWI h-spr (spr-address spr-group spr-index)) newval)) + ) + ) +(.splice begin (.unsplice (.map (.pmacro (args) (.apply define-h-spr-reg args)) (spr-reg-info)))) + +(define-pmacro (spr-field-info) + ((SYS VR REV 5 0 "revision field") + (SYS VR CFG 23 16 "configuration template field") + (SYS VR VER 31 24 "version field") + (SYS UPR UP 0 0 "UPR present bit") + (SYS UPR DCP 1 1 "data cache present bit") + (SYS UPR ICP 2 2 "insn cache present bit") + (SYS UPR DMP 3 3 "data MMU present bit") + (SYS UPR MP 4 4 "MAC unit present bit") + (SYS UPR IMP 5 5 "insn MMU present bit") + (SYS UPR DUP 6 6 "debug unit present bit") + (SYS UPR PCUP 7 7 "performance counters unit present bit") + (SYS UPR PICP 8 8 "programmable interrupt controller present bit") + (SYS UPR PMP 9 9 "power management present bit") + (SYS UPR TTP 10 10 "tick timer present bit") + (SYS UPR CUP 31 24 "custom units present field") + (SYS CPUCFGR NSGR 3 0 "number of shadow GPR files field") + (SYS CPUCFGR CGF 4 4 "custom GPR file bit") + (SYS CPUCFGR OB32S 5 5 "ORBIS32 supported bit") + (SYS CPUCFGR OB64S 6 6 "ORBIS64 supported bit") + (SYS CPUCFGR OF32S 7 7 "ORFPX32 supported bit") + (SYS CPUCFGR OF64S 8 8 "ORFPX64 supported bit") + (SYS CPUCFGR OV64S 9 9 "ORVDX64 supported bit") + (SYS CPUCFGR ND 10 10 "no transfer delay bit") + (SYS SR SM 0 0 "supervisor mode bit") + (SYS SR TEE 1 1 "tick timer exception enabled bit") + (SYS SR IEE 2 2 "interrupt exception enabled bit") + (SYS SR DCE 3 3 "data cache enabled bit") + (SYS SR ICE 4 4 "insn cache enabled bit") + (SYS SR DME 5 5 "data MMU enabled bit") + (SYS SR IME 6 6 "insn MMU enabled bit") + (SYS SR LEE 7 7 "little endian enabled bit") + (SYS SR CE 8 8 "CID enable bit") + (SYS SR F 9 9 "flag bit") + (SYS SR CY 10 10 "carry bit") + (SYS SR OV 11 11 "overflow bit") + (SYS SR OVE 12 12 "overflow exception enabled bit") + (SYS SR DSX 13 13 "delay slot exception bit") + (SYS SR EPH 14 14 "exception prefix high bit") + (SYS SR FO 15 15 "fixed one bit") + (SYS SR SUMRA 16 16 "SPRs user mode read access bit") + (SYS SR CID 31 28 "context ID field") + (SYS FPCSR FPEE 0 0 "floating point exceptions enabled bit") + (SYS FPCSR RM 2 1 "floating point rounding mode field") + (SYS FPCSR OVF 3 3 "floating point overflow flag bit") + (SYS FPCSR UNF 4 4 "floating point underflow bit") + (SYS FPCSR SNF 5 5 "floating point SNAN flag bit") + (SYS FPCSR QNF 6 6 "floating point QNAN flag bit") + (SYS FPCSR ZF 7 7 "floating point zero flag bit") + (SYS FPCSR IXF 8 8 "floating point inexact flag bit") + (SYS FPCSR IVF 9 9 "floating point invalid flag bit") + (SYS FPCSR INF 10 10 "floating point infinity flag bit") + (SYS FPCSR DZF 11 11 "floating point divide by zero flag bit") + ) + ) + +(define-normal-enum + spr-field-msbs + "SPR field msb positions" + () + SPR-FIELD-MSB- + (.map (.pmacro (args) + (.apply (.pmacro (group index field msb lsb comment) + ((.sym group "-" index "-" field) msb) + ) + args + ) + ) + (spr-field-info) + ) + ) + +(define-normal-enum + spr-field-lsbs + "SPR field lsb positions" + () + SPR-FIELD-SIZE- + (.map (.pmacro (args) + (.apply (.pmacro (group index field msb lsb comment) + ((.sym group "-" index "-" field) lsb) + ) + args + ) + ) + (spr-field-info) + ) + ) + +(define-normal-enum + spr-field-masks + "SPR field masks" + () + SPR-FIELD-MASK- + (.map (.pmacro (args) + (.apply (.pmacro (group index field msb lsb comment) + (.splice (.str group "-" index "-" field) (.sll (.inv (.sll (.inv 0) (.add (.sub msb lsb) 1))) lsb)) + ) + args + ) + ) + (spr-field-info) + ) + ) + +(define-pmacro (define-h-spr-field spr-group spr-index spr-field spr-field-msb spr-field-lsb spr-field-comment) + (.let ((spr-field-name (.sym "h-" (.downcase spr-group) "-" (.downcase spr-index) "-" (.downcase spr-field))) + ) + (begin + (define-hardware + (name spr-field-name) + (comment spr-field-comment) + (attrs VIRTUAL (MACH ORBIS-MACHS)) + (type register UWI) + (get () (c-call UWI "@cpu@_h_spr_field_get_raw" (spr-address spr-group spr-index) spr-field-msb spr-field-lsb)) + (set (value) (c-call VOID "@cpu@_h_spr_field_set_raw" (spr-address spr-group spr-index) spr-field-msb spr-field-lsb value)) + ) + ) + ) + ) +(.splice begin (.unsplice (.map (.pmacro (args) (.apply define-h-spr-field args)) (spr-field-info)))) + +(define-attr + (type boolean) + (for insn) + (name DELAYED-CTI) + (comment "delayed control transfer instruction") + (values #f #t) + (default #f) + ) + +(define-attr + (for insn) + (type boolean) + (name NOT-IN-DELAY-SLOT) + (comment "instruction cannot be in delay slot") + (values #f #t) + (default #f) + ) + +(define-attr + (for insn) + (type boolean) + (name FORCED-CTI) + (comment "instruction may forcefully transfer control (e.g., rfe)") + ) diff -rNU3 dist.orig/cpu/or1korbis.cpu dist/cpu/or1korbis.cpu --- dist.orig/cpu/or1korbis.cpu 1970-01-01 01:00:00.000000000 +0100 +++ dist/cpu/or1korbis.cpu 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,1145 @@ +; OpenRISC Basic Instruction Set 32-bit (ORBIS) -*- Scheme -*- +; Copyright 2000-2014 Free Software Foundation, Inc. +; Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org +; Modified by Julius Baxter, juliusbaxter@gmail.com +; Modified by Peter Gavin, pgavin@gmail.com +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see + +; Instruction fields. + +; Hardware for immediate operands +(dnh h-simm16 "16-bit signed immediate" ((MACH ORBIS-MACHS)) (immediate (INT 16)) () () ()) +(dnh h-uimm16 "16-bit unsigned immediate" () (immediate (UINT 16)) () () ()) +(dnh h-uimm6 "6-bit unsigned immediate" () (immediate (UINT 6)) () () ()) + +; Hardware for the (internal) atomic registers +(dsh h-atomic-reserve "atomic reserve flag" () (register BI)) +(dsh h-atomic-address "atomic reserve address" () (register SI)) + +; Instruction classes. +(dnf f-opcode "insn opcode" ((MACH ORBIS-MACHS)) 31 6) + +; Register fields. +(dnf f-r1 "r1" ((MACH ORBIS-MACHS)) 25 5) +(dnf f-r2 "r2" ((MACH ORBIS-MACHS)) 20 5) +(dnf f-r3 "r3" ((MACH ORBIS-MACHS)) 15 5) + +; Sub fields +(dnf f-op-25-2 "op-25-2" ((MACH ORBIS-MACHS)) 25 2) ;; nop +(dnf f-op-25-5 "op-25-5" ((MACH ORBIS-MACHS)) 25 5) ;; sys, trap, *sync, sf* +(dnf f-op-16-1 "op-16-1" ((MACH ORBIS-MACHS)) 16 1) ;; movhi,macrc +(dnf f-op-7-4 "op-7-4" ((MACH ORBIS-MACHS)) 7 4) +(dnf f-op-3-4 "op-3-4" ((MACH ORBIS-MACHS)) 3 4) +(dnf f-op-9-2 "op-9-2" ((MACH ORBIS-MACHS)) 9 2) ;; alu ops upper opcode +(dnf f-op-9-4 "op-9-4" ((MACH ORBIS-MACHS)) 9 4) ;; +(dnf f-op-7-8 "op-7-8" ((MACH ORBIS-MACHS)) 7 8) +(dnf f-op-7-2 "op-7-2" ((MACH ORBIS-MACHS)) 7 2) ;; alu lower upper opc,shroti + +; Reserved fields +(dnf f-resv-25-26 "resv-25-26" ((MACH ORBIS-MACHS) RESERVED) 25 26) +(dnf f-resv-25-10 "resv-25-10" ((MACH ORBIS-MACHS) RESERVED) 25 10) +(dnf f-resv-25-5 "resv-25-5" ((MACH ORBIS-MACHS) RESERVED) 25 5) +(dnf f-resv-23-8 "resv-23-8" ((MACH ORBIS-MACHS) RESERVED) 23 8) +(dnf f-resv-20-21 "resv-20-21" ((MACH ORBIS-MACHS) RESERVED) 20 21) +(dnf f-resv-20-5 "resv-20-5" ((MACH ORBIS-MACHS) RESERVED) 20 5) +(dnf f-resv-20-4 "resv-20-4" ((MACH ORBIS-MACHS) RESERVED) 20 4) +(dnf f-resv-15-8 "resv-15-8" ((MACH ORBIS-MACHS) RESERVED) 15 8) +(dnf f-resv-15-6 "resv-15-6" ((MACH ORBIS-MACHS) RESERVED) 15 6) +(dnf f-resv-10-11 "resv-10-11" ((MACH ORBIS-MACHS) RESERVED) 10 11) +(dnf f-resv-10-7 "resv-10-7" ((MACH ORBIS-MACHS) RESERVED) 10 7) +(dnf f-resv-10-3 "resv-10-3" ((MACH ORBIS-MACHS) RESERVED) 10 3) +(dnf f-resv-10-1 "resv-10-1" ((MACH ORBIS-MACHS) RESERVED) 10 1) +(dnf f-resv-7-4 "resv-7-4" ((MACH ORBIS-MACHS) RESERVED) 7 4) +(dnf f-resv-5-2 "resv-5-2" ((MACH ORBIS-MACHS) RESERVED) 5 2) + +(dnf f-imm16-25-5 "imm16-25-5" ((MACH ORBIS-MACHS)) 25 5) +(dnf f-imm16-10-11 "imm16-10-11" ((MACH ORBIS-MACHS)) 10 11) + +; PC relative, 26-bit (2 shifted to right) +(df f-disp26 + "disp26" + ((MACH ORBIS-MACHS) PCREL-ADDR) + 25 + 26 + INT + ((value pc) (sra SI (sub IAI value pc) (const 2))) + ((value pc) (add IAI (sll IAI value (const 2)) pc)) + ) + +; Immediates. +(dnf f-uimm16 "uimm16" ((MACH ORBIS-MACHS)) 15 16) +(df f-simm16 "simm16" ((MACH ORBIS-MACHS) SIGN-OPT) 15 16 INT #f #f) +(dnf f-uimm6 "uimm6" ((MACH ORBIS-MACHS)) 5 6) ;; shroti + +(define-multi-ifield + (name f-uimm16-split) + (comment "16-bit split unsigned immediate") + (attrs (MACH ORBIS-MACHS)) + (mode UINT) + (subfields f-imm16-25-5 f-imm16-10-11) + (insert (sequence () + (set (ifield f-imm16-25-5) + (and (srl (ifield f-uimm16-split) + (const 11)) + (const #x1f))) + (set (ifield f-imm16-10-11) + (and (ifield f-uimm16-split) + (const #x7ff))))) + (extract + (set (ifield f-uimm16-split) + (trunc UHI + (or (sll (ifield f-imm16-25-5) + (const 11)) + (ifield f-imm16-10-11))))) + ) + +(define-multi-ifield + (name f-simm16-split) + (comment "16-bit split signed immediate") + (attrs (MACH ORBIS-MACHS) SIGN-OPT) + (mode INT) + (subfields f-imm16-25-5 f-imm16-10-11) + (insert (sequence () + (set (ifield f-imm16-25-5) + (and (sra (ifield f-simm16-split) + (const 11)) + (const #x1f))) + (set (ifield f-imm16-10-11) + (and (ifield f-simm16-split) + (const #x7ff))))) + (extract + (set (ifield f-simm16-split) + (trunc HI + (or (sll (ifield f-imm16-25-5) + (const 11)) + (ifield f-imm16-10-11))))) + ) + +; Enums. + +; insn-opcode: bits 31-26 +(define-normal-insn-enum + insn-opcode "insn main opcode enums" ((MACH ORBIS-MACHS)) OPC_ f-opcode + (("J" #x00) + ("JAL" #x01) + ("BNF" #x03) + ("BF" #x04) + ("NOP" #x05) + ("MOVHIMACRC" #x06) + ("SYSTRAPSYNCS" #x08) + ("RFE" #x09) + ("VECTOR" #x0a) + ("JR" #x11) + ("JALR" #x12) + ("MACI" #x13) + ("LWA" #x1b) + ("CUST1" #x1c) + ("CUST2" #x1d) + ("CUST3" #x1e) + ("CUST4" #x1f) + ("LD" #x20) + ("LWZ" #x21) + ("LWS" #x22) + ("LBZ" #x23) + ("LBS" #x24) + ("LHZ" #x25) + ("LHS" #x26) + ("ADDI" #x27) + ("ADDIC" #x28) + ("ANDI" #x29) + ("ORI" #x2a) + ("XORI" #x2b) + ("MULI" #x2c) + ("MFSPR" #x2d) + ("SHROTI" #x2e) + ("SFI" #x2f) + ("MTSPR" #x30) + ("MAC" #x31) + ("FLOAT" #x32) + ("SWA" #x33) + ("SD" #x34) + ("SW" #x35) + ("SB" #x36) + ("SH" #x37) + ("ALU" #x38) + ("SF" #x39) + ("CUST5" #x3c) + ("CUST6" #x3d) + ("CUST7" #x3e) + ("CUST8" #x3f) + ) +) + +(define-normal-insn-enum insn-opcode-systrapsyncs + "systrapsync insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_SYSTRAPSYNCS_ f-op-25-5 + (("SYSCALL" #x00 ) + ("TRAP" #x08 ) + ("MSYNC" #x10 ) + ("PSYNC" #x14 ) + ("CSYNC" #x18 ) + ) +) + +(define-normal-insn-enum insn-opcode-movehimacrc + "movhi/macrc insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_MOVHIMACRC_ f-op-16-1 + (("MOVHI" #x0) + ("MACRC" #x1) + ) +) + +(define-normal-insn-enum insn-opcode-mac + "multiply/accumulate insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_MAC_ f-op-3-4 + (("MAC" #x1) + ("MSB" #x2) + ) + ) + +(define-normal-insn-enum insn-opcode-shorts + "shift/rotate insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_SHROTS_ f-op-7-2 + (("SLL" #x0 ) + ("SRL" #x1 ) + ("SRA" #x2 ) + ("ROR" #x3 ) + ) +) + +(define-normal-insn-enum insn-opcode-extbhs + "extend byte/half opcode enums" ((MACH ORBIS-MACHS)) + OPC_EXTBHS_ f-op-9-4 + (("EXTHS" #x0) + ("EXTBS" #x1) + ("EXTHZ" #x2) + ("EXTBZ" #x3) + ) +) + +(define-normal-insn-enum insn-opcode-extws + "extend word opcode enums" ((MACH ORBIS-MACHS)) + OPC_EXTWS_ f-op-9-4 + (("EXTWS" #x0) + ("EXTWZ" #x1) + ) +) + +(define-normal-insn-enum insn-opcode-alu-regreg + "alu reg/reg insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_ALU_REGREG_ f-op-3-4 + (("ADD" #x0) + ("ADDC" #x1) + ("SUB" #x2) + ("AND" #x3) + ("OR" #x4) + ("XOR" #x5) + ("MUL" #x6) + ("SHROT" #x8) + ("DIV" #x9) + ("DIVU" #xA) + ("MULU" #xB) + ("EXTBH" #xC) + ("EXTW" #xD) + ("CMOV" #xE) + ("FFL1" #xF) + ) +) + +(define-normal-insn-enum insn-opcode-setflag + "setflag insn opcode enums" ((MACH ORBIS-MACHS)) + OPC_SF_ f-op-25-5 + (("EQ" #x00) + ("NE" #x01) + ("GTU" #x02) + ("GEU" #x03) + ("LTU" #x04) + ("LEU" #x05) + ("GTS" #x0A) + ("GES" #x0B) + ("LTS" #x0C) + ("LES" #x0D) + ) +) + + +; Instruction operands. + +(dnop sys-sr "supervision register" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr f-nil) +(dnop sys-esr0 "exception supervision register 0" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-esr0 f-nil) +(dnop sys-epcr0 "exception PC register 0" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-epcr0 f-nil) + +(dnop sys-sr-lee "SR little endian enable bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-lee f-nil) +(dnop sys-sr-f "SR flag bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-f f-nil) +(dnop sys-sr-cy "SR carry bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-cy f-nil) +(dnop sys-sr-ov "SR overflow bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-ov f-nil) +(dnop sys-sr-ove "SR overflow exception enable bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-ove f-nil) +(dnop sys-cpucfgr-ob64s "CPUCFGR ORBIS64 supported bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-cpucfgr-ob64s f-nil) +(dnop sys-cpucfgr-nd "CPUCFGR no delay bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-cpucfgr-nd f-nil) +(dnop sys-fpcsr-rm "floating point round mode" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-fpcsr-rm f-nil) + +(dnop mac-machi "MAC HI result register" ((MACH ORBIS-MACHS) SEM-ONLY) h-mac-machi f-nil) +(dnop mac-maclo "MAC LO result register" ((MACH ORBIS-MACHS) SEM-ONLY) h-mac-maclo f-nil) + +(dnop atomic-reserve "atomic reserve flag" ((MACH ORBIS-MACHS) SEM-ONLY) h-atomic-reserve f-nil) +(dnop atomic-address "atomic address" ((MACH ORBIS-MACHS) SEM-ONLY) h-atomic-address f-nil) + +(dnop uimm6 "uimm6" ((MACH ORBIS-MACHS)) h-uimm6 f-uimm6) + +(dnop rD "destination register" ((MACH ORBIS-MACHS)) h-gpr f-r1) +(dnop rA "source register A" ((MACH ORBIS-MACHS)) h-gpr f-r2) +(dnop rB "source register B" ((MACH ORBIS-MACHS)) h-gpr f-r3) + +(define-operand + (name disp26) + (comment "pc-rel 26 bit") + (attrs (MACH ORBIS-MACHS)) + (type h-iaddr) + (index f-disp26) + (handlers (parse "disp26")) + ) + +(define-operand + (name simm16) + (comment "16-bit signed immediate") + (attrs (MACH ORBIS-MACHS) SIGN-OPT) + (type h-simm16) + (index f-simm16) + (handlers (parse "simm16")) + ) + +(define-operand + (name uimm16) + (comment "16-bit unsigned immediate") + (attrs (MACH ORBIS-MACHS)) + (type h-uimm16) + (index f-uimm16) + (handlers (parse "uimm16")) + ) + +(define-operand + (name simm16-split) + (comment "split 16-bit signed immediate") + (attrs (MACH ORBIS-MACHS) SIGN-OPT) + (type h-simm16) + (index f-simm16-split) + (handlers (parse "simm16")) +) + +(define-operand + (name uimm16-split) + (comment "split 16-bit unsigned immediate") + (attrs (MACH ORBIS-MACHS)) + (type h-uimm16) + (index f-uimm16-split) + (handlers (parse "uimm16")) +) + +; Instructions. + +; Branch releated instructions + +(define-pmacro (cti-link-return) + (set IAI (reg h-gpr 9) (add pc (if sys-cpucfgr-nd 4 8))) + ) +(define-pmacro (cti-transfer-control condition target) + ;; this mess is necessary because we're + ;; skipping the delay slot, but it's + ;; actually the start of the next basic + ;; block + (sequence () + (if condition + (delay 1 (set IAI pc target)) + (if sys-cpucfgr-nd + (delay 1 (set IAI pc (add pc 4)))) + ) + (if sys-cpucfgr-nd + (skip 1) + ) + ) + ) + +(define-pmacro + (define-cti + cti-name + cti-comment + cti-attrs + cti-syntax + cti-format + cti-semantics) + (begin + (dni + cti-name + cti-comment + (.splice (MACH ORBIS-MACHS) DELAYED-CTI NOT-IN-DELAY-SLOT (.unsplice cti-attrs)) + cti-syntax + cti-format + (cti-semantics) + () + ) + ) + ) + +(define-cti + l-j + "jump (pc-relative iaddr)" + (!COND-CTI UNCOND-CTI) + "l.j ${disp26}" + (+ OPC_J disp26) + (.pmacro () + (cti-transfer-control 1 disp26) + ) + ) + +(define-cti + l-jal + "jump and link (pc-relative iaddr)" + (!COND-CTI UNCOND-CTI) + "l.jal ${disp26}" + (+ OPC_JAL disp26) + (.pmacro () + (sequence () + (cti-link-return) + (cti-transfer-control 1 disp26) + ) + ) + ) + +(define-cti + l-jr + "jump register (absolute iaddr)" + (!COND-CTI UNCOND-CTI) + "l.jr $rB" + (+ OPC_JR (f-resv-25-10 0) rB (f-resv-10-11 0)) + (.pmacro () + (cti-transfer-control 1 rB) + ) + ) + +(define-cti + l-jalr + "jump register and link (absolute iaddr)" + (!COND-CTI UNCOND-CTI) + "l.jalr $rB" + (+ OPC_JALR (f-resv-25-10 0) rB (f-resv-10-11 0) ) + (.pmacro () + (sequence () + (cti-link-return) + (cti-transfer-control 1 rB) + ) + ) + ) + +(define-cti + l-bnf + "branch if condition bit not set (pc relative iaddr)" + (COND-CTI !UNCOND-CTI) + "l.bnf ${disp26}" + (+ OPC_BNF disp26) + (.pmacro () + (cti-transfer-control (not sys-sr-f) disp26) + ) + ) + +(define-cti + l-bf + "branch if condition bit set (pc relative iaddr)" + (COND-CTI !UNCOND-CTI) + "l.bf ${disp26}" + (+ OPC_BF disp26) + (.pmacro () + (cti-transfer-control sys-sr-f disp26) + ) + ) + +(dni l-trap "trap (exception)" + ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT) + "l.trap ${uimm16}" + (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_TRAP (f-resv-20-5 0) uimm16) + ; Do exception entry handling in C function, PC set based on SR state + (raise-exception EXCEPT-TRAP) + () +) + + +(dni l-sys "syscall (exception)" + ; This function may not be in delay slot + ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT) + + "l.sys ${uimm16}" + (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_SYSCALL (f-resv-20-5 0) uimm16) + ; Do exception entry handling in C function, PC set based on SR state + (raise-exception EXCEPT-SYSCALL) + () +) + +(dni l-msync "memory sync" + ((MACH ORBIS-MACHS)) + "l.msync" + (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_MSYNC (f-resv-20-21 0)) + (nop) + () +) + +(dni l-psync "pipeline sync" + ((MACH ORBIS-MACHS)) + "l.psync" + (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_PSYNC (f-resv-20-21 0)) + (nop) + () +) + +(dni l-csync "context sync" + ((MACH ORBIS-MACHS)) + "l.csync" + (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_CSYNC (f-resv-20-21 0)) + (nop) + () +) + +(dni l-rfe "return from exception" + ; This function may not be in delay slot + ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT FORCED-CTI) + + "l.rfe" + (+ OPC_RFE (f-resv-25-26 0)) + (c-call VOID "@cpu@_rfe") + () +) + + +; Misc instructions + +; l.nop with immediate must be first so it handles all l.nops in sim +(dni l-nop-imm "nop uimm16" + ((MACH ORBIS-MACHS)) + "l.nop ${uimm16}" + (+ OPC_NOP (f-op-25-2 #x1) (f-resv-23-8 0) uimm16) + (c-call VOID "@cpu@_nop" (zext UWI uimm16)) + () + ) + +(if (application-is? SIMULATOR) + (begin) + (begin + (dni l-nop "nop" + ((MACH ORBIS-MACHS)) + "l.nop" + (+ OPC_NOP (f-op-25-2 #x1) (f-resv-23-8 0) uimm16) + (nop) + () + ) + ) +) + +(dni l-movhi "movhi reg/uimm16" + ((MACH ORBIS-MACHS)) + "l.movhi $rD,$uimm16" + (+ OPC_MOVHIMACRC rD (f-resv-20-4 0) OPC_MOVHIMACRC_MOVHI uimm16) + (set UWI rD (sll UWI (zext UWI uimm16) (const 16))) + () +) + +(dni l-macrc "macrc reg" + ((MACH ORBIS-MACHS)) + "l.macrc $rD" + (+ OPC_MOVHIMACRC rD (f-resv-20-4 0) OPC_MOVHIMACRC_MACRC (f-uimm16 0)) + (sequence () + (set UWI rD mac-maclo) + (set UWI mac-maclo 0) + (set UWI mac-machi 0) + ) + () + ) + + +; System releated instructions + +(dni l-mfspr "mfspr" + ((MACH ORBIS-MACHS)) + "l.mfspr $rD,$rA,${uimm16}" + (+ OPC_MFSPR rD rA uimm16) + (set UWI rD (c-call UWI "@cpu@_mfspr" (or rA (zext UWI uimm16)))) + () +) + +(dni l-mtspr "mtspr" + ((MACH ORBIS-MACHS)) + "l.mtspr $rA,$rB,${uimm16-split}" + (+ OPC_MTSPR rA rB uimm16-split ) + (c-call VOID "@cpu@_mtspr" (or rA (zext WI uimm16-split)) rB) + () +) + + +; Load instructions +(define-pmacro (load-store-addr base offset size) + (c-call AI "@cpu@_make_load_store_addr" base (ext SI offset) size)) + +(dni l-lwz "l.lwz reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lwz $rD,${simm16}($rA)" + (+ OPC_LWZ rD rA simm16) + (set UWI rD (zext UWI (mem USI (load-store-addr rA simm16 4)))) + () +) + + +(dni l-lws "l.lws reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lws $rD,${simm16}($rA)" + (+ OPC_LWS rD rA simm16) + (set WI rD (ext WI (mem SI (load-store-addr rA simm16 4)))) + () +) + +(dni l-lwa "l.lwa reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lwa $rD,${simm16}($rA)" + (+ OPC_LWA rD rA simm16) + (sequence () + (set UWI rD (zext UWI (mem USI (load-store-addr rA simm16 4)))) + (set atomic-reserve (const 1)) + (set atomic-address (load-store-addr rA simm16 4)) + ) + () +) + +(dni l-lbz "l.lbz reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lbz $rD,${simm16}($rA)" + (+ OPC_LBZ rD rA simm16) + (set UWI rD (zext UWI (mem UQI (load-store-addr rA simm16 1)))) + () +) + +(dni l-lbs "l.lbs reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lbs $rD,${simm16}($rA)" + (+ OPC_LBS rD rA simm16) + (set WI rD (ext WI (mem QI (load-store-addr rA simm16 1)))) + () +) + +(dni l-lhz "l.lhz reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lhz $rD,${simm16}($rA)" + (+ OPC_LHZ rD simm16 rA) + (set UWI rD (zext UWI (mem UHI (load-store-addr rA simm16 2)))) + () +) + +(dni l-lhs "l.lhs reg/simm16(reg)" + ((MACH ORBIS-MACHS)) + "l.lhs $rD,${simm16}($rA)" + (+ OPC_LHS rD rA simm16) + (set WI rD (ext WI (mem HI (load-store-addr rA simm16 2)))) + () +) + + +; Store instructions + +(define-pmacro (store-insn mnemonic opc-op mode size) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " simm16(reg)/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " ${simm16-split}($rA),$rB") + (+ opc-op rA rB simm16-split) + (sequence ((SI addr)) + (set addr (load-store-addr rA simm16-split size)) + (set mode (mem mode addr) (trunc mode rB)) + (if (eq (and addr #xffffffc) atomic-address) + (set atomic-reserve (const 0)) + ) + ) + () + ) + ) +) + +(store-insn sw OPC_SW USI 4) +(store-insn sb OPC_SB UQI 1) +(store-insn sh OPC_SH UHI 2) + +(dni l-swa "l.swa simm16(reg)/reg" + ((MACH ORBIS-MACHS)) + "l.swa ${simm16-split}($rA),$rB" + (+ OPC_SWA rA rB simm16) + (sequence ((SI addr) (BI flag)) + (set addr (load-store-addr rA simm16-split 4)) + (set sys-sr-f (and atomic-reserve (eq addr atomic-address))) + (if sys-sr-f + (set USI (mem USI addr) (trunc USI rB)) + ) + (set atomic-reserve (const 0)) + ) + () +) + + +; Shift and rotate instructions + +(define-pmacro (shift-insn mnemonic) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " reg/reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-3 0) (.sym OPC_SHROTS_ (.upcase mnemonic)) (f-resv-5-2 0) + OPC_ALU_REGREG_SHROT ) + (set UWI rD (mnemonic rA rB)) + () + ) + (dni (.sym l- mnemonic "i") + (.str "l." mnemonic " reg/reg/uimm6") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic "i $rD,$rA,${uimm6}") + (+ OPC_SHROTI rD rA (f-resv-15-8 0) (.sym OPC_SHROTS_ (.upcase mnemonic)) uimm6) + (set rD (mnemonic rA uimm6)) + () + ) + ) +) + +(shift-insn sll) +(shift-insn srl) +(shift-insn sra) +(shift-insn ror) + + +; Arithmetic insns + +; ALU op macro +(define-pmacro (alu-insn mnemonic) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " reg/reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-7 0) (.sym OPC_ALU_REGREG_ (.upcase mnemonic))) + (set rD (mnemonic rA rB)) + () + ) + ) +) + +(alu-insn and) +(alu-insn or) +(alu-insn xor) + +(define-pmacro (alu-carry-insn mnemonic) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " reg/reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) (.sym OPC_ALU_REGREG_ (.upcase mnemonic))) + (sequence () + (sequence () + (set BI sys-sr-cy ((.sym mnemonic "c-cflag") WI rA rB 0)) + (set BI sys-sr-ov ((.sym mnemonic "c-oflag") WI rA rB 0)) + (set rD (mnemonic WI rA rB)) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () + ) + ) + ) + +(alu-carry-insn add) +(alu-carry-insn sub) + +(dni (l-addc) "l.addc reg/reg/reg" + ((MACH ORBIS-MACHS)) + ("l.addc $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) OPC_ALU_REGREG_ADDC) + (sequence () + (sequence ((BI tmp-sys-sr-cy)) + (set BI tmp-sys-sr-cy sys-sr-cy) + (set BI sys-sr-cy (addc-cflag WI rA rB tmp-sys-sr-cy)) + (set BI sys-sr-ov (addc-oflag WI rA rB tmp-sys-sr-cy)) + (set rD (addc WI rA rB tmp-sys-sr-cy)) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni (l-mul) "l.mul reg/reg/reg" + ((MACH ORBIS-MACHS)) + ("l.mul $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_MUL) + (sequence () + (sequence () + ; 2's complement overflow + (set BI sys-sr-ov (mul-o2flag WI rA rB)) + ; 1's complement overflow + (set BI sys-sr-cy (mul-o1flag WI rA rB)) + (set rD (mul WI rA rB)) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni (l-mulu) "l.mulu reg/reg/reg" + ((MACH ORBIS-MACHS)) + ("l.mulu $rD,$rA,$rB") + (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_MULU) + (sequence () + (sequence () + ; 2's complement overflow + (set BI sys-sr-ov 0) + ; 1's complement overflow + (set BI sys-sr-cy (mul-o1flag UWI rA rB)) + (set rD (mul UWI rA rB)) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni l-div "divide (signed)" + ((MACH ORBIS-MACHS)) + "l.div $rD,$rA,$rB" + (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_DIV) + (sequence () + (if (ne rB 0) + (sequence () + (set BI sys-sr-cy 0) + (set WI rD (div WI rA rB)) + ) + (set BI sys-sr-cy 1) + ) + (set BI sys-sr-ov 0) + (if (andif sys-sr-cy sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni l-divu "divide (unsigned)" + ((MACH ORBIS-MACHS)) + "l.divu $rD,$rA,$rB" + (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_DIVU) + (sequence () + (if (ne rB 0) + (sequence () + (set BI sys-sr-cy 0) + (set rD (udiv UWI rA rB)) + ) + (set BI sys-sr-cy 1) + ) + (set BI sys-sr-ov 0) + (if (andif sys-sr-cy sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni l-ff1 "find first '1'" + ((MACH ORBIS-MACHS)) + "l.ff1 $rD,$rA" + (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) OPC_ALU_REGREG_FFL1) + (set rD (c-call UWI "@cpu@_ff1" rA)) + () +) + +(dni l-fl1 "find last '1'" + ((MACH ORBIS-MACHS)) + "l.fl1 $rD,$rA" + (+ OPC_ALU rD rA rB (f-resv-10-7 #x10) OPC_ALU_REGREG_FFL1) + (set rD (c-call UWI "@cpu@_fl1" rA)) + () +) + + +(define-pmacro (alu-insn-simm mnemonic) + (begin + (dni (.sym l- mnemonic "i") + (.str "l." mnemonic " reg/reg/simm16") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic "i $rD,$rA,$simm16") + (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA simm16) + (set rD (mnemonic rA (ext WI simm16))) + () + ) + ) +) + +(define-pmacro (alu-insn-uimm mnemonic) + (begin + (dni (.sym l- mnemonic "i") + (.str "l." mnemonic " reg/reg/uimm16") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic "i $rD,$rA,$uimm16") + (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA uimm16) + (set rD (mnemonic rA (zext UWI uimm16))) + () + ) + ) +) + +(alu-insn-uimm and) +(alu-insn-uimm or) +(alu-insn-simm xor) + +(define-pmacro (alu-carry-insn-simm mnemonic) + (begin + (dni (.sym l- mnemonic "i") + (.str "l." mnemonic "i reg/reg/simm16") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic "i $rD,$rA,$simm16") + (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA simm16) + (sequence () + (sequence () + (set BI sys-sr-cy ((.sym mnemonic "c-cflag") WI rA (ext WI simm16) 0)) + (set BI sys-sr-ov ((.sym mnemonic "c-oflag") WI rA (ext WI simm16) 0)) + (set rD (mnemonic WI rA (ext WI simm16))) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () + ) + ) + ) + +(alu-carry-insn-simm add) + +(dni (l-addic) + ("l.addic reg/reg/simm16") + ((MACH ORBIS-MACHS)) + ("l.addic $rD,$rA,$simm16") + (+ OPC_ADDIC rD rA simm16) + (sequence () + (sequence ((BI tmp-sys-sr-cy)) + (set BI tmp-sys-sr-cy sys-sr-cy) + (set BI sys-sr-cy (addc-cflag WI rA (ext WI simm16) tmp-sys-sr-cy)) + (set BI sys-sr-ov (addc-oflag WI rA (ext WI simm16) tmp-sys-sr-cy)) + (set WI rD (addc WI rA (ext WI simm16) tmp-sys-sr-cy)) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () +) + +(dni (l-muli) + "l.muli reg/reg/simm16" + ((MACH ORBIS-MACHS)) + ("l.muli $rD,$rA,$simm16") + (+ OPC_MULI rD rA simm16) + (sequence () + (sequence () + ; 2's complement overflow + (set sys-sr-ov (mul-o2flag WI rA (ext WI simm16))) + ; 1's complement overflow + (set sys-sr-cy (mul-o1flag UWI rA (ext UWI simm16))) + (set rD (mul WI rA (ext WI simm16))) + ) + (if (andif sys-sr-ov sys-sr-ove) + (raise-exception EXCEPT-RANGE)) + ) + () + ) + +(define-pmacro (extbh-insn mnemonic extop extmode truncmode) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " $rD,$rA") + (+ OPC_ALU rD rA (f-resv-15-6 0) (.sym OPC_EXTBHS_ (.upcase mnemonic)) (f-resv-5-2 0) OPC_ALU_REGREG_EXTBH) + (set rD (extop extmode (trunc truncmode rA))) + () + ) + ) + ) + +(extbh-insn exths ext WI HI) +(extbh-insn extbs ext WI QI) +(extbh-insn exthz zext UWI UHI) +(extbh-insn extbz zext UWI UQI) + +(define-pmacro (extw-insn mnemonic extop extmode truncmode) + (begin + (dni (.sym l- mnemonic) + (.str "l." mnemonic " reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l." mnemonic " $rD,$rA") + (+ OPC_ALU rD rA (f-resv-15-6 0) (.sym OPC_EXTWS_ (.upcase mnemonic)) (f-resv-5-2 0) OPC_ALU_REGREG_EXTW) + (set rD (extop extmode (trunc truncmode rA))) + () + ) + ) + ) + +(extw-insn extws ext WI SI) +(extw-insn extwz zext USI USI) + +(dni l-cmov + "l.cmov reg/reg/reg" + ((MACH ORBIS-MACHS)) + "l.cmov $rD,$rA,$rB" + (+ OPC_ALU rD rA rB (f-resv-10-1 0) (f-op-9-2 0) (f-resv-7-4 0) OPC_ALU_REGREG_CMOV) + (if sys-sr-f + (set UWI rD rA) + (set UWI rD rB) + ) + () + ) + +; Compare instructions + +; Ordering compare +(define-pmacro (sf-insn op) + (begin + (dni (.sym l- "sf" op "s") ; l-sfgts + (.str "l.sf" op "s reg/reg") ; "l.sfgts reg/reg" + ((MACH ORBIS-MACHS)) + (.str "l.sf" op "s $rA,$rB") ; "l.sfgts $rA,$rB" + (+ OPC_SF (.sym "OPC_SF_" (.upcase op) "S") rA rB (f-resv-10-11 0)) ; (+ OPC_SF OPC_SF_GTS rA rB (f-resv-10-11 0)) + (set sys-sr-f (op WI rA rB)) ; (set sys-sr-f (gt WI rA rB)) + () + ) + (dni (.sym l- "sf" op "si") ; l-sfgtsi + (.str "l.sf" op "si reg/simm16") ; "l.sfgtsi reg/simm16" + ((MACH ORBIS-MACHS)) + (.str "l.sf" op "si $rA,$simm16") ; "l.sfgtsi $rA,$simm16" + (+ OPC_SFI (.sym "OPC_SF_" (.upcase op) "S") rA simm16) ; (+ OPC_SFI OPC_SF_GTS rA simm16) + (set sys-sr-f (op WI rA (ext WI simm16))) ; (set sys-sr-f (gt WI rA (ext WI simm16))) + () + ) + (dni (.sym l- "sf" op "u") ; l-sfgtu + (.str "l.sf" op "u reg/reg") ; "l.sfgtu reg/reg" + ((MACH ORBIS-MACHS)) + (.str "l.sf" op "u $rA,$rB") ; "l.sfgtu $rA,$rB" + (+ OPC_SF (.sym "OPC_SF_" (.upcase op) "U") rA rB (f-resv-10-11 0)) ; (+ OPC_SF OPC_SF_GTU rA rB (f-resv-10-11 0)) + (set sys-sr-f ((.sym op "u") WI rA rB)) ; (set sys-sr-f (gtu WI rA rB)) + () + ) + ; immediate is sign extended even for unsigned compare + (dni (.sym l- "sf" op "ui") ; l-sfgtui + (.str "l.sf" op "ui reg/simm16") ; "l.sfgtui reg/uimm16" + ((MACH ORBIS-MACHS)) + (.str "l.sf" op "ui $rA,$simm16") ; "l.sfgtui $rA,$simm16" + (+ OPC_SFI (.sym "OPC_SF_" (.upcase op) "U") rA simm16) ; (+ OPC_SFI OPC_SF_GTU rA simm16) + (set sys-sr-f ((.sym op "u") WI rA (ext WI simm16))) ; (set sys-sr-f (gtu WI rA (ext WI simm16))) + () + ) + ) + ) + +(sf-insn gt) +(sf-insn ge) +(sf-insn lt) +(sf-insn le) + +; Equality compare +(define-pmacro (sf-insn-eq op) + (begin + (dni (.sym l- "sf" op) + (.str "l." op " reg/reg") + ((MACH ORBIS-MACHS)) + (.str "l.sf" op " $rA,$rB") + (+ OPC_SF (.sym "OPC_SF_" (.upcase op)) rA rB (f-resv-10-11 0)) + (set sys-sr-f (op WI rA rB)) + () + ) + (dni (.sym l- "sf" op "i") + (.str "l.sf" op "i reg/simm16") + ((MACH ORBIS-MACHS)) + (.str "l.sf" op "i $rA,$simm16") + (+ OPC_SFI (.sym "OPC_SF_" (.upcase op)) rA simm16) + (set sys-sr-f (op WI rA (ext WI simm16))) + () + ) + ) +) + +(sf-insn-eq eq) +(sf-insn-eq ne) + +(dni l-mac + "l.mac reg/reg" + ((MACH ORBIS-MACHS)) + "l.mac $rA,$rB" + (+ OPC_MAC (f-op-25-5 0) rA rB (f-resv-10-7 0) OPC_MAC_MAC) + (sequence ((WI prod) (DI result)) + (set WI prod (mul WI rA rB)) + (set DI result (add (join DI SI mac-machi mac-maclo) (ext DI prod))) + (set SI mac-machi (subword SI result 0)) + (set SI mac-maclo (subword SI result 1)) + ) + () + ) + +(dni l-msb + "l.msb reg/reg" + ((MACH ORBIS-MACHS)) + "l.msb $rA,$rB" + (+ OPC_MAC (f-op-25-5 0) rA rB (f-resv-10-7 0) OPC_MAC_MSB) + (sequence ((WI prod) (DI result)) + (set WI prod (mul WI rA rB)) + (set DI result (sub (join DI SI mac-machi mac-maclo) (ext DI prod))) + (set SI mac-machi (subword SI result 0)) + (set SI mac-maclo (subword SI result 1)) + ) + () + ) + +(dni l-maci + "l.maci reg/simm16" + ((MACH ORBIS-MACHS)) + "l.maci $rA,${simm16}" + (+ OPC_MACI (f-resv-25-5 0) rA simm16) + (sequence ((WI prod) (DI result)) + (set WI prod (mul WI (ext WI simm16) rA)) + (set DI result (add (join DI SI mac-machi mac-maclo) (ext DI prod))) + (set SI mac-machi (subword SI result 0)) + (set SI mac-maclo (subword SI result 1)) + ) + () + ) + +(define-pmacro (cust-insn cust-num) + (begin + (dni (.sym l- "cust" cust-num) + (.str "l.cust" cust-num) + ((MACH ORBIS-MACHS)) + (.str "l.cust" cust-num) + (+ (.sym OPC_CUST cust-num) (f-resv-25-26 0)) + (nop) + () + ) + ) + ) + +(cust-insn "1") +(cust-insn "2") +(cust-insn "3") +(cust-insn "4") +(cust-insn "5") +(cust-insn "6") +(cust-insn "7") +(cust-insn "8") diff -rNU3 dist.orig/cpu/or1korfpx.cpu dist/cpu/or1korfpx.cpu --- dist.orig/cpu/or1korfpx.cpu 1970-01-01 01:00:00.000000000 +0100 +++ dist/cpu/or1korfpx.cpu 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,222 @@ +; OpenRISC 1000 architecture. -*- Scheme -*- +; Copyright 2000-2014 Free Software Foundation, Inc. +; Contributed by Peter Gavin, pgavin@gmail.com +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see + +; Initial ORFPX32 instruction set + +; I'm not sure how CGEN handles rounding in FP operations, except for +; in conversions to/from integers. So lf.add, lf.sub, lf.mul, and +; lf.div do not round according to the FPCSR RM field. +; NaN, overflow, and underflow are not yet handled either. + +(define-normal-insn-enum insn-opcode-float-regreg + "floating point reg/reg insn opcode enums" () + OPC_FLOAT_REGREG_ f-op-7-8 + (("ADD_S" #x00) + ("SUB_S" #x01) + ("MUL_S" #x02) + ("DIV_S" #x03) + ("ITOF_S" #x04) + ("FTOI_S" #x05) + ("REM_S" #x06) + ("MADD_S" #x07) + ("SFEQ_S" #x08) + ("SFNE_S" #x09) + ("SFGT_S" #x0a) + ("SFGE_S" #x0b) + ("SFLT_S" #x0c) + ("SFLE_S" #x0d) + ("ADD_D" #x10) + ("SUB_D" #x11) + ("MUL_D" #x12) + ("DIV_D" #x13) + ("ITOF_D" #x14) + ("FTOI_D" #x15) + ("REM_D" #x16) + ("MADD_D" #x17) + ("SFEQ_D" #x18) + ("SFNE_D" #x19) + ("SFGT_D" #x1a) + ("SFGE_D" #x1b) + ("SFLT_D" #x1c) + ("SFLE_D" #x1d) + ("CUST1_S" #xd0) + ("CUST1_D" #xe0) + ) + ) + +(dnop rDSF "destination register (single floating point mode)" () h-fsr f-r1) +(dnop rASF "source register A (single floating point mode)" () h-fsr f-r2) +(dnop rBSF "source register B (single floating point mode)" () h-fsr f-r3) + +(dnop rDDF "destination register (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1) +(dnop rADF "source register A (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1) +(dnop rBDF "source register B (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1) + +(define-pmacro (float-regreg-insn mnemonic) + (begin + (dni (.sym lf- mnemonic -s) + (.str "lf." mnemonic ".s reg/reg/reg") + ((MACH ORFPX-MACHS)) + (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF") + (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S)) + (set SF rDSF (mnemonic SF rASF rBSF)) + () + ) + (dni (.sym lf- mnemonic -d) + (.str "lf." mnemonic ".d reg/reg/reg") + ((MACH ORFPX64-MACHS)) + (.str "lf." mnemonic ".d $rDDF,$rADF,$rBDF") + (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D)) + (set DF rDDF (mnemonic DF rADF rBDF)) + () + ) + ) + ) + +(float-regreg-insn add) +(float-regreg-insn sub) +(float-regreg-insn mul) +(float-regreg-insn div) + +(dni lf-rem-s + "lf.rem.s reg/reg/reg" + ((MACH ORFPX-MACHS)) + "lf.rem.s $rDSF,$rASF,$rBSF" + (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S) + (set SF rDSF (rem SF rASF rBSF)) + () + ) +(dni lf-rem-d + "lf.rem.d reg/reg/reg" + ((MACH ORFPX64-MACHS)) + "lf.rem.d $rDDF,$rADF,$rBDF" + (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_D) + (set DF rDDF (mod DF rADF rBDF)) + () + ) + +(define-pmacro (get-rounding-mode) + (case INT sys-fpcsr-rm + ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest" + ((1) 3) ; TOWARD-ZERO + ((2) 4) ; TOWARD-POSITIVE + (else 5) ; TOWARD-NEGATIVE + ) + ) + +(dni lf-itof-s + "lf.itof.s reg/reg" + ((MACH ORFPX-MACHS)) + "lf.itof.s $rDSF,$rA" + (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S) + (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA))) + () + ) +(dni lf-itof-d + "lf.itof.d reg/reg" + ((MACH ORFPX64-MACHS)) + "lf.itof.d $rDSF,$rA" + (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_D) + (set DF rDDF (float DF (get-rounding-mode) rA)) + () + ) + +(dni lf-ftoi-s + "lf.ftoi.s reg/reg" + ((MACH ORFPX-MACHS)) + "lf.ftoi.s $rD,$rASF" + (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S) + (set WI rD (ext WI (fix SI (get-rounding-mode) rASF))) + () + ) + +(dni lf-ftoi-d + "lf.ftoi.d reg/reg" + ((MACH ORFPX64-MACHS)) + "lf.ftoi.d $rD,$rADF" + (+ OPC_FLOAT rD rADF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_D) + (set DI rD (fix DI (get-rounding-mode) rADF)) + () + ) + +(define-pmacro (float-setflag-insn mnemonic) + (begin + (dni (.sym lf- mnemonic -s) + (.str "lf.sf" mnemonic ".s reg/reg") + ((MACH ORFPX-MACHS)) + (.str "lf.sf" mnemonic ".s $rASF,$rBSF") + (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S)) + (set BI sys-sr-f (mnemonic SF rASF rBSF)) + () + ) + (dni (.sym lf- mnemonic -d) + (.str "lf.sf" mnemonic ".d reg/reg") + ((MACH ORFPX64-MACHS)) + (.str "lf.sf" mnemonic ".d $rASF,$rBSF") + (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D)) + (set BI sys-sr-f (mnemonic DF rADF rBDF)) + () + ) + ) + ) + +(float-setflag-insn eq) +(float-setflag-insn ne) +(float-setflag-insn ge) +(float-setflag-insn gt) +(float-setflag-insn lt) +(float-setflag-insn le) + +(dni lf-madd-s + "lf.madd.s reg/reg/reg" + ((MACH ORFPX-MACHS)) + "lf.madd.s $rDSF,$rASF,$rBSF" + (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S) + (set SF rDSF (add SF (mul SF rASF rBSF) rDSF)) + () + ) +(dni lf-madd-d + "lf.madd.d reg/reg/reg" + ((MACH ORFPX64-MACHS)) + "lf.madd.d $rDDF,$rADF,$rBDF" + (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_D) + (set DF rDDF (add DF (mul DF rADF rBDF) rDDF)) + () + ) + +(define-pmacro (float-cust-insn cust-num) + (begin + (dni (.sym "lf-cust" cust-num "-s") + (.str "lf.cust" cust-num ".s") + ((MACH ORFPX-MACHS)) + (.str "lf.cust" cust-num ".s $rASF,$rBSF") + (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S")) + (nop) + () + ) + (dni (.sym "lf-cust" cust-num "-d") + (.str "lf.cust" cust-num ".d") + ((MACH ORFPX64-MACHS)) + (.str "lf.cust" cust-num ".d") + (+ OPC_FLOAT (f-resv-25-5 0) rADF rBDF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D")) + (nop) + () + ) + ) + ) + +(float-cust-insn "1") diff -rNU3 dist.orig/gas/Makefile.am dist/gas/Makefile.am --- dist.orig/gas/Makefile.am 2012-09-04 14:53:45.000000000 +0200 +++ dist/gas/Makefile.am 2015-10-18 13:11:13.000000000 +0200 @@ -147,11 +147,11 @@ config/tc-msp430.c \ config/tc-mt.c \ config/tc-ns32k.c \ - config/tc-openrisc.c \ - config/tc-or32.c \ + config/tc-or1k.c \ config/tc-pdp11.c \ config/tc-pj.c \ config/tc-ppc.c \ + config/tc-riscv.c \ config/tc-rl78.c \ config/tc-rx.c \ config/tc-s390.c \ @@ -216,11 +216,11 @@ config/tc-msp430.h \ config/tc-mt.h \ config/tc-ns32k.h \ - config/tc-openrisc.h \ - config/tc-or32.h \ + config/tc-or1k.h \ config/tc-pdp11.h \ config/tc-pj.h \ config/tc-ppc.h \ + config/tc-riscv.h \ config/tc-rl78.h \ config/tc-rx.h \ config/tc-s390.h \ diff -rNU3 dist.orig/gas/Makefile.in dist/gas/Makefile.in --- dist.orig/gas/Makefile.in 2012-09-04 14:53:45.000000000 +0200 +++ dist/gas/Makefile.in 2015-10-18 13:11:13.000000000 +0200 @@ -415,11 +415,11 @@ config/tc-msp430.c \ config/tc-mt.c \ config/tc-ns32k.c \ - config/tc-openrisc.c \ - config/tc-or32.c \ + config/tc-or1k.c \ config/tc-pdp11.c \ config/tc-pj.c \ config/tc-ppc.c \ + config/tc-riscv.c \ config/tc-rl78.c \ config/tc-rx.c \ config/tc-s390.c \ @@ -484,11 +484,11 @@ config/tc-msp430.h \ config/tc-mt.h \ config/tc-ns32k.h \ - config/tc-openrisc.h \ - config/tc-or32.h \ + config/tc-or1k.h \ config/tc-pdp11.h \ config/tc-pj.h \ config/tc-ppc.h \ + config/tc-riscv.h \ config/tc-rl78.h \ config/tc-rx.h \ config/tc-s390.h \ @@ -835,11 +835,11 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-msp430.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-mt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ns32k.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-openrisc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-or32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-or1k.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pdp11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pj.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ppc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-riscv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rl78.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-s390.Po@am__quote@ @@ -1447,33 +1447,19 @@ @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-ns32k.obj `if test -f 'config/tc-ns32k.c'; then $(CYGPATH_W) 'config/tc-ns32k.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-ns32k.c'; fi` -tc-openrisc.o: config/tc-openrisc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-openrisc.o -MD -MP -MF $(DEPDIR)/tc-openrisc.Tpo -c -o tc-openrisc.o `test -f 'config/tc-openrisc.c' || echo '$(srcdir)/'`config/tc-openrisc.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-openrisc.Tpo $(DEPDIR)/tc-openrisc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-openrisc.c' object='tc-openrisc.o' libtool=no @AMDEPBACKSLASH@ +tc-or1k.o: config/tc-or1k.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-or1k.o -MD -MP -MF $(DEPDIR)/tc-or1k.Tpo -c -o tc-or1k.o `test -f 'config/tc-or1k.c' || echo '$(srcdir)/'`config/tc-or1k.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-or1k.Tpo $(DEPDIR)/tc-or1k.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-or1k.c' object='tc-or1k.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-or1k.o `test -f 'config/tc-or1k.c' || echo '$(srcdir)/'`config/tc-or1k.c + +tc-or1k.obj: config/tc-or1k.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-or1k.obj -MD -MP -MF $(DEPDIR)/tc-or1k.Tpo -c -o tc-or1k.obj `if test -f 'config/tc-or1k.c'; then $(CYGPATH_W) 'config/tc-or1k.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-or1k.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-or1k.Tpo $(DEPDIR)/tc-or1k.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-or1k.c' object='tc-or1k.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-openrisc.o `test -f 'config/tc-openrisc.c' || echo '$(srcdir)/'`config/tc-openrisc.c - -tc-openrisc.obj: config/tc-openrisc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-openrisc.obj -MD -MP -MF $(DEPDIR)/tc-openrisc.Tpo -c -o tc-openrisc.obj `if test -f 'config/tc-openrisc.c'; then $(CYGPATH_W) 'config/tc-openrisc.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-openrisc.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-openrisc.Tpo $(DEPDIR)/tc-openrisc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-openrisc.c' object='tc-openrisc.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-openrisc.obj `if test -f 'config/tc-openrisc.c'; then $(CYGPATH_W) 'config/tc-openrisc.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-openrisc.c'; fi` - -tc-or32.o: config/tc-or32.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-or32.o -MD -MP -MF $(DEPDIR)/tc-or32.Tpo -c -o tc-or32.o `test -f 'config/tc-or32.c' || echo '$(srcdir)/'`config/tc-or32.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-or32.Tpo $(DEPDIR)/tc-or32.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-or32.c' object='tc-or32.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-or32.o `test -f 'config/tc-or32.c' || echo '$(srcdir)/'`config/tc-or32.c - -tc-or32.obj: config/tc-or32.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-or32.obj -MD -MP -MF $(DEPDIR)/tc-or32.Tpo -c -o tc-or32.obj `if test -f 'config/tc-or32.c'; then $(CYGPATH_W) 'config/tc-or32.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-or32.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-or32.Tpo $(DEPDIR)/tc-or32.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-or32.c' object='tc-or32.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-or32.obj `if test -f 'config/tc-or32.c'; then $(CYGPATH_W) 'config/tc-or32.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-or32.c'; fi` +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-or1k.obj `if test -f 'config/tc-or1k.c'; then $(CYGPATH_W) 'config/tc-or1k.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-or1k.c'; fi` tc-pdp11.o: config/tc-pdp11.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-pdp11.o -MD -MP -MF $(DEPDIR)/tc-pdp11.Tpo -c -o tc-pdp11.o `test -f 'config/tc-pdp11.c' || echo '$(srcdir)/'`config/tc-pdp11.c @@ -1517,6 +1503,20 @@ @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-ppc.obj `if test -f 'config/tc-ppc.c'; then $(CYGPATH_W) 'config/tc-ppc.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-ppc.c'; fi` +tc-riscv.o: config/tc-riscv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-riscv.o -MD -MP -MF $(DEPDIR)/tc-riscv.Tpo -c -o tc-riscv.o `test -f 'config/tc-riscv.c' || echo '$(srcdir)/'`config/tc-riscv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.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-riscv.o `test -f 'config/tc-riscv.c' || echo '$(srcdir)/'`config/tc-riscv.c + +tc-riscv.obj: config/tc-riscv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-riscv.obj -MD -MP -MF $(DEPDIR)/tc-riscv.Tpo -c -o tc-riscv.obj `if test -f 'config/tc-riscv.c'; then $(CYGPATH_W) 'config/tc-riscv.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-riscv.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.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-riscv.obj `if test -f 'config/tc-riscv.c'; then $(CYGPATH_W) 'config/tc-riscv.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-riscv.c'; fi` + tc-rl78.o: config/tc-rl78.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-rl78.o -MD -MP -MF $(DEPDIR)/tc-rl78.Tpo -c -o tc-rl78.o `test -f 'config/tc-rl78.c' || echo '$(srcdir)/'`config/tc-rl78.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-rl78.Tpo $(DEPDIR)/tc-rl78.Po diff -rNU3 dist.orig/gas/atof-generic.c dist/gas/atof-generic.c --- dist.orig/gas/atof-generic.c 2009-09-02 09:24:19.000000000 +0200 +++ dist/gas/atof-generic.c 2015-10-18 13:11:13.000000000 +0200 @@ -121,6 +121,32 @@ switch (first_digit[0]) { + case 's': + case 'S': + if (!strncasecmp ("snan", first_digit, 4)) + { + address_of_generic_floating_point_number->sign = 0; + address_of_generic_floating_point_number->exponent = 0; + address_of_generic_floating_point_number->leader = + address_of_generic_floating_point_number->low; + *address_of_string_pointer = first_digit + 4; + return 0; + } + break; + + case 'q': + case 'Q': + if (!strncasecmp ("qnan", first_digit, 4)) + { + address_of_generic_floating_point_number->sign = 0; + address_of_generic_floating_point_number->exponent = 0; + address_of_generic_floating_point_number->leader = + address_of_generic_floating_point_number->low; + *address_of_string_pointer = first_digit + 4; + return 0; + } + break; + case 'n': case 'N': if (!strncasecmp ("nan", first_digit, 3)) diff -rNU3 dist.orig/gas/config/atof-vax.c dist/gas/config/atof-vax.c --- dist.orig/gas/config/atof-vax.c 2007-10-17 18:45:54.000000000 +0200 +++ dist/gas/config/atof-vax.c 2015-10-18 13:11:13.000000000 +0200 @@ -268,10 +268,27 @@ int exponent_skippage; LITTLENUM_TYPE word1; - /* JF: Deal with new Nan, +Inf and -Inf codes. */ if (f->sign != '-' && f->sign != '+') { - make_invalid_floating_point_number (words); + if (f->sign == 0) + { + /* All NaNs are 0. */ + memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision); + } + else if (f->sign == 'P') + { + /* Positive Infinity. */ + memset (words, 0xff, sizeof (LITTLENUM_TYPE) * precision); + words[0] &= 0x7fff; + } + else if (f->sign == 'N') + { + /* Negative Infinity. */ + memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision); + words[0] = 0x0080; + } + else + make_invalid_floating_point_number (words); return return_value; } diff -rNU3 dist.orig/gas/config/obj-elf.c dist/gas/config/obj-elf.c --- dist.orig/gas/config/obj-elf.c 2012-06-30 08:32:29.000000000 +0200 +++ dist/gas/config/obj-elf.c 2015-10-18 13:11:13.000000000 +0200 @@ -1705,12 +1705,14 @@ const struct elf_backend_data *bed; bed = get_elf_backend_data (stdoutput); +#if 0 if (!(bed->elf_osabi == ELFOSABI_GNU || bed->elf_osabi == ELFOSABI_FREEBSD /* GNU is still using the default value 0. */ || bed->elf_osabi == ELFOSABI_NONE)) as_bad (_("symbol type \"%s\" is supported only by GNU and FreeBSD targets"), type_name); +#endif type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION; } else if (strcmp (type_name, "gnu_unique_object") == 0) diff -rNU3 dist.orig/gas/config/tc-arm.c dist/gas/config/tc-arm.c --- dist.orig/gas/config/tc-arm.c 2013-03-25 09:06:21.000000000 +0100 +++ dist/gas/config/tc-arm.c 2015-10-18 13:11:13.000000000 +0200 @@ -6936,7 +6936,7 @@ /* Functions for operand encoding. ARM, then Thumb. */ -#define rotate_left(v, n) (v << n | v >> (32 - n)) +#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31)) /* If VAL can be encoded in the immediate field of an ARM instruction, return the encoded form. Otherwise, return FAIL. */ @@ -17290,12 +17290,16 @@ asection *sect; for (sect = stdoutput->sections; sect != NULL; sect = sect->next) - if (seg_info (sect)->tc_segment_info_data.current_it.state - == MANUAL_IT_BLOCK) - { - as_warn (_("section '%s' finished with an open IT block."), - sect->name); - } + { + segment_info_type *seginfo = seg_info (sect); + + if (seginfo && seginfo->tc_segment_info_data.current_it.state + == MANUAL_IT_BLOCK) + { + as_warn (_("section '%s' finished with an open IT block."), + sect->name); + } + } #else if (now_it.state == MANUAL_IT_BLOCK) as_warn (_("file finished with an open IT block.")); diff -rNU3 dist.orig/gas/config/tc-m68k.c dist/gas/config/tc-m68k.c --- dist.orig/gas/config/tc-m68k.c 2012-05-16 12:26:47.000000000 +0200 +++ dist/gas/config/tc-m68k.c 2015-10-18 13:11:13.000000000 +0200 @@ -7426,12 +7426,12 @@ } } - /* Remove 'm' or 'mc' prefix from 68k variants. */ + /* Remove 'm' or 'mc' prefix from 68k or coldfire variants. */ if (allow_m) { if (arg[0] == 'm') { - if (arg[1] == '6') + if (arg[1] == '6' || arg[1] == '5') arg += 1; else if (arg[1] == 'c' && arg[2] == '6') arg += 2; diff -rNU3 dist.orig/gas/config/tc-mips.c dist/gas/config/tc-mips.c --- dist.orig/gas/config/tc-mips.c 2012-09-04 16:21:03.000000000 +0200 +++ dist/gas/config/tc-mips.c 2015-10-18 13:11:13.000000000 +0200 @@ -909,6 +909,9 @@ NUM_FIX_VR4120_CLASSES }; +/* ...likewise -mtrap-zero-jump. */ +static bfd_boolean mips_trap_zero_jump; + /* ...likewise -mfix-loongson2f-jump. */ static bfd_boolean mips_fix_loongson2f_jump; @@ -941,6 +944,8 @@ efficient expansion. */ static int mips_relax_branch; + +static int mips_fix_loongson2f_btb; /* The expansion of many macros depends on the type of symbol that they refer to. For example, when generating position-dependent code, @@ -1316,6 +1321,7 @@ static void mips16_macro_build (expressionS *, const char *, const char *, va_list *); static void load_register (int, expressionS *, int); +static void macro_build (expressionS *, const char *, const char *, ...); static void macro_start (void); static void macro_end (void); static void macro (struct mips_cl_insn * ip); @@ -3626,6 +3632,35 @@ return nops; } +static void +trap_zero_jump (struct mips_cl_insn * ip) +{ + if (strcmp (ip->insn_mo->name, "j") == 0 + || strcmp (ip->insn_mo->name, "jr") == 0 + || strcmp (ip->insn_mo->name, "jalr") == 0) + { + int sreg; + + if (mips_opts.warn_about_macros) + return; + + sreg = EXTRACT_OPERAND (0, RS, *ip); + if (mips_opts.isa == ISA_MIPS32 + || mips_opts.isa == ISA_MIPS32R2 + || mips_opts.isa == ISA_MIPS64 + || mips_opts.isa == ISA_MIPS64R2) + { + expressionS ep; + ep.X_op = O_constant; + ep.X_add_number = 4096; + macro_build (&ep, "tltiu", "s,j", sreg, BFD_RELOC_LO16); + } + else if (mips_opts.isa != ISA_UNKNOWN + && mips_opts.isa != ISA_MIPS1) + macro_build (NULL, "teq", "s,t", sreg, 0); + } +} + /* Fix NOP issue: Replace nops by "or at,at,zero". */ static void @@ -3663,6 +3698,16 @@ ep.X_add_number = 0xffff; macro_build (&ep, "ori", "t,r,i", ATREG, ATREG, BFD_RELOC_LO16); macro_build (NULL, "and", "d,v,t", sreg, sreg, ATREG); + /* Hide these three instructions to avoid getting a ``macro expanded into + multiple instructions'' warning. */ + if (mips_relax.sequence != 2) { + mips_macro_warning.sizes[0] -= 3 * 4; + mips_macro_warning.insns[0] -= 3; + } + if (mips_relax.sequence != 1) { + mips_macro_warning.sizes[1] -= 3 * 4; + mips_macro_warning.insns[1] -= 3; + } } } @@ -3718,6 +3763,11 @@ if (mips_opts.mips16 && history[0].fixp[0]) return FALSE; + if (mips_fix_loongson2f) + fix_loongson2f (ip); + if (mips_trap_zero_jump) + trap_zero_jump (ip); + /* If the branch is itself the target of a branch, we can not swap. We cheat on this; all we check for is whether there is a label on this instruction. If there are any branches to anything other than @@ -4764,6 +4814,45 @@ r[i] = (bfd_reloc_code_real_type) va_arg (*args, int); } +/* Fix jump through register issue on loongson2f processor for kernel code: + force a BTB clear before the jump to prevent it from being incorrectly + prefetched by the branch prediction engine. */ + +static void +macro_build_jrpatch (expressionS *ep, unsigned int sreg) +{ + if (!mips_fix_loongson2f_btb) + return; + + if (sreg == ZERO || sreg == KT0 || sreg == KT1 || sreg == AT) + return; + + if (!mips_opts.at) + { + as_warn (_("unable to apply loongson2f BTB workaround when .set noat")); + return; + } + + /* li $at, COP_0_BTB_CLEAR | COP_0_RAS_DISABLE */ + ep->X_op = O_constant; + ep->X_add_number = 3; + macro_build (ep, "ori", "t,r,i", AT, ZERO, BFD_RELOC_LO16); + + /* dmtc0 $at, COP_0_DIAG */ + macro_build (NULL, "dmtc0", "t,G", AT, 22); + + /* Hide these two instructions to avoid getting a ``macro expanded into + multiple instructions'' warning. */ + if (mips_relax.sequence != 2) { + mips_macro_warning.sizes[0] -= 2 * 4; + mips_macro_warning.insns[0] -= 2; + } + if (mips_relax.sequence != 1) { + mips_macro_warning.sizes[1] -= 2 * 4; + mips_macro_warning.insns[1] -= 2; + } +} + /* Build an instruction created by a macro expansion. This is passed a pointer to the count of instructions created so far, an expression, the name of the instruction to build, an operand format @@ -7637,6 +7726,26 @@ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", treg, tempreg, breg); break; + case M_JR_S: + macro_build_jrpatch (&expr1, sreg); + macro_build (NULL, "jr", "s", sreg); + return; /* didn't modify $at */ + + case M_J_S: + macro_build_jrpatch (&expr1, sreg); + macro_build (NULL, "j", "s", sreg); + return; /* didn't modify $at */ + + case M_JALR_S: + macro_build_jrpatch (&expr1, sreg); + macro_build (NULL, "jalr", "s", sreg); + return; /* didn't modify $at */ + + case M_JALR_DS: + macro_build_jrpatch (&expr1, sreg); + macro_build (NULL, "jalr", "d,s", dreg, sreg); + return; /* didn't modify $at */ + case M_MSGSND: gas_assert (!mips_opts.micromips); { @@ -9126,18 +9235,28 @@ case M_SAA_AB: - ab = 1; + ab = (offset_expr.X_op != O_constant || offset_expr.X_add_number != 0); case M_SAA_OB: s = "saa"; off0 = 1; fmt = "t,(b)"; + if (!ab) + { + tempreg = AT; + goto ld_noat; + } goto ld_st; case M_SAAD_AB: - ab = 1; + ab = (offset_expr.X_op != O_constant || offset_expr.X_add_number != 0); case M_SAAD_OB: s = "saad"; off0 = 1; fmt = "t,(b)"; + if (!ab) + { + tempreg = AT; + goto ld_noat; + } goto ld_st; /* New code added to support COPZ instructions. @@ -14350,6 +14469,8 @@ OPTION_SINGLE_FLOAT, OPTION_DOUBLE_FLOAT, OPTION_32, + OPTION_TRAP_ZERO_JUMP, + OPTION_NO_TRAP_ZERO_JUMP, #ifdef OBJ_ELF OPTION_CALL_SHARED, OPTION_CALL_NONPIC, @@ -14364,6 +14485,8 @@ OPTION_NO_PDR, OPTION_MVXWORKS_PIC, #endif /* OBJ_ELF */ + OPTION_FIX_LOONGSON2F_BTB, + OPTION_NO_FIX_LOONGSON2F_BTB, OPTION_END_OF_ENUM }; @@ -14421,6 +14544,8 @@ {"mno-fix-loongson2f-jump", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_JUMP}, {"mfix-loongson2f-nop", no_argument, NULL, OPTION_FIX_LOONGSON2F_NOP}, {"mno-fix-loongson2f-nop", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_NOP}, + {"mfix-loongson2f-btb", no_argument, NULL, OPTION_FIX_LOONGSON2F_BTB}, + {"mno-fix-loongson2f-btb", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_BTB}, {"mfix-vr4120", no_argument, NULL, OPTION_FIX_VR4120}, {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120}, {"mfix-vr4130", no_argument, NULL, OPTION_FIX_VR4130}, @@ -14459,6 +14584,9 @@ make testing easier. */ {"32", no_argument, NULL, OPTION_32}, + {"mtrap-zero-jump", no_argument, NULL, OPTION_TRAP_ZERO_JUMP}, + {"mno-trap-zero-jump", no_argument, NULL, OPTION_NO_TRAP_ZERO_JUMP}, + /* ELF-specific options. */ #ifdef OBJ_ELF {"KPIC", no_argument, NULL, OPTION_CALL_SHARED}, @@ -14750,6 +14878,14 @@ mips_fix_vr4130 = 0; break; + case OPTION_FIX_LOONGSON2F_BTB: + mips_fix_loongson2f_btb = 1; + break; + + case OPTION_NO_FIX_LOONGSON2F_BTB: + mips_fix_loongson2f_btb = 0; + break; + case OPTION_FIX_CN63XXP1: mips_fix_cn63xxp1 = TRUE; break; @@ -14782,6 +14918,14 @@ mips_opts.sym32 = FALSE; break; + case OPTION_TRAP_ZERO_JUMP: + mips_trap_zero_jump = TRUE; + break; + + case OPTION_NO_TRAP_ZERO_JUMP: + mips_trap_zero_jump = FALSE; + break; + #ifdef OBJ_ELF /* When generating ELF code, we permit -KPIC and -call_shared to select SVR4_PIC, and -non_shared to select no PIC. This is @@ -19411,6 +19555,7 @@ fprintf (stream, _("\ -mfix-loongson2f-jump work around Loongson2F JUMP instructions\n\ -mfix-loongson2f-nop work around Loongson2F NOP errata\n\ +-mfix-loongson2f-btb work around Loongson2F BTB errata\n\ -mfix-vr4120 work around certain VR4120 errata\n\ -mfix-vr4130 work around VR4130 mflo/mfhi errata\n\ -mfix-24k insert a nop after ERET and DERET instructions\n\ diff -rNU3 dist.orig/gas/config/tc-openrisc.c dist/gas/config/tc-openrisc.c --- dist.orig/gas/config/tc-openrisc.c 2009-07-24 13:45:00.000000000 +0200 +++ dist/gas/config/tc-openrisc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,363 +0,0 @@ -/* tc-openrisc.c -- Assembler for the OpenRISC family. - Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 - Free Software Foundation. - Contributed by Johan Rydberg, jrydberg@opencores.org - - 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 "subsegs.h" -#include "symcat.h" -#include "opcodes/openrisc-desc.h" -#include "opcodes/openrisc-opc.h" -#include "cgen.h" - -/* Structure to hold all of the different components describing - an individual instruction. */ -typedef struct openrisc_insn openrisc_insn; - -struct openrisc_insn -{ - const CGEN_INSN * insn; - const CGEN_INSN * orig_insn; - CGEN_FIELDS fields; -#if CGEN_INT_INSN_P - CGEN_INSN_INT buffer [1]; -#define INSN_VALUE(buf) (*(buf)) -#else - unsigned char buffer [CGEN_MAX_INSN_SIZE]; -#define INSN_VALUE(buf) (buf) -#endif - char * addr; - fragS * frag; - int num_fixups; - fixS * fixups [GAS_CGEN_MAX_FIXUPS]; - int indices [MAX_OPERAND_INSTANCES]; -}; - - -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 OPENRISC_SHORTOPTS "m:" -const char * md_shortopts = OPENRISC_SHORTOPTS; - -struct option md_longopts[] = -{ - {NULL, no_argument, NULL, 0} -}; -size_t md_longopts_size = sizeof (md_longopts); - -unsigned long openrisc_machine = 0; /* default */ - -int -md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED) -{ - return 0; -} - -void -md_show_usage (FILE * stream ATTRIBUTE_UNUSED) -{ -} - -static void -ignore_pseudo (int val ATTRIBUTE_UNUSED) -{ - discard_rest_of_line (); -} - -const char openrisc_comment_chars [] = ";#"; - -/* The target specific pseudo-ops which we support. */ -const pseudo_typeS md_pseudo_table[] = -{ - { "word", cons, 4 }, - { "proc", ignore_pseudo, 0 }, - { "endproc", ignore_pseudo, 0 }, - { NULL, NULL, 0 } -}; - - - -void -md_begin (void) -{ - /* Initialize the `cgen' interface. */ - - /* Set the machine number and endian. */ - gas_cgen_cpu_desc = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, - CGEN_CPU_OPEN_ENDIAN, - CGEN_ENDIAN_BIG, - CGEN_CPU_OPEN_END); - openrisc_cgen_init_asm (gas_cgen_cpu_desc); - - /* This is a callback from cgen to gas to parse operands. */ - cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand); -} - -void -md_assemble (char * str) -{ - static int last_insn_had_delay_slot = 0; - openrisc_insn insn; - char * errmsg; - - /* Initialize GAS's cgen interface for a new instruction. */ - gas_cgen_init_parse (); - - insn.insn = openrisc_cgen_assemble_insn - (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg); - - if (!insn.insn) - { - as_bad ("%s", errmsg); - return; - } - - /* Doesn't really matter what we pass for RELAX_P here. */ - gas_cgen_finish_insn (insn.insn, insn.buffer, - CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL); - - last_insn_had_delay_slot - = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT); -} - - -/* The syntax in the manual says constants begin with '#'. - We just ignore it. */ - -void -md_operand (expressionS * expressionP) -{ - if (* input_line_pointer == '#') - { - input_line_pointer ++; - expression (expressionP); - } -} - -valueT -md_section_align (segT segment, valueT size) -{ - int align = bfd_get_section_alignment (stdoutput, segment); - return ((size + (1 << align) - 1) & (-1 << align)); -} - -symbolS * -md_undefined_symbol (char * name ATTRIBUTE_UNUSED) -{ - return 0; -} - - -/* Interface to relax_segment. */ - -/* FIXME: Look through this. */ - -const relax_typeS md_relax_table[] = -{ -/* The fields are: - 1) most positive reach of this state, - 2) most negative reach of this state, - 3) how many bytes this mode will add to the size of the current frag - 4) which index into the table to try if we can't fit into this one. */ - - /* The first entry must be unused because an `rlx_more' value of zero ends - each list. */ - {1, 1, 0, 0}, - - /* The displacement used by GAS is from the end of the 2 byte insn, - so we subtract 2 from the following. */ - /* 16 bit insn, 8 bit disp -> 10 bit range. - This doesn't handle a branch in the right slot at the border: - the "& -4" isn't taken into account. It's not important enough to - complicate things over it, so we subtract an extra 2 (or + 2 in -ve - case). */ - {511 - 2 - 2, -512 - 2 + 2, 0, 2 }, - /* 32 bit insn, 24 bit disp -> 26 bit range. */ - {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 }, - /* Same thing, but with leading nop for alignment. */ - {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 } -}; - -/* Return an initial guess of the length by which a fragment must grow to - hold a branch to reach its destination. - Also updates fr_type/fr_subtype as necessary. - - Called just before doing relaxation. - Any symbol that is now undefined will not become defined. - The guess for fr_var is ACTUALLY the growth beyond fr_fix. - Whatever we do to grow fr_fix or fr_var contributes to our returned value. - Although it may not be explicit in the frag, pretend fr_var starts with a - 0 value. */ - -int -md_estimate_size_before_relax (fragS * fragP, segT segment) -{ - /* The only thing we have to handle here are symbols outside of the - current segment. They may be undefined or in a different segment in - which case linker scripts may place them anywhere. - However, we can't finish the fragment here and emit the reloc as insn - alignment requirements may move the insn about. */ - - if (S_GET_SEGMENT (fragP->fr_symbol) != segment) - { - /* The symbol is undefined in this segment. - Change the relaxation subtype to the max allowable and leave - all further handling to md_convert_frag. */ - fragP->fr_subtype = 2; - - { - const CGEN_INSN * insn; - int i; - - /* Update the recorded insn. - Fortunately we don't have to look very far. - FIXME: Change this to record in the instruction the next higher - relaxable insn to use. */ - for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++) - { - if ((strcmp (CGEN_INSN_MNEMONIC (insn), - CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn)) - == 0) - && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED)) - break; - } - if (i == 4) - abort (); - - fragP->fr_cgen.insn = insn; - return 2; - } - } - - return md_relax_table[fragP->fr_subtype].rlx_length; -} - -/* *fragP has been relaxed to its final size, and now needs to have - the bytes inside it modified to conform to the new size. - - Called after relaxation is finished. - fragP->fr_type == rs_machine_dependent. - fragP->fr_subtype is the subtype of what the address relaxed to. */ - -void -md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, - segT sec ATTRIBUTE_UNUSED, - fragS * fragP ATTRIBUTE_UNUSED) -{ - /* FIXME */ -} - - -/* Functions concerning relocs. */ - -/* The location from which a PC relative jump should be calculated, - given a PC relative reloc. */ - -long -md_pcrel_from_section (fixS * fixP, segT sec) -{ - if (fixP->fx_addsy != (symbolS *) NULL - && (! S_IS_DEFINED (fixP->fx_addsy) - || S_GET_SEGMENT (fixP->fx_addsy) != sec)) - /* The symbol is undefined (or is defined but not in this section). - Let the linker figure it out. */ - return 0; - - return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1; -} - - -/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. - Returns BFD_RELOC_NONE if no reloc type can be found. - *FIXP may be modified if desired. */ - -bfd_reloc_code_real_type -md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED, - const CGEN_OPERAND * operand, - fixS * fixP) -{ - bfd_reloc_code_real_type type; - - switch (operand->type) - { - case OPENRISC_OPERAND_ABS_26: - fixP->fx_pcrel = 0; - type = BFD_RELOC_OPENRISC_ABS_26; - goto emit; - case OPENRISC_OPERAND_DISP_26: - fixP->fx_pcrel = 1; - type = BFD_RELOC_OPENRISC_REL_26; - goto emit; - - case OPENRISC_OPERAND_HI16: - type = BFD_RELOC_HI16; - goto emit; - - case OPENRISC_OPERAND_LO16: - type = BFD_RELOC_LO16; - goto emit; - - emit: - return type; - - default : /* avoid -Wall warning */ - break; - } - - return BFD_RELOC_NONE; -} - -/* Write a value out to the object file, using the appropriate endianness. */ - -void -md_number_to_chars (char * buf, valueT val, int n) -{ - number_to_chars_bigendian (buf, val, n); -} - -/* Turn a string in input_line_pointer into a floating point constant of type - type, and store the appropriate bytes in *litP. The number of LITTLENUMS - emitted is stored in *sizeP . An error message is returned, or NULL on OK. -*/ - -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - -char * -md_atof (int type, char * litP, int * sizeP) -{ - return ieee_md_atof (type, litP, sizeP, TRUE); -} - -bfd_boolean -openrisc_fix_adjustable (fixS * fixP) -{ - /* We need the symbol name for the VTABLE entries. */ - if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - return 0; - - return 1; -} diff -rNU3 dist.orig/gas/config/tc-openrisc.h dist/gas/config/tc-openrisc.h --- dist.orig/gas/config/tc-openrisc.h 2007-07-03 13:01:04.000000000 +0200 +++ dist/gas/config/tc-openrisc.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,61 +0,0 @@ -/* tc-openrisc.h -- Header file for tc-openrisc.c. - Copyright 2001, 2002, 2003, 2005, 2007 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_OPENRISC - -#define LISTING_HEADER "OpenRISC GAS " - -/* The target BFD architecture. */ -#define TARGET_ARCH bfd_arch_openrisc - -extern unsigned long openrisc_machine; -#define TARGET_MACH (openrisc_machine) - -#define TARGET_FORMAT "elf32-openrisc" -#define TARGET_BYTES_BIG_ENDIAN 1 - -extern const char openrisc_comment_chars []; -#define tc_comment_chars openrisc_comment_chars - -/* Permit temporary numeric labels. */ -#define LOCAL_LABELS_FB 1 - -#define DIFF_EXPR_OK 1 /* .-foo gets turned into PC relative relocs */ - -/* We don't need to handle .word strangely. */ -#define WORKING_DOT_WORD - -/* Values passed to md_apply_fix don't include the symbol value. */ -#define MD_APPLY_SYM_VALUE(FIX) 0 - -#define md_apply_fix gas_cgen_md_apply_fix - -extern bfd_boolean openrisc_fix_adjustable (struct fix *); -#define tc_fix_adjustable(FIX) openrisc_fix_adjustable (FIX) - -#define tc_gen_reloc gas_cgen_tc_gen_reloc - -/* Call md_pcrel_from_section(), not md_pcrel_from(). */ -extern long md_pcrel_from_section (struct fix *, segT); -#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) - -/* For 8 vs 16 vs 32 bit branch selection. */ -extern const struct relax_type md_relax_table[]; -#define TC_GENERIC_RELAX_TABLE md_relax_table diff -rNU3 dist.orig/gas/config/tc-or1k.c dist/gas/config/tc-or1k.c --- dist.orig/gas/config/tc-or1k.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/tc-or1k.c 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,362 @@ +/* tc-or1k.c -- Assembler for the OpenRISC family. + Copyright 2001-2014 Free Software Foundation. + Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org + + 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 this program; if not, see */ +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "symcat.h" +#include "opcodes/or1k-desc.h" +#include "opcodes/or1k-opc.h" +#include "cgen.h" +#include "elf/or1k.h" +#include "dw2gencfi.h" + +/* Structure to hold all of the different components describing + an individual instruction. */ + +typedef struct +{ + const CGEN_INSN * insn; + const CGEN_INSN * orig_insn; + CGEN_FIELDS fields; +#if CGEN_INT_INSN_P + CGEN_INSN_INT buffer [1]; +#define INSN_VALUE(buf) (*(buf)) +#else + unsigned char buffer [CGEN_MAX_INSN_SIZE]; +#define INSN_VALUE(buf) (buf) +#endif + char * addr; + fragS * frag; + int num_fixups; + fixS * fixups [GAS_CGEN_MAX_FIXUPS]; + int indices [MAX_OPERAND_INSTANCES]; +} +or1k_insn; + +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 OR1K_SHORTOPTS "m:" +const char * md_shortopts = OR1K_SHORTOPTS; + +struct option md_longopts[] = +{ + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof (md_longopts); + +unsigned long or1k_machine = 0; /* default */ + +int +md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED) +{ + return 0; +} + +void +md_show_usage (FILE * stream ATTRIBUTE_UNUSED) +{ +} + +static void +ignore_pseudo (int val ATTRIBUTE_UNUSED) +{ + discard_rest_of_line (); +} + +static bfd_boolean nodelay = FALSE; +static void +s_nodelay (int val ATTRIBUTE_UNUSED) +{ + nodelay = TRUE; +} + +const char or1k_comment_chars [] = ";#"; + +/* The target specific pseudo-ops which we support. */ +const pseudo_typeS md_pseudo_table[] = +{ + { "align", s_align_bytes, 0 }, + { "word", cons, 4 }, + { "proc", ignore_pseudo, 0 }, + { "endproc", ignore_pseudo, 0 }, + { "nodelay", s_nodelay, 0 }, + { NULL, NULL, 0 } +}; + + +void +md_begin (void) +{ + /* Initialize the `cgen' interface. */ + + /* Set the machine number and endian. */ + gas_cgen_cpu_desc = or1k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, + CGEN_CPU_OPEN_ENDIAN, + CGEN_ENDIAN_BIG, + CGEN_CPU_OPEN_END); + or1k_cgen_init_asm (gas_cgen_cpu_desc); + + /* This is a callback from cgen to gas to parse operands. */ + cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand); +} + +void +md_assemble (char * str) +{ + static int last_insn_had_delay_slot = 0; + or1k_insn insn; + char * errmsg; + + /* Initialize GAS's cgen interface for a new instruction. */ + gas_cgen_init_parse (); + + insn.insn = or1k_cgen_assemble_insn + (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg); + + if (!insn.insn) + { + as_bad ("%s", errmsg); + return; + } + + /* Doesn't really matter what we pass for RELAX_P here. */ + gas_cgen_finish_insn (insn.insn, insn.buffer, + CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL); + + last_insn_had_delay_slot + = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT); + (void) last_insn_had_delay_slot; +} + + +/* The syntax in the manual says constants begin with '#'. + We just ignore it. */ + +void +md_operand (expressionS * expressionP) +{ + if (* input_line_pointer == '#') + { + input_line_pointer ++; + expression (expressionP); + } +} + +valueT +md_section_align (segT segment, valueT size) +{ + int align = bfd_get_section_alignment (stdoutput, segment); + return ((size + (1 << align) - 1) & (-1 << align)); +} + +symbolS * +md_undefined_symbol (char * name ATTRIBUTE_UNUSED) +{ + return 0; +} + + +/* Interface to relax_segment. */ + +const relax_typeS md_relax_table[] = +{ +/* The fields are: + 1) most positive reach of this state, + 2) most negative reach of this state, + 3) how many bytes this mode will add to the size of the current frag + 4) which index into the table to try if we can't fit into this one. */ + + /* The first entry must be unused because an `rlx_more' value of zero ends + each list. */ + {1, 1, 0, 0}, + + /* The displacement used by GAS is from the end of the 4 byte insn, + so we subtract 4 from the following. */ + {(((1 << 25) - 1) << 2) - 4, -(1 << 25) - 4, 0, 0}, +}; + +int +md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED) +{ + return md_relax_table[fragP->fr_subtype].rlx_length; +} + +/* *fragP has been relaxed to its final size, and now needs to have + the bytes inside it modified to conform to the new size. + + Called after relaxation is finished. + fragP->fr_type == rs_machine_dependent. + fragP->fr_subtype is the subtype of what the address relaxed to. */ + +void +md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, + segT sec ATTRIBUTE_UNUSED, + fragS * fragP ATTRIBUTE_UNUSED) +{ + /* FIXME */ +} + + +/* Functions concerning relocs. */ + +/* The location from which a PC relative jump should be calculated, + given a PC relative reloc. */ + +long +md_pcrel_from_section (fixS * fixP, segT sec) +{ + if (fixP->fx_addsy != (symbolS *) NULL + && (! S_IS_DEFINED (fixP->fx_addsy) + || (S_GET_SEGMENT (fixP->fx_addsy) != sec) + || S_IS_EXTERNAL (fixP->fx_addsy) + || S_IS_WEAK (fixP->fx_addsy))) + { + /* The symbol is undefined (or is defined but not in this section). + Let the linker figure it out. */ + return 0; + } + + return fixP->fx_frag->fr_address + fixP->fx_where; +} + + +/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. + Returns BFD_RELOC_NONE if no reloc type can be found. + *FIXP may be modified if desired. */ + +bfd_reloc_code_real_type +md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED, + const CGEN_OPERAND * operand, + fixS * fixP) +{ + if (fixP->fx_cgen.opinfo) + return fixP->fx_cgen.opinfo; + + switch (operand->type) + { + case OR1K_OPERAND_DISP26: + fixP->fx_pcrel = 1; + return BFD_RELOC_OR1K_REL_26; + + default: /* avoid -Wall warning */ + return BFD_RELOC_NONE; + } +} + +/* Write a value out to the object file, using the appropriate endianness. */ + +void +md_number_to_chars (char * buf, valueT val, int n) +{ + number_to_chars_bigendian (buf, val, n); +} + +/* Turn a string in input_line_pointer into a floating point constant of type + type, and store the appropriate bytes in *litP. The number of LITTLENUMS + emitted is stored in *sizeP . An error message is returned, or NULL on OK. */ + +/* Equal to MAX_PRECISION in atof-ieee.c. */ +#define MAX_LITTLENUMS 6 + +char * +md_atof (int type, char * litP, int * sizeP) +{ + return ieee_md_atof (type, litP, sizeP, TRUE); +} + +bfd_boolean +or1k_fix_adjustable (fixS * fixP) +{ + /* We need the symbol name for the VTABLE entries. */ + if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return FALSE; + + return TRUE; +} + +#define GOT_NAME "_GLOBAL_OFFSET_TABLE_" + +arelent * +tc_gen_reloc (asection *sec, fixS *fx) +{ + bfd_reloc_code_real_type code = fx->fx_r_type; + + if (fx->fx_addsy != NULL + && strcmp (S_GET_NAME (fx->fx_addsy), GOT_NAME) == 0 + && (code == BFD_RELOC_OR1K_GOTPC_HI16 + || code == BFD_RELOC_OR1K_GOTPC_LO16)) + { + arelent * reloc; + + reloc = xmalloc (sizeof (* reloc)); + reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy); + reloc->address = fx->fx_frag->fr_address + fx->fx_where; + reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type); + reloc->addend = fx->fx_offset; + return reloc; + } + + return gas_cgen_tc_gen_reloc (sec, fx); +} + +void +or1k_apply_fix (struct fix *f, valueT *t, segT s) +{ + gas_cgen_md_apply_fix (f, t, s); + + switch (f->fx_r_type) + { + case BFD_RELOC_OR1K_TLS_GD_HI16: + case BFD_RELOC_OR1K_TLS_GD_LO16: + case BFD_RELOC_OR1K_TLS_LDM_HI16: + case BFD_RELOC_OR1K_TLS_LDM_LO16: + case BFD_RELOC_OR1K_TLS_LDO_HI16: + case BFD_RELOC_OR1K_TLS_LDO_LO16: + case BFD_RELOC_OR1K_TLS_IE_HI16: + case BFD_RELOC_OR1K_TLS_IE_LO16: + case BFD_RELOC_OR1K_TLS_LE_HI16: + case BFD_RELOC_OR1K_TLS_LE_LO16: + S_SET_THREAD_LOCAL (f->fx_addsy); + break; + default: + break; + } +} + +void +or1k_elf_final_processing (void) +{ + if (nodelay) + elf_elfheader (stdoutput)->e_flags |= EF_OR1K_NODELAY; +} + +/* Standard calling conventions leave the CFA at SP on entry. */ + +void +or1k_cfi_frame_initial_instructions (void) +{ + cfi_add_CFA_def_cfa_register (1); +} + diff -rNU3 dist.orig/gas/config/tc-or1k.h dist/gas/config/tc-or1k.h --- dist.orig/gas/config/tc-or1k.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/tc-or1k.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,79 @@ +/* tc-or1k.h -- Header file for tc-or1k.c. + Copyright 2001-2014 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 this program; if not, see */ + +#define TC_OR1K + +#define LISTING_HEADER "Or1k GAS " + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_or1k + +extern unsigned long or1k_machine; +#define TARGET_MACH (or1k_machine) + +#define TARGET_FORMAT "elf32-or1k" +#define TARGET_BYTES_BIG_ENDIAN 1 + +extern const char or1k_comment_chars []; +#define tc_comment_chars or1k_comment_chars + +/* Permit temporary numeric labels. */ +#define LOCAL_LABELS_FB 1 + +#define DIFF_EXPR_OK 1 /* .-foo gets turned into PC relative relocs. */ + +/* We don't need to handle .word strangely. */ +#define WORKING_DOT_WORD + +/* Values passed to md_apply_fix don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +#define md_apply_fix or1k_apply_fix +extern void or1k_apply_fix (struct fix *, valueT *, segT); + +extern bfd_boolean or1k_fix_adjustable (struct fix *); +#define tc_fix_adjustable(FIX) or1k_fix_adjustable (FIX) + +/* Call md_pcrel_from_section(), not md_pcrel_from(). */ +extern long md_pcrel_from_section (struct fix *, segT); +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) + +/* For 8 vs 16 vs 32 bit branch selection. */ +extern const struct relax_type md_relax_table[]; +#define TC_GENERIC_RELAX_TABLE md_relax_table + +#define GAS_CGEN_PCREL_R_TYPE(r_type) gas_cgen_pcrel_r_type(r_type) + +#define elf_tc_final_processing or1k_elf_final_processing +void or1k_elf_final_processing (void); + +/* Enable cfi directives. */ +#define TARGET_USE_CFIPOP 1 + +/* Stack grows to lower addresses and wants 4 byte boundary. */ +#define DWARF2_CIE_DATA_ALIGNMENT -4 + +/* Define the column that represents the PC. */ +#define DWARF2_DEFAULT_RETURN_COLUMN 9 + +/* or1k instructions are 4 bytes long. */ +#define DWARF2_LINE_MIN_INSN_LENGTH 4 + +#define tc_cfi_frame_initial_instructions \ + or1k_cfi_frame_initial_instructions +extern void or1k_cfi_frame_initial_instructions (void); diff -rNU3 dist.orig/gas/config/tc-or32.c dist/gas/config/tc-or32.c --- dist.orig/gas/config/tc-or32.c 2012-05-17 17:13:16.000000000 +0200 +++ dist/gas/config/tc-or32.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,967 +0,0 @@ -/* Assembly backend for the OpenRISC 1000. - Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010, 2012 - Free Software Foundation, Inc. - Contributed by Damjan Lampret . - Modified bu Johan Rydberg, . - Based upon a29k port. - - 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. */ - -/* tc-a29k.c used as a template. */ - -#include "as.h" -#include "safe-ctype.h" -#include "opcode/or32.h" -#include "elf/or32.h" - -#define DEBUG 0 - -#ifndef REGISTER_PREFIX -#define REGISTER_PREFIX '%' -#endif - -/* Make it easier to clone this machine desc into another one. */ -#define machine_opcode or32_opcode -#define machine_opcodes or32_opcodes -#define machine_ip or32_ip -#define machine_it or32_it - -/* Handle of the OPCODE hash table. */ -static struct hash_control *op_hash = NULL; - -struct machine_it -{ - char * error; - unsigned long opcode; - struct nlist * nlistp; - expressionS exp; - int pcrel; - int reloc_offset; /* Offset of reloc within insn. */ - int reloc; -} -the_insn; - -const pseudo_typeS md_pseudo_table[] = -{ - {"align", s_align_bytes, 4 }, - {"space", s_space, 0 }, - {"cputype", s_ignore, 0 }, - {"reg", s_lsym, 0 }, /* Register equate, same as equ. */ - {"sect", s_ignore, 0 }, /* Creation of coff sections. */ - {"proc", s_ignore, 0 }, /* Start of a function. */ - {"endproc", s_ignore, 0 }, /* Function end. */ - {"word", cons, 4 }, - {NULL, 0, 0 }, -}; - -int md_short_jump_size = 4; -int md_long_jump_size = 4; - -/* This array holds the chars that always start a comment. - If the pre-processor is disabled, these aren't very useful. */ -const char comment_chars[] = "#"; - -/* This array holds the chars that only start a comment at the beginning of - a line. If the line seems to have the form '# 123 filename' - .line and .file directives will appear in the pre-processed output. */ -/* Note that input_file.c hand checks for '#' at the beginning of the - first line of the input file. This is because the compiler outputs - #NO_APP at the beginning of its output. */ -/* Also note that comments like this one will always work. */ -const char line_comment_chars[] = "#"; - -/* We needed an unused char for line separation to work around the - lack of macros, using sed and such. */ -const char line_separator_chars[] = ";"; - -/* Chars that can be used to separate mant from exp in floating point nums. */ -const char EXP_CHARS[] = "eE"; - -/* Chars that mean this number is a floating point constant. - As in 0f12.456 - or 0d1.2345e12. */ -const char FLT_CHARS[] = "rRsSfFdDxXpP"; - -/* "l.jalr r9" precalculated opcode. */ -static unsigned long jalr_r9_opcode; - -static void machine_ip (char *); - - -/* Set bits in machine opcode according to insn->encoding - description and passed operand. */ - -static void -encode (const struct machine_opcode *insn, - unsigned long *opcode, - signed long param_val, - char param_ch) -{ - int opc_pos = 0; - int param_pos = 0; - char *enc; - -#if DEBUG - printf (" encode: opcode=%.8lx param_val=%.8lx abs=%.8lx param_ch=%c\n", - *opcode, param_val, abs (param_val), param_ch); -#endif - for (enc = insn->encoding; *enc != '\0'; enc++) - if (*enc == param_ch) - { - if (enc - 2 >= insn->encoding && (*(enc - 2) == '0') && (*(enc - 1) == 'x')) - continue; - else - param_pos ++; - } - - opc_pos = 32; - - for (enc = insn->encoding; *enc != '\0';) - { - if ((*enc == '0') && (*(enc + 1) == 'x')) - { - int tmp = strtol (enc, NULL, 16); - - opc_pos -= 4; - *opcode |= tmp << opc_pos; - enc += 3; - } - else if ((*enc == '0') || (*enc == '-')) - { - opc_pos--; - enc++; - } - else if (*enc == '1') - { - opc_pos--; - *opcode |= 1 << opc_pos; - enc++; - } - else if (*enc == param_ch) - { - opc_pos--; - param_pos--; - *opcode |= ((param_val >> param_pos) & 0x1) << opc_pos; - enc++; - } - else if (ISALPHA (*enc)) - { - opc_pos--; - enc++; - } - else - enc++; - } - -#if DEBUG - printf (" opcode=%.8lx\n", *opcode); -#endif -} - -/* This function is called once, at assembler startup time. It should - set up all the tables, etc., that the MD part of the assembler will - need. */ - -void -md_begin (void) -{ - const char *retval = NULL; - int lose = 0; - int skipnext = 0; - unsigned int i; - - /* Hash up all the opcodes for fast use later. */ - op_hash = hash_new (); - - for (i = 0; i < or32_num_opcodes; i++) - { - const char *name = machine_opcodes[i].name; - - if (skipnext) - { - skipnext = 0; - continue; - } - - retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]); - if (retval != NULL) - { - fprintf (stderr, "internal error: can't hash `%s': %s\n", - machine_opcodes[i].name, retval); - lose = 1; - } - } - - if (lose) - as_fatal (_("Broken assembler. No assembly attempted.")); - - encode (&machine_opcodes[insn_index ("l.jalr")], &jalr_r9_opcode, 9, 'B'); -} - -/* Returns non zero if instruction is to be used. */ - -static int -check_invalid_opcode (unsigned long opcode) -{ - return opcode == jalr_r9_opcode; -} - -/* Assemble a single instruction. Its label has already been handled - by the generic front end. We just parse opcode and operands, and - produce the bytes of data and relocation. */ - -void -md_assemble (char *str) -{ - char *toP; - -#if DEBUG - printf ("NEW INSTRUCTION\n"); -#endif - - know (str); - machine_ip (str); - toP = frag_more (4); - - /* Put out the opcode. */ - md_number_to_chars (toP, the_insn.opcode, 4); - - /* Put out the symbol-dependent stuff. */ - if (the_insn.reloc != BFD_RELOC_NONE) - { - fix_new_exp (frag_now, - (toP - frag_now->fr_literal + the_insn.reloc_offset), - 4, /* size */ - &the_insn.exp, - the_insn.pcrel, - the_insn.reloc); - } -} - -/* This is true of the we have issued a "lo(" or "hi"(. */ -static int waiting_for_shift = 0; - -static int mask_or_shift = 0; - -static char * -parse_operand (char *s, expressionS *operandp, int opt) -{ - char *save = input_line_pointer; - char *new_pointer; - -#if DEBUG - printf (" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt); -#endif - - input_line_pointer = s; - - if (strncasecmp (s, "HI(", 3) == 0) - { - waiting_for_shift = 1; - mask_or_shift = BFD_RELOC_HI16; - - input_line_pointer += 3; - } - else if (strncasecmp (s, "LO(", 3) == 0) - { - mask_or_shift = BFD_RELOC_LO16; - - input_line_pointer += 3; - } - else - mask_or_shift = 0; - - if ((*s == '(') && (*(s+1) == 'r')) - s++; - - if ((*s == 'r') && ISDIGIT (*(s + 1))) - { - operandp->X_add_number = strtol (s + 1, NULL, 10); - operandp->X_op = O_register; - for (; (*s != ',') && (*s != '\0');) - s++; - input_line_pointer = save; - return s; - } - - expression (operandp); - - if (operandp->X_op == O_absent) - { - if (! opt) - as_bad (_("missing operand")); - else - { - operandp->X_add_number = 0; - operandp->X_op = O_constant; - } - } - - new_pointer = input_line_pointer; - input_line_pointer = save; - -#if DEBUG - printf (" %s=parse_operand(%s): operandp->X_op = %u\n", new_pointer, s, - operandp->X_op); -#endif - - return new_pointer; -} - -/* Instruction parsing. Takes a string containing the opcode. - Operands are at input_line_pointer. Output is in the_insn. - Warnings or errors are generated. */ - -static void -machine_ip (char *str) -{ - char *s; - const char *args; - const struct machine_opcode *insn; - unsigned long opcode; - expressionS the_operand; - expressionS *operand = &the_operand; - unsigned int regno; - int reloc = BFD_RELOC_NONE; - -#if DEBUG - printf ("machine_ip(%s)\n", str); -#endif - - s = str; - for (; ISALNUM (*s) || *s == '.'; ++s) - if (ISUPPER (*s)) - *s = TOLOWER (*s); - - switch (*s) - { - case '\0': - break; - - case ' ': /* FIXME-SOMEDAY more whitespace. */ - *s++ = '\0'; - break; - - default: - as_bad (_("unknown opcode1: `%s'"), str); - return; - } - - if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL) - { - as_bad (_("unknown opcode2 `%s'."), str); - return; - } - - opcode = 0; - memset (&the_insn, '\0', sizeof (the_insn)); - the_insn.reloc = BFD_RELOC_NONE; - - reloc = BFD_RELOC_NONE; - - /* Build the opcode, checking as we go to make sure that the - operands match. - - If an operand matches, we modify the_insn or opcode appropriately, - and do a "continue". If an operand fails to match, we "break". */ - if (insn->args[0] != '\0') - /* Prime the pump. */ - s = parse_operand (s, operand, insn->args[0] == 'I'); - - for (args = insn->args;; ++args) - { -#if DEBUG - printf (" args = %s\n", args); -#endif - switch (*args) - { - case '\0': /* End of args. */ - /* We have have 0 args, do the bazoooka! */ - if (args == insn->args) - encode (insn, &opcode, 0, 0); - - if (*s == '\0') - { - /* We are truly done. */ - the_insn.opcode = opcode; - if (check_invalid_opcode (opcode)) - as_bad (_("instruction not allowed: %s"), str); - return; - } - as_bad (_("too many operands: %s"), s); - break; - - case ',': /* Must match a comma. */ - if (*s++ == ',') - { - reloc = BFD_RELOC_NONE; - - /* Parse next operand. */ - s = parse_operand (s, operand, args[1] == 'I'); -#if DEBUG - printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n", - operand->X_add_number, args, s); -#endif - continue; - } - break; - - case '(': /* Must match a (. */ - s = parse_operand (s, operand, args[1] == 'I'); - continue; - - case ')': /* Must match a ). */ - continue; - - case 'r': /* A general register. */ - args++; - - if (operand->X_op != O_register) - break; /* Only registers. */ - - know (operand->X_add_symbol == 0); - know (operand->X_op_symbol == 0); - regno = operand->X_add_number; - encode (insn, &opcode, regno, *args); -#if DEBUG - printf (" r: operand->X_op = %d\n", operand->X_op); -#endif - continue; - - default: - /* if (! ISALPHA (*args)) - break; */ /* Only immediate values. */ - - if (mask_or_shift) - { -#if DEBUG - printf ("mask_or_shift = %d\n", mask_or_shift); -#endif - reloc = mask_or_shift; - } - mask_or_shift = 0; - - if (strncasecmp (args, "LO(", 3) == 0) - { -#if DEBUG - printf ("reloc_const\n"); -#endif - reloc = BFD_RELOC_LO16; - } - else if (strncasecmp (args, "HI(", 3) == 0) - { -#if DEBUG - printf ("reloc_consth\n"); -#endif - reloc = BFD_RELOC_HI16; - } - - if (*s == '(') - operand->X_op = O_constant; - else if (*s == ')') - s += 1; -#if DEBUG - printf (" default case: operand->X_add_number = %d, *args = %s, *s = %s\n", operand->X_add_number, args, s); -#endif - if (operand->X_op == O_constant) - { - if (reloc == BFD_RELOC_NONE) - { - bfd_vma v, mask; - - mask = 0x3ffffff; - v = abs (operand->X_add_number) & ~ mask; - if (v) - as_bad (_("call/jmp target out of range (1)")); - } - - if (reloc == BFD_RELOC_HI16) - operand->X_add_number = ((operand->X_add_number >> 16) & 0xffff); - - the_insn.pcrel = 0; - encode (insn, &opcode, operand->X_add_number, *args); - /* the_insn.reloc = BFD_RELOC_NONE; */ - continue; - } - - if (reloc == BFD_RELOC_NONE) - the_insn.reloc = BFD_RELOC_32_GOT_PCREL; - else - the_insn.reloc = reloc; - - /* the_insn.reloc = insn->reloc; */ -#if DEBUG - printf (" reloc sym=%d\n", the_insn.reloc); - printf (" BFD_RELOC_NONE=%d\n", BFD_RELOC_NONE); -#endif - the_insn.exp = *operand; - - /* the_insn.reloc_offset = 1; */ - the_insn.pcrel = 1; /* Assume PC-relative jump. */ - - /* FIXME-SOON, Do we figure out whether abs later, after - know sym val? */ - if (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_HI16) - the_insn.pcrel = 0; - - encode (insn, &opcode, operand->X_add_number, *args); - continue; - } - - /* Types or values of args don't match. */ - as_bad (_("invalid operands")); - return; - } -} - -char * -md_atof (int type, char * litP, int * sizeP) -{ - return ieee_md_atof (type, litP, sizeP, TRUE); -} - -/* Write out big-endian. */ - -void -md_number_to_chars (char *buf, valueT val, int n) -{ - number_to_chars_bigendian (buf, val, n); -} - -void -md_apply_fix (fixS * fixP, valueT * val, segT seg ATTRIBUTE_UNUSED) -{ - char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - long t_val; - - t_val = (long) *val; - -#if DEBUG - printf ("md_apply_fix val:%x\n", t_val); -#endif - - fixP->fx_addnumber = t_val; /* Remember value for emit_reloc. */ - - switch (fixP->fx_r_type) - { - case BFD_RELOC_32: /* XXXXXXXX pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val >> 24; - buf[1] = t_val >> 16; - buf[2] = t_val >> 8; - buf[3] = t_val; - break; - - case BFD_RELOC_16: /* XXXX0000 pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val >> 8; - buf[1] = t_val; - break; - - case BFD_RELOC_8: /* XX000000 pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[0] = t_val; - break; - - case BFD_RELOC_LO16: /* 0000XXXX pattern in a word. */ -#if DEBUG - printf ("reloc_const: val=%x\n", t_val); -#endif - buf[2] = t_val >> 8; /* Holds bits 0000XXXX. */ - buf[3] = t_val; - break; - - case BFD_RELOC_HI16: /* 0000XXXX pattern in a word. */ -#if DEBUG - printf ("reloc_consth: val=%x\n", t_val); -#endif - buf[2] = t_val >> 24; /* Holds bits XXXX0000. */ - buf[3] = t_val >> 16; - break; - - case BFD_RELOC_32_GOT_PCREL: /* 0000XXXX pattern in a word. */ - if (!fixP->fx_done) - ; - else if (fixP->fx_pcrel) - { - long v = t_val >> 28; - - if (v != 0 && v != -1) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("call/jmp target out of range (2)")); - } - else - /* This case was supposed to be handled in machine_ip. */ - abort (); - - buf[0] |= (t_val >> 26) & 0x03; /* Holds bits 0FFFFFFC of address. */ - buf[1] = t_val >> 18; - buf[2] = t_val >> 10; - buf[3] = t_val >> 2; - break; - - case BFD_RELOC_VTABLE_INHERIT: - case BFD_RELOC_VTABLE_ENTRY: - fixP->fx_done = 0; - break; - - case BFD_RELOC_NONE: - default: - as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type); - break; - } - - if (fixP->fx_addsy == (symbolS *) NULL) - fixP->fx_done = 1; -} - -/* Should never be called for or32. */ - -void -md_create_short_jump (char * ptr ATTRIBUTE_UNUSED, - addressT from_addr ATTRIBUTE_UNUSED, - addressT to_addr ATTRIBUTE_UNUSED, - fragS * frag ATTRIBUTE_UNUSED, - symbolS * to_symbol ATTRIBUTE_UNUSED) -{ - as_fatal ("or32_create_short_jmp\n"); -} - -/* Should never be called for or32. */ - -void -md_convert_frag (bfd * headers ATTRIBUTE_UNUSED, - segT seg ATTRIBUTE_UNUSED, - fragS * fragP ATTRIBUTE_UNUSED) -{ - as_fatal ("or32_convert_frag\n"); -} - -/* Should never be called for or32. */ - -void -md_create_long_jump (char * ptr ATTRIBUTE_UNUSED, - addressT from_addr ATTRIBUTE_UNUSED, - addressT to_addr ATTRIBUTE_UNUSED, - fragS * frag ATTRIBUTE_UNUSED, - symbolS * to_symbol ATTRIBUTE_UNUSED) -{ - as_fatal ("or32_create_long_jump\n"); -} - -/* Should never be called for or32. */ - -int -md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, - segT segtype ATTRIBUTE_UNUSED) -{ - as_fatal ("or32_estimate_size_before_relax\n"); - return 0; -} - -/* Translate internal representation of relocation info to target format. - - On sparc/29k: first 4 bytes are normal unsigned long address, next three - bytes are index, most sig. byte first. Byte 7 is broken up with - bit 7 as external, bits 6 & 5 unused, and the lower - five bits as relocation type. Next 4 bytes are long addend. */ -/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com. */ - -#ifdef OBJ_AOUT -void -tc_aout_fix_to_chars (char *where, - fixS *fixP, - relax_addressT segment_address_in_file) -{ - long r_symbolnum; - -#if DEBUG - printf ("tc_aout_fix_to_chars\n"); -#endif - - know (fixP->fx_r_type < BFD_RELOC_NONE); - know (fixP->fx_addsy != NULL); - - md_number_to_chars - (where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); - - r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) - ? S_GET_TYPE (fixP->fx_addsy) - : fixP->fx_addsy->sy_number); - - where[4] = (r_symbolnum >> 16) & 0x0ff; - where[5] = (r_symbolnum >> 8) & 0x0ff; - where[6] = r_symbolnum & 0x0ff; - where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); - - /* Also easy. */ - md_number_to_chars (&where[8], fixP->fx_addnumber, 4); -} - -#endif /* OBJ_AOUT */ - -const char *md_shortopts = ""; - -struct option md_longopts[] = -{ - { NULL, no_argument, NULL, 0 } -}; -size_t md_longopts_size = sizeof (md_longopts); - -int -md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED) -{ - return 0; -} - -void -md_show_usage (FILE * stream ATTRIBUTE_UNUSED) -{ -} - -/* This is called when a line is unrecognized. This is used to handle - definitions of or32 style local labels. */ - -int -or32_unrecognized_line (int c) -{ - int lab; - char *s; - - if (c != '$' - || ! ISDIGIT ((unsigned char) input_line_pointer[0])) - return 0; - - s = input_line_pointer; - - lab = 0; - while (ISDIGIT ((unsigned char) *s)) - { - lab = lab * 10 + *s - '0'; - ++s; - } - - if (*s != ':') - /* Not a label definition. */ - return 0; - - if (dollar_label_defined (lab)) - { - as_bad (_("label \"$%d\" redefined"), lab); - return 0; - } - - define_dollar_label (lab); - colon (dollar_label_name (lab, 0)); - input_line_pointer = s + 1; - - return 1; -} - -/* Default the values of symbols known that should be "predefined". We - don't bother to predefine them unless you actually use one, since there - are a lot of them. */ - -symbolS * -md_undefined_symbol (char *name ATTRIBUTE_UNUSED) -{ - return NULL; -} - -/* Parse an operand that is machine-specific. */ - -void -md_operand (expressionS *expressionP) -{ -#if DEBUG - printf (" md_operand(input_line_pointer = %s)\n", input_line_pointer); -#endif - - if (input_line_pointer[0] == REGISTER_PREFIX && input_line_pointer[1] == 'r') - { - /* We have a numeric register expression. No biggy. */ - input_line_pointer += 2; /* Skip %r */ - (void) expression (expressionP); - - if (expressionP->X_op != O_constant - || expressionP->X_add_number > 255) - as_bad (_("Invalid expression after %%%%\n")); - expressionP->X_op = O_register; - } - else if (input_line_pointer[0] == '&') - { - /* We are taking the 'address' of a register...this one is not - in the manual, but it *is* in traps/fpsymbol.h! What they - seem to want is the register number, as an absolute number. */ - input_line_pointer++; /* Skip & */ - (void) expression (expressionP); - - if (expressionP->X_op != O_register) - as_bad (_("invalid register in & expression")); - else - expressionP->X_op = O_constant; - } - else if (input_line_pointer[0] == '$' - && ISDIGIT ((unsigned char) input_line_pointer[1])) - { - long lab; - char *name; - symbolS *sym; - - /* This is a local label. */ - ++input_line_pointer; - lab = (long) get_absolute_expression (); - - if (dollar_label_defined (lab)) - { - name = dollar_label_name (lab, 0); - sym = symbol_find (name); - } - else - { - name = dollar_label_name (lab, 1); - sym = symbol_find_or_make (name); - } - - expressionP->X_op = O_symbol; - expressionP->X_add_symbol = sym; - expressionP->X_add_number = 0; - } - else if (input_line_pointer[0] == '$') - { - char *s; - char type; - int fieldnum, fieldlimit; - LITTLENUM_TYPE floatbuf[8]; - - /* $float(), $doubleN(), or $extendN() convert floating values - to integers. */ - s = input_line_pointer; - - ++s; - - fieldnum = 0; - if (strncmp (s, "double", sizeof "double" - 1) == 0) - { - s += sizeof "double" - 1; - type = 'd'; - fieldlimit = 2; - } - else if (strncmp (s, "float", sizeof "float" - 1) == 0) - { - s += sizeof "float" - 1; - type = 'f'; - fieldlimit = 1; - } - else if (strncmp (s, "extend", sizeof "extend" - 1) == 0) - { - s += sizeof "extend" - 1; - type = 'x'; - fieldlimit = 4; - } - else - return; - - if (ISDIGIT (*s)) - { - fieldnum = *s - '0'; - ++s; - } - if (fieldnum >= fieldlimit) - return; - - SKIP_WHITESPACE (); - if (*s != '(') - return; - ++s; - SKIP_WHITESPACE (); - - s = atof_ieee (s, type, floatbuf); - if (s == NULL) - return; - s = s; - - SKIP_WHITESPACE (); - if (*s != ')') - return; - ++s; - SKIP_WHITESPACE (); - - input_line_pointer = s; - expressionP->X_op = O_constant; - expressionP->X_unsigned = 1; - expressionP->X_add_number = ((floatbuf[fieldnum * 2] - << LITTLENUM_NUMBER_OF_BITS) - + floatbuf[fieldnum * 2 + 1]); - } -} - -/* Round up a section size to the appropriate boundary. */ - -valueT -md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size ATTRIBUTE_UNUSED) -{ - return size; /* Byte alignment is fine. */ -} - -/* Exactly what point is a PC-relative offset relative TO? - On the 29000, they're relative to the address of the instruction, - which we have set up as the address of the fixup too. */ - -long -md_pcrel_from (fixS *fixP) -{ - return fixP->fx_where + fixP->fx_frag->fr_address; -} - -/* Generate a reloc for a fixup. */ - -arelent * -tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) -{ - arelent *reloc; - - reloc = xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); - *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; - /* reloc->address = fixp->fx_frag->fr_address + fixp->fx_where + fixp->fx_addnumber;*/ - 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, - _("reloc %d not supported by object file format"), - (int) fixp->fx_r_type); - return NULL; - } - - if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - reloc->address = fixp->fx_offset; - - reloc->addend = fixp->fx_addnumber; - return reloc; -} diff -rNU3 dist.orig/gas/config/tc-or32.h dist/gas/config/tc-or32.h --- dist.orig/gas/config/tc-or32.h 2007-07-03 13:01:04.000000000 +0200 +++ dist/gas/config/tc-or32.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,56 +0,0 @@ -/* tc-or32.h -- Assemble for the OpenRISC 1000. - Copyright (C) 2002, 2003. 2005, 2007 Free Software Foundation, Inc. - Contributed by Damjan Lampret . - Based upon a29k port. - - 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_OR32 - -#define TARGET_BYTES_BIG_ENDIAN 1 - -#define LEX_DOLLAR 1 - -#ifdef OBJ_ELF -#define TARGET_FORMAT "elf32-or32" -#define TARGET_ARCH bfd_arch_or32 -#endif - -#ifdef OBJ_COFF -#define TARGET_FORMAT "coff-or32-big" -#define reloc_type int -#endif - -#define tc_unrecognized_line(c) or32_unrecognized_line (c) - -extern int or32_unrecognized_line (int); - -#define tc_coff_symbol_emit_hook(a) ; /* Not used. */ - -#define COFF_MAGIC SIPFBOMAGIC - -/* No shared lib support, so we don't need to ensure externally - visible symbols can be overridden. */ -#define EXTERN_FORCE_RELOC 0 - -#ifdef OBJ_ELF -/* Values passed to md_apply_fix don't include the symbol value. */ -#define MD_APPLY_SYM_VALUE(FIX) 0 -#endif - -#define ZERO_BASED_SEGMENTS diff -rNU3 dist.orig/gas/config/tc-riscv.c dist/gas/config/tc-riscv.c --- dist.orig/gas/config/tc-riscv.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/tc-riscv.c 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,2225 @@ +/* tc-riscv.c -- RISC-V assembler + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + This file is part of GAS. + + 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 "config.h" +#include "subsegs.h" +#include "safe-ctype.h" + +#include "itbl-ops.h" +#include "dwarf2dbg.h" +#include "dw2gencfi.h" + +#include "elf/riscv.h" +#include "opcode/riscv.h" + +#include +#include + +/* Information about an instruction, including its format, operands + and fixups. */ +struct riscv_cl_insn +{ + /* The opcode's entry in riscv_opcodes. */ + const struct riscv_opcode *insn_mo; + + /* The encoded instruction bits. */ + insn_t insn_opcode; + + /* The frag that contains the instruction. */ + struct frag *frag; + + /* The offset into FRAG of the first instruction byte. */ + long where; + + /* The relocs associated with the instruction, if any. */ + fixS *fixp; +}; + +bfd_boolean rv64 = TRUE; /* RV64 (true) or RV32 (false) */ +#define LOAD_ADDRESS_INSN (rv64 ? "ld" : "lw") +#define ADD32_INSN (rv64 ? "addiw" : "addi") + +struct riscv_subset +{ + const char* name; + int version_major; + int version_minor; + + struct riscv_subset* next; +}; + +static struct riscv_subset* riscv_subsets; + +static int +riscv_subset_supports(const char* feature) +{ + struct riscv_subset* s; + bfd_boolean rv64_insn; + + if ((rv64_insn = !strncmp(feature, "64", 2)) || !strncmp(feature, "32", 2)) + { + if (rv64 != rv64_insn) + return 0; + feature += 2; + } + + for (s = riscv_subsets; s != NULL; s = s->next) + if (strcmp(s->name, feature) == 0) + /* FIXME: once we support version numbers: + return major == s->version_major && minor <= s->version_minor; */ + return 1; + + return 0; +} + +static void +riscv_add_subset(const char* subset) +{ + struct riscv_subset* s = xmalloc(sizeof(struct riscv_subset)); + s->name = xstrdup(subset); + s->version_major = 1; + s->version_minor = 0; + s->next = riscv_subsets; + riscv_subsets = s; +} + +static void +riscv_set_arch(const char* arg) +{ + /* Formally, ISA subset names begin with RV, RV32, or RV64, but we allow the + prefix to be omitted. We also allow all-lowercase names if version + numbers and eXtensions are omitted (i.e. only some combination of imafd + is supported in this case). + + FIXME: Version numbers are not supported yet. */ + const char* subsets = "IMAFD"; + const char* p; + + for (p = arg; *p; p++) + if (!ISLOWER(*p) || strchr(subsets, TOUPPER(*p)) == NULL) + break; + + if (!*p) + { + /* Legal all-lowercase name. */ + for (p = arg; *p; p++) + { + char subset[2] = {TOUPPER(*p), 0}; + riscv_add_subset(subset); + } + return; + } + + if (strncmp(arg, "RV32", 4) == 0) + { + rv64 = FALSE; + arg += 4; + } + else if (strncmp(arg, "RV64", 4) == 0) + { + rv64 = TRUE; + arg += 4; + } + else if (strncmp(arg, "RV", 2) == 0) + arg += 2; + + if (*arg && *arg != 'I') + as_fatal("`I' must be the first ISA subset name specified (got %c)", *arg); + + for (p = arg; *p; p++) + { + if (*p == 'X') + { + const char* q = p+1; + while (ISLOWER(*q)) + q++; + + char subset[q-p+1]; + memcpy(subset, p, q-p); + subset[q-p] = 0; + + riscv_add_subset(subset); + p = q-1; + } + else if (strchr(subsets, *p) != NULL) + { + char subset[2] = {*p, 0}; + riscv_add_subset(subset); + } + else + as_fatal("unsupported ISA subset %c", *p); + } +} + +/* This is the set of options which may be modified by the .set + pseudo-op. We use a struct so that .set push and .set pop are more + reliable. */ + +struct riscv_set_options +{ + /* Generate position-independent code. */ + int pic; + /* Generate RVC code. */ + int rvc; +}; + +static struct riscv_set_options riscv_opts = +{ + 0, /* pic */ + 0, /* rvc */ +}; + +/* handle of the OPCODE hash table */ +static struct hash_control *op_hash = NULL; + +/* This array holds the chars that always start a comment. If the + pre-processor is disabled, these aren't very useful */ +const char comment_chars[] = "#"; + +/* This array holds the chars that only start a comment at the beginning of + a line. If the line seems to have the form '# 123 filename' + .line and .file directives will appear in the pre-processed output */ +/* Note that input_file.c hand checks for '#' at the beginning of the + first line of the input file. This is because the compiler outputs + #NO_APP at the beginning of its output. */ +/* Also note that C style comments are always supported. */ +const char line_comment_chars[] = "#"; + +/* This array holds machine specific line separator characters. */ +const char line_separator_chars[] = ";"; + +/* Chars that can be used to separate mant from exp in floating point nums */ +const char EXP_CHARS[] = "eE"; + +/* Chars that mean this number is a floating point constant */ +/* As in 0f12.456 */ +/* or 0d1.2345e12 */ +const char FLT_CHARS[] = "rRsSfFdDxXpP"; + +/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be + changed in read.c . Ideally it shouldn't have to know about it at all, + but nothing is ideal around here. + */ + +static char *insn_error; + +#define RELAX_BRANCH_ENCODE(uncond, toofar) \ + ((relax_substateT) \ + (0xc0000000 \ + | ((toofar) ? 1 : 0) \ + | ((uncond) ? 2 : 0))) +#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000) +#define RELAX_BRANCH_TOOFAR(i) (((i) & 1) != 0) +#define RELAX_BRANCH_UNCOND(i) (((i) & 2) != 0) + +/* Is the given value a sign-extended 32-bit value? */ +#define IS_SEXT_32BIT_NUM(x) \ + (((x) &~ (offsetT) 0x7fffffff) == 0 \ + || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff)) + +#define IS_SEXT_NBIT_NUM(x,n) \ + ({ int64_t __tmp = (x); \ + __tmp = (__tmp << (64-(n))) >> (64-(n)); \ + __tmp == (x); }) + +/* Is the given value a zero-extended 32-bit value? Or a negated one? */ +#define IS_ZEXT_32BIT_NUM(x) \ + (((x) &~ (offsetT) 0xffffffff) == 0 \ + || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff)) + +/* Replace bits MASK << SHIFT of STRUCT with the equivalent bits in + VALUE << SHIFT. VALUE is evaluated exactly once. */ +#define INSERT_BITS(STRUCT, VALUE, MASK, SHIFT) \ + (STRUCT) = (((STRUCT) & ~((insn_t)(MASK) << (SHIFT))) \ + | ((insn_t)((VALUE) & (MASK)) << (SHIFT))) + +/* Extract bits MASK << SHIFT from STRUCT and shift them right + SHIFT places. */ +#define EXTRACT_BITS(STRUCT, MASK, SHIFT) \ + (((STRUCT) >> (SHIFT)) & (MASK)) + +/* Change INSN's opcode so that the operand given by FIELD has value VALUE. + INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once. */ +#define INSERT_OPERAND(FIELD, INSN, VALUE) \ + INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD) + +/* Extract the operand given by FIELD from riscv_cl_insn INSN. */ +#define EXTRACT_OPERAND(FIELD, INSN) \ + EXTRACT_BITS ((INSN).insn_opcode, OP_MASK_##FIELD, OP_SH_##FIELD) + +/* Determine if an instruction matches an opcode. */ +#define OPCODE_MATCHES(OPCODE, OP) \ + (((OPCODE) & MASK_##OP) == MATCH_##OP) + +#define INSN_MATCHES(INSN, OP) \ + (((INSN).insn_opcode & MASK_##OP) == MATCH_##OP) + +/* Prototypes for static functions. */ + +#define internalError() \ + as_fatal (_("internal Error, line %d, %s"), __LINE__, __FILE__) + +static char *expr_end; + +/* Expressions which appear in instructions. These are set by + riscv_ip. */ + +static expressionS imm_expr; +static expressionS offset_expr; + +/* Relocs associated with imm_expr and offset_expr. */ + +static bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED; +static bfd_reloc_code_real_type offset_reloc = BFD_RELOC_UNUSED; + +/* The default target format to use. */ + +const char * +riscv_target_format (void) +{ + return rv64 ? "elf64-littleriscv" : "elf32-littleriscv"; +} + +/* Return the length of instruction INSN. */ + +static inline unsigned int +insn_length (const struct riscv_cl_insn *insn) +{ + return riscv_insn_length (insn->insn_opcode); +} + +/* Initialise INSN from opcode entry MO. Leave its position unspecified. */ + +static void +create_insn (struct riscv_cl_insn *insn, const struct riscv_opcode *mo) +{ + insn->insn_mo = mo; + insn->insn_opcode = mo->match; + insn->frag = NULL; + insn->where = 0; + insn->fixp = NULL; +} + +/* Install INSN at the location specified by its "frag" and "where" fields. */ + +static void +install_insn (const struct riscv_cl_insn *insn) +{ + char *f = insn->frag->fr_literal + insn->where; + md_number_to_chars (f, insn->insn_opcode, insn_length(insn)); +} + +/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly + and install the opcode in the new location. */ + +static void +move_insn (struct riscv_cl_insn *insn, fragS *frag, long where) +{ + insn->frag = frag; + insn->where = where; + if (insn->fixp != NULL) + { + insn->fixp->fx_frag = frag; + insn->fixp->fx_where = where; + } + install_insn (insn); +} + +/* Add INSN to the end of the output. */ + +static void +add_fixed_insn (struct riscv_cl_insn *insn) +{ + char *f = frag_more (insn_length (insn)); + move_insn (insn, frag_now, f - frag_now->fr_literal); +} + +static void +add_relaxed_insn (struct riscv_cl_insn *insn, int max_chars, int var, + relax_substateT subtype, symbolS *symbol, offsetT offset) +{ + frag_grow (max_chars); + move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal); + frag_var (rs_machine_dependent, max_chars, var, + subtype, symbol, offset, NULL); +} + +/* Compute the length of a branch sequence, and adjust the + RELAX_BRANCH_TOOFAR bit accordingly. If FRAGP is NULL, the + worst-case length is computed. */ +static int +relaxed_branch_length (fragS *fragp, asection *sec, int update) +{ + bfd_boolean toofar = TRUE; + + if (fragp) + { + bfd_boolean uncond = RELAX_BRANCH_UNCOND (fragp->fr_subtype); + + if (S_IS_DEFINED (fragp->fr_symbol) + && sec == S_GET_SEGMENT (fragp->fr_symbol)) + { + offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; + bfd_vma range; + val -= fragp->fr_address + fragp->fr_fix; + + if (uncond) + range = RISCV_JUMP_REACH; + else + range = RISCV_BRANCH_REACH; + toofar = (bfd_vma)(val + range/2) >= range; + } + + if (update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + fragp->fr_subtype = RELAX_BRANCH_ENCODE (uncond, toofar); + } + + return toofar ? 8 : 4; +} + +struct regname { + const char *name; + unsigned int num; +}; + +enum reg_class { + RCLASS_GPR, + RCLASS_FPR, + RCLASS_CSR, + RCLASS_VEC_GPR, + RCLASS_VEC_FPR, + RCLASS_MAX +}; + +static struct hash_control *reg_names_hash = NULL; + +#define ENCODE_REG_HASH(cls, n) (void*)(uintptr_t)((n)*RCLASS_MAX + (cls) + 1) +#define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX) +#define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX) + +static void +hash_reg_name (enum reg_class class, const char *name, unsigned n) +{ + void *hash = ENCODE_REG_HASH (class, n); + const char *retval = hash_insert (reg_names_hash, name, hash); + if (retval != NULL) + as_fatal (_("internal error: can't hash `%s': %s"), name, retval); +} + +static void +hash_reg_names (enum reg_class class, const char * const names[], unsigned n) +{ + unsigned i; + for (i = 0; i < n; i++) + hash_reg_name (class, names[i], i); +} + +static unsigned int +reg_lookup_internal (const char *s, enum reg_class class) +{ + struct regname *r = (struct regname *) hash_find (reg_names_hash, s); + if (r == NULL || DECODE_REG_CLASS (r) != class) + return -1; + return DECODE_REG_NUM (r); +} + +static int +reg_lookup (char **s, enum reg_class class, unsigned int *regnop) +{ + char *e; + char save_c; + int reg = -1; + + /* Find end of name. */ + e = *s; + if (is_name_beginner (*e)) + ++e; + while (is_part_of_name (*e)) + ++e; + + /* Terminate name. */ + save_c = *e; + *e = '\0'; + + /* Look for the register. Advance to next token if one was recognized. */ + if ((reg = reg_lookup_internal (*s, class)) >= 0) + *s = e; + + *e = save_c; + if (regnop) + *regnop = reg; + return reg >= 0; +} + +static int +arg_lookup(char **s, const char* const* array, size_t size, unsigned *regnop) +{ + const char *p = strchr(*s, ','); + size_t i, len = p ? (size_t)(p - *s) : strlen(*s); + + for (i = 0; i < size; i++) + if (array[i] != NULL && strncmp(array[i], *s, len) == 0) + { + *regnop = i; + *s += len; + return 1; + } + + return 0; +} + +/* For consistency checking, verify that all bits are specified either + by the match/mask part of the instruction definition, or by the + operand list. */ +static int +validate_riscv_insn (const struct riscv_opcode *opc) +{ + const char *p = opc->args; + char c; + insn_t required_bits, used_bits = opc->mask; + + if ((used_bits & opc->match) != opc->match) + { + as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"), + opc->name, opc->args); + return 0; + } + required_bits = ((insn_t)1 << (8 * riscv_insn_length (opc->match))) - 1; + /* Work around for undefined behavior of uint64_t << 64 */ + if(riscv_insn_length (opc->match) == 8) + required_bits = 0xffffffffffffffff; + +#define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift))) + while (*p) + switch (c = *p++) + { + /* Xcustom */ + case '^': + switch (c = *p++) + { + case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break; + case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break; + case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break; + case 'j': USE_BITS (OP_MASK_CUSTOM_IMM, OP_SH_CUSTOM_IMM); break; + } + break; + /* Xhwacha */ + case '#': + switch (c = *p++) + { + case 'g': USE_BITS (OP_MASK_IMMNGPR, OP_SH_IMMNGPR); break; + case 'f': USE_BITS (OP_MASK_IMMNFPR, OP_SH_IMMNFPR); break; + case 'n': USE_BITS (OP_MASK_IMMSEGNELM, OP_SH_IMMSEGNELM); break; + case 'd': USE_BITS (OP_MASK_VRD, OP_SH_VRD); break; + case 's': USE_BITS (OP_MASK_VRS, OP_SH_VRS); break; + case 't': USE_BITS (OP_MASK_VRT, OP_SH_VRT); break; + case 'r': USE_BITS (OP_MASK_VRR, OP_SH_VRR); break; + case 'D': USE_BITS (OP_MASK_VFD, OP_SH_VFD); break; + case 'S': USE_BITS (OP_MASK_VFS, OP_SH_VFS); break; + case 'T': USE_BITS (OP_MASK_VFT, OP_SH_VFT); break; + case 'R': USE_BITS (OP_MASK_VFR, OP_SH_VFR); break; + + default: + as_bad (_("internal: bad RISC-V opcode (unknown extension operand type `#%c'): %s %s"), + c, opc->name, opc->args); + return 0; + } + break; + case ',': break; + case '(': break; + case ')': break; + case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break; + case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break; + case 'A': break; + case 'D': USE_BITS (OP_MASK_RD, OP_SH_RD); break; + case 'Z': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break; + case 'E': USE_BITS (OP_MASK_CSR, OP_SH_CSR); break; + case 'I': break; + case 'R': USE_BITS (OP_MASK_RS3, OP_SH_RS3); break; + case 'S': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break; + case 'U': USE_BITS (OP_MASK_RS1, OP_SH_RS1); /* fallthru */ + case 'T': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break; + case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break; + case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break; + case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break; + case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break; + case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break; + case 'Q': USE_BITS (OP_MASK_SUCC, OP_SH_SUCC); break; + case 'o': + case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break; + case 'a': used_bits |= ENCODE_UJTYPE_IMM(-1U); break; + case 'p': used_bits |= ENCODE_SBTYPE_IMM(-1U); break; + case 'q': used_bits |= ENCODE_STYPE_IMM(-1U); break; + case 'u': used_bits |= ENCODE_UTYPE_IMM(-1U); break; + case '[': break; + case ']': break; + case '0': break; + default: + as_bad (_("internal: bad RISC-V opcode (unknown operand type `%c'): %s %s"), + c, opc->name, opc->args); + return 0; + } +#undef USE_BITS + if (used_bits != required_bits) + { + as_bad (_("internal: bad RISC-V opcode (bits 0x%lx undefined): %s %s"), + ~(long)(used_bits & required_bits), opc->name, opc->args); + return 0; + } + return 1; +} + +struct percent_op_match +{ + const char *str; + bfd_reloc_code_real_type reloc; +}; + +/* This function is called once, at assembler startup time. It should set up + all the tables, etc. that the MD part of the assembler will need. */ + +void +md_begin (void) +{ + const char *retval = NULL; + int i = 0; + + if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, 0)) + as_warn (_("Could not set architecture and machine")); + + op_hash = hash_new (); + + for (i = 0; i < NUMOPCODES;) + { + const char *name = riscv_opcodes[i].name; + + if (riscv_subset_supports(riscv_opcodes[i].subset)) + retval = hash_insert (op_hash, name, (void *) &riscv_opcodes[i]); + + if (retval != NULL) + { + fprintf (stderr, _("internal error: can't hash `%s': %s\n"), + riscv_opcodes[i].name, retval); + /* Probably a memory allocation problem? Give up now. */ + as_fatal (_("Broken assembler. No assembly attempted.")); + } + do + { + if (riscv_opcodes[i].pinfo != INSN_MACRO) + { + if (!validate_riscv_insn (&riscv_opcodes[i])) + as_fatal (_("Broken assembler. No assembly attempted.")); + } + ++i; + } + while ((i < NUMOPCODES) && !strcmp (riscv_opcodes[i].name, name)); + } + + reg_names_hash = hash_new (); + hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR); + hash_reg_names (RCLASS_GPR, riscv_gpr_names_abi, NGPR); + hash_reg_names (RCLASS_FPR, riscv_fpr_names_numeric, NFPR); + hash_reg_names (RCLASS_FPR, riscv_fpr_names_abi, NFPR); + hash_reg_names (RCLASS_VEC_GPR, riscv_vec_gpr_names, NVGPR); + hash_reg_names (RCLASS_VEC_FPR, riscv_vec_fpr_names, NVFPR); + +#define DECLARE_CSR(name, num) hash_reg_name (RCLASS_CSR, #name, num); +#include "opcode/riscv-opc.h" +#undef DECLARE_CSR + + /* set the default alignment for the text section (2**2) */ + record_alignment (text_section, 2); +} + +/* Output an instruction. IP is the instruction information. + ADDRESS_EXPR is an operand of the instruction to be used with + RELOC_TYPE. */ + +static void +append_insn (struct riscv_cl_insn *ip, expressionS *address_expr, + bfd_reloc_code_real_type reloc_type) +{ +#ifdef OBJ_ELF + dwarf2_emit_insn (0); +#endif + + gas_assert(reloc_type <= BFD_RELOC_UNUSED); + + if (address_expr != NULL) + { + if (address_expr->X_op == O_constant) + { + switch (reloc_type) + { + case BFD_RELOC_32: + ip->insn_opcode |= address_expr->X_add_number; + break; + + case BFD_RELOC_RISCV_HI20: + ip->insn_opcode |= ENCODE_UTYPE_IMM ( + RISCV_CONST_HIGH_PART (address_expr->X_add_number)); + break; + + case BFD_RELOC_RISCV_LO12_S: + ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number); + break; + + case BFD_RELOC_UNUSED: + case BFD_RELOC_RISCV_LO12_I: + ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number); + break; + + default: + internalError (); + } + reloc_type = BFD_RELOC_UNUSED; + } + else if (reloc_type == BFD_RELOC_12_PCREL) + { + add_relaxed_insn (ip, relaxed_branch_length (NULL, NULL, 0), 4, + RELAX_BRANCH_ENCODE (0, 0), + address_expr->X_add_symbol, + address_expr->X_add_number); + return; + } + else if (reloc_type < BFD_RELOC_UNUSED) + { + reloc_howto_type *howto; + + howto = bfd_reloc_type_lookup (stdoutput, reloc_type); + if (howto == NULL) + as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type); + + ip->fixp = fix_new_exp (ip->frag, ip->where, + bfd_get_reloc_size (howto), + address_expr, + reloc_type == BFD_RELOC_12_PCREL || + reloc_type == BFD_RELOC_RISCV_CALL || + reloc_type == BFD_RELOC_RISCV_JMP, + reloc_type); + + /* These relocations can have an addend that won't fit in + 4 octets for 64bit assembly. */ + if (rv64 + && ! howto->partial_inplace + && (reloc_type == BFD_RELOC_32 + || reloc_type == BFD_RELOC_64 + || reloc_type == BFD_RELOC_CTOR + || reloc_type == BFD_RELOC_RISCV_HI20 + || reloc_type == BFD_RELOC_RISCV_LO12_I + || reloc_type == BFD_RELOC_RISCV_LO12_S)) + ip->fixp->fx_no_overflow = 1; + } + } + + add_fixed_insn (ip); + + install_insn (ip); +} + +/* Build an instruction created by a macro expansion. This is passed + a pointer to the count of instructions created so far, an + expression, the name of the instruction to build, an operand format + string, and corresponding arguments. */ + +static void +macro_build (expressionS *ep, const char *name, const char *fmt, ...) +{ + const struct riscv_opcode *mo; + struct riscv_cl_insn insn; + bfd_reloc_code_real_type r; + va_list args; + + va_start (args, fmt); + + r = BFD_RELOC_UNUSED; + mo = (struct riscv_opcode *) hash_find (op_hash, name); + gas_assert (mo); + gas_assert (strcmp (name, mo->name) == 0); + + create_insn (&insn, mo); + for (;;) + { + switch (*fmt++) + { + case 'd': + INSERT_OPERAND (RD, insn, va_arg (args, int)); + continue; + + case 's': + INSERT_OPERAND (RS1, insn, va_arg (args, int)); + continue; + + case 't': + INSERT_OPERAND (RS2, insn, va_arg (args, int)); + continue; + + case '>': + INSERT_OPERAND (SHAMT, insn, va_arg (args, int)); + continue; + + case 'j': + case 'u': + case 'q': + gas_assert (ep != NULL); + r = va_arg (args, int); + continue; + + case '\0': + break; + case ',': + continue; + default: + internalError (); + } + break; + } + va_end (args); + gas_assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL); + + append_insn (&insn, ep, r); +} + +/* + * Sign-extend 32-bit mode constants that have bit 31 set and all + * higher bits unset. + */ +static void +normalize_constant_expr (expressionS *ex) +{ + if (rv64) + return; + if ((ex->X_op == O_constant || ex->X_op == O_symbol) + && IS_ZEXT_32BIT_NUM (ex->X_add_number)) + ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000) + - 0x80000000); +} + +static symbolS * +make_internal_label (void) +{ + return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg, + (valueT) frag_now_fix(), frag_now); +} + +/* Load an entry from the GOT. */ +static void +pcrel_access (int destreg, int tempreg, expressionS *ep, + const char* lo_insn, const char* lo_pattern, + bfd_reloc_code_real_type hi_reloc, + bfd_reloc_code_real_type lo_reloc) +{ + expressionS ep2; + ep2.X_op = O_symbol; + ep2.X_add_symbol = make_internal_label (); + ep2.X_add_number = 0; + + macro_build (ep, "auipc", "d,u", tempreg, hi_reloc); + macro_build (&ep2, lo_insn, lo_pattern, destreg, tempreg, lo_reloc); +} + +static void +pcrel_load (int destreg, int tempreg, expressionS *ep, const char* lo_insn, + bfd_reloc_code_real_type hi_reloc, + bfd_reloc_code_real_type lo_reloc) +{ + pcrel_access (destreg, tempreg, ep, lo_insn, "d,s,j", hi_reloc, lo_reloc); +} + +static void +pcrel_store (int srcreg, int tempreg, expressionS *ep, const char* lo_insn, + bfd_reloc_code_real_type hi_reloc, + bfd_reloc_code_real_type lo_reloc) +{ + pcrel_access (srcreg, tempreg, ep, lo_insn, "t,s,q", hi_reloc, lo_reloc); +} + +/* PC-relative function call using AUIPC/JALR, relaxed to JAL. */ +static void +riscv_call (int destreg, int tempreg, expressionS *ep, + bfd_reloc_code_real_type reloc) +{ + macro_build (ep, "auipc", "d,u", tempreg, reloc); + macro_build (NULL, "jalr", "d,s", destreg, tempreg); +} + +/* Warn if an expression is not a constant. */ + +static void +check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex) +{ + if (ex->X_op == O_big) + as_bad (_("unsupported large constant")); + else if (ex->X_op != O_constant) + as_bad (_("Instruction %s requires absolute expression"), + ip->insn_mo->name); + normalize_constant_expr (ex); +} + +/* Load an integer constant into a register. */ + +static void +load_const (int reg, expressionS *ep) +{ + int shift = RISCV_IMM_BITS; + expressionS upper = *ep, lower = *ep; + lower.X_add_number = (int32_t) ep->X_add_number << (32-shift) >> (32-shift); + upper.X_add_number -= lower.X_add_number; + + gas_assert (ep->X_op == O_constant); + + if (rv64 && !IS_SEXT_32BIT_NUM(ep->X_add_number)) + { + /* Reduce to a signed 32-bit constant using SLLI and ADDI, which + is not optimal but also not so bad. */ + while (((upper.X_add_number >> shift) & 1) == 0) + shift++; + + upper.X_add_number = (int64_t) upper.X_add_number >> shift; + load_const(reg, &upper); + + macro_build (NULL, "slli", "d,s,>", reg, reg, shift); + if (lower.X_add_number != 0) + macro_build (&lower, "addi", "d,s,j", reg, reg, BFD_RELOC_RISCV_LO12_I); + } + else + { + int hi_reg = 0; + + if (upper.X_add_number != 0) + { + macro_build (ep, "lui", "d,u", reg, BFD_RELOC_RISCV_HI20); + hi_reg = reg; + } + + if (lower.X_add_number != 0 || hi_reg == 0) + macro_build (ep, ADD32_INSN, "d,s,j", reg, hi_reg, + BFD_RELOC_RISCV_LO12_I); + } +} + +/* Expand RISC-V assembly macros into one or more instructions. */ +static void +macro (struct riscv_cl_insn *ip) +{ + int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD; + int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1; + int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2; + int mask = ip->insn_mo->mask; + + switch (mask) + { + case M_LI: + load_const (rd, &imm_expr); + break; + + case M_LA: + case M_LLA: + /* Load the address of a symbol into a register. */ + if (!IS_SEXT_32BIT_NUM (offset_expr.X_add_number)) + as_bad(_("offset too large")); + + if (offset_expr.X_op == O_constant) + load_const (rd, &offset_expr); + else if (riscv_opts.pic && mask == M_LA) /* Global PIC symbol */ + pcrel_load (rd, rd, &offset_expr, LOAD_ADDRESS_INSN, + BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + else /* Local PIC symbol, or any non-PIC symbol */ + pcrel_load (rd, rd, &offset_expr, "addi", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LA_TLS_GD: + pcrel_load (rd, rd, &offset_expr, "addi", + BFD_RELOC_RISCV_TLS_GD_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LA_TLS_IE: + pcrel_load (rd, rd, &offset_expr, LOAD_ADDRESS_INSN, + BFD_RELOC_RISCV_TLS_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LB: + pcrel_load (rd, rd, &offset_expr, "lb", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LBU: + pcrel_load (rd, rd, &offset_expr, "lbu", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LH: + pcrel_load (rd, rd, &offset_expr, "lh", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LHU: + pcrel_load (rd, rd, &offset_expr, "lhu", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LW: + pcrel_load (rd, rd, &offset_expr, "lw", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LWU: + pcrel_load (rd, rd, &offset_expr, "lwu", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_LD: + pcrel_load (rd, rd, &offset_expr, "ld", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_FLW: + pcrel_load (rd, rs1, &offset_expr, "flw", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_FLD: + pcrel_load (rd, rs1, &offset_expr, "fld", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I); + break; + + case M_SB: + pcrel_store (rs2, rs1, &offset_expr, "sb", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_SH: + pcrel_store (rs2, rs1, &offset_expr, "sh", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_SW: + pcrel_store (rs2, rs1, &offset_expr, "sw", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_SD: + pcrel_store (rs2, rs1, &offset_expr, "sd", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_FSW: + pcrel_store (rs2, rs1, &offset_expr, "fsw", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_FSD: + pcrel_store (rs2, rs1, &offset_expr, "fsd", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_VF: + pcrel_access (0, rs1, &offset_expr, "vf", "s,s,q", + BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S); + break; + + case M_CALL: + riscv_call (rd, rs1, &offset_expr, offset_reloc); + break; + + default: + as_bad (_("Macro %s not implemented"), ip->insn_mo->name); + break; + } +} + +static const struct percent_op_match percent_op_utype[] = +{ + {"%tprel_hi", BFD_RELOC_RISCV_TPREL_HI20}, + {"%pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20}, + {"%tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20}, + {"%tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20}, + {"%hi", BFD_RELOC_RISCV_HI20}, + {0, 0} +}; + +static const struct percent_op_match percent_op_itype[] = +{ + {"%lo", BFD_RELOC_RISCV_LO12_I}, + {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I}, + {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I}, + {0, 0} +}; + +static const struct percent_op_match percent_op_stype[] = +{ + {"%lo", BFD_RELOC_RISCV_LO12_S}, + {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S}, + {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S}, + {0, 0} +}; + +static const struct percent_op_match percent_op_rtype[] = +{ + {"%tprel_add", BFD_RELOC_RISCV_TPREL_ADD}, + {0, 0} +}; + +/* Return true if *STR points to a relocation operator. When returning true, + move *STR over the operator and store its relocation code in *RELOC. + Leave both *STR and *RELOC alone when returning false. */ + +static bfd_boolean +parse_relocation (char **str, bfd_reloc_code_real_type *reloc, + const struct percent_op_match *percent_op) +{ + for ( ; percent_op->str; percent_op++) + if (strncasecmp (*str, percent_op->str, strlen (percent_op->str)) == 0) + { + int len = strlen (percent_op->str); + + if (!ISSPACE ((*str)[len]) && (*str)[len] != '(') + continue; + + *str += strlen (percent_op->str); + *reloc = percent_op->reloc; + + /* Check whether the output BFD supports this relocation. + If not, issue an error and fall back on something safe. */ + if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc)) + { + as_bad ("relocation %s isn't supported by the current ABI", + percent_op->str); + *reloc = BFD_RELOC_UNUSED; + } + return TRUE; + } + return FALSE; +} + +static void +my_getExpression (expressionS *ep, char *str) +{ + char *save_in; + + save_in = input_line_pointer; + input_line_pointer = str; + expression (ep); + expr_end = input_line_pointer; + input_line_pointer = save_in; +} + +/* Parse string STR as a 16-bit relocatable operand. Store the + expression in *EP and the relocation, if any, in RELOC. + Return the number of relocation operators used (0 or 1). + + On exit, EXPR_END points to the first character after the expression. */ + +static size_t +my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc, + char *str, const struct percent_op_match *percent_op) +{ + size_t reloc_index; + int crux_depth, str_depth; + char *crux; + + /* Search for the start of the main expression. + End the loop with CRUX pointing to the start + of the main expression and with CRUX_DEPTH containing the number + of open brackets at that point. */ + reloc_index = -1; + str_depth = 0; + do + { + reloc_index++; + crux = str; + crux_depth = str_depth; + + /* Skip over whitespace and brackets, keeping count of the number + of brackets. */ + while (*str == ' ' || *str == '\t' || *str == '(') + if (*str++ == '(') + str_depth++; + } + while (*str == '%' + && reloc_index < 1 + && parse_relocation (&str, reloc, percent_op)); + + my_getExpression (ep, crux); + str = expr_end; + + /* Match every open bracket. */ + while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t')) + if (*str++ == ')') + crux_depth--; + + if (crux_depth > 0) + as_bad ("unclosed '('"); + + expr_end = str; + + return reloc_index; +} + +/* This routine assembles an instruction into its binary format. As a + side effect, it sets one of the global variables imm_reloc or + offset_reloc to the type of relocation to do if one of the operands + is an address expression. */ + +static void +riscv_ip (char *str, struct riscv_cl_insn *ip) +{ + char *s; + const char *args; + char c = 0; + struct riscv_opcode *insn; + char *argsStart; + unsigned int regno; + char save_c = 0; + int argnum; + const struct percent_op_match *p; + + insn_error = NULL; + + /* If the instruction contains a '.', we first try to match an instruction + including the '.'. Then we try again without the '.'. */ + insn = NULL; + for (s = str; *s != '\0' && !ISSPACE (*s); ++s) + continue; + + /* If we stopped on whitespace, then replace the whitespace with null for + the call to hash_find. Save the character we replaced just in case we + have to re-parse the instruction. */ + if (ISSPACE (*s)) + { + save_c = *s; + *s++ = '\0'; + } + + insn = (struct riscv_opcode *) hash_find (op_hash, str); + + /* If we didn't find the instruction in the opcode table, try again, but + this time with just the instruction up to, but not including the + first '.'. */ + if (insn == NULL) + { + /* Restore the character we overwrite above (if any). */ + if (save_c) + *(--s) = save_c; + + /* Scan up to the first '.' or whitespace. */ + for (s = str; + *s != '\0' && *s != '.' && !ISSPACE (*s); + ++s) + continue; + + /* If we did not find a '.', then we can quit now. */ + if (*s != '.') + { + insn_error = "unrecognized opcode"; + return; + } + + /* Lookup the instruction in the hash table. */ + *s++ = '\0'; + if ((insn = (struct riscv_opcode *) hash_find (op_hash, str)) == NULL) + { + insn_error = "unrecognized opcode"; + return; + } + } + + argsStart = s; + for (;;) + { + bfd_boolean ok = TRUE; + gas_assert (strcmp (insn->name, str) == 0); + + create_insn (ip, insn); + insn_error = NULL; + argnum = 1; + for (args = insn->args;; ++args) + { + s += strspn (s, " \t"); + switch (*args) + { + case '\0': /* end of args */ + if (*s == '\0') + return; + break; + /* Xcustom */ + case '^': + { + unsigned long max = OP_MASK_RD; + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + switch (*++args) + { + case 'j': + max = OP_MASK_CUSTOM_IMM; + INSERT_OPERAND (CUSTOM_IMM, *ip, imm_expr.X_add_number); + break; + case 'd': + INSERT_OPERAND (RD, *ip, imm_expr.X_add_number); + break; + case 's': + INSERT_OPERAND (RS1, *ip, imm_expr.X_add_number); + break; + case 't': + INSERT_OPERAND (RS2, *ip, imm_expr.X_add_number); + break; + } + imm_expr.X_op = O_absent; + s = expr_end; + if ((unsigned long) imm_expr.X_add_number > max) + as_warn ("Bad custom immediate (%lu), must be at most %lu", + (unsigned long)imm_expr.X_add_number, max); + continue; + } + + /* Xhwacha */ + case '#': + switch ( *++args ) + { + case 'g': + my_getExpression( &imm_expr, s ); + /* check_absolute_expr( ip, &imm_expr ); */ + if ((unsigned long) imm_expr.X_add_number > 32 ) + as_warn( _( "Improper ngpr amount (%lu)" ), + (unsigned long) imm_expr.X_add_number ); + INSERT_OPERAND( IMMNGPR, *ip, imm_expr.X_add_number ); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + case 'f': + my_getExpression( &imm_expr, s ); + /* check_absolute_expr( ip, &imm_expr ); */ + if ((unsigned long) imm_expr.X_add_number > 32 ) + as_warn( _( "Improper nfpr amount (%lu)" ), + (unsigned long) imm_expr.X_add_number ); + INSERT_OPERAND( IMMNFPR, *ip, imm_expr.X_add_number ); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + case 'n': + my_getExpression( &imm_expr, s ); + /* check_absolute_expr( ip, &imm_expr ); */ + if ((unsigned long) imm_expr.X_add_number > 8 ) + as_warn( _( "Improper nelm amount (%lu)" ), + (unsigned long) imm_expr.X_add_number ); + INSERT_OPERAND( IMMSEGNELM, *ip, imm_expr.X_add_number - 1 ); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + case 'd': + ok = reg_lookup( &s, RCLASS_VEC_GPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VRD, *ip, regno ); + continue; + case 's': + ok = reg_lookup( &s, RCLASS_VEC_GPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VRS, *ip, regno ); + continue; + case 't': + ok = reg_lookup( &s, RCLASS_VEC_GPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VRT, *ip, regno ); + continue; + case 'r': + ok = reg_lookup( &s, RCLASS_VEC_GPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VRR, *ip, regno ); + continue; + case 'D': + ok = reg_lookup( &s, RCLASS_VEC_FPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VFD, *ip, regno ); + continue; + case 'S': + ok = reg_lookup( &s, RCLASS_VEC_FPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VFS, *ip, regno ); + continue; + case 'T': + ok = reg_lookup( &s, RCLASS_VEC_FPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VFT, *ip, regno ); + continue; + case 'R': + ok = reg_lookup( &s, RCLASS_VEC_FPR, ®no ); + if ( !ok ) + as_bad( _( "Invalid vector register" ) ); + INSERT_OPERAND( VFR, *ip, regno ); + continue; + } + break; + + case ',': + ++argnum; + if (*s++ == *args) + continue; + s--; + break; + + case '(': + case ')': + case '[': + case ']': + if (*s++ == *args) + continue; + break; + + case '<': /* shift amount, 0 - 31 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > 31) + as_warn (_("Improper shift amount (%lu)"), + (unsigned long) imm_expr.X_add_number); + INSERT_OPERAND (SHAMTW, *ip, imm_expr.X_add_number); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '>': /* shift amount, 0 - (XLEN-1) */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > (rv64 ? 63 : 31)) + as_warn (_("Improper shift amount (%lu)"), + (unsigned long) imm_expr.X_add_number); + INSERT_OPERAND (SHAMT, *ip, imm_expr.X_add_number); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'Z': /* CSRRxI immediate */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > 31) + as_warn (_("Improper CSRxI immediate (%lu)"), + (unsigned long) imm_expr.X_add_number); + INSERT_OPERAND (RS1, *ip, imm_expr.X_add_number); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case 'E': /* Control register. */ + ok = reg_lookup (&s, RCLASS_CSR, ®no); + if (ok) + INSERT_OPERAND (CSR, *ip, regno); + else + { + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number > 0xfff) + as_warn(_("Improper CSR address (%lu)"), + (unsigned long) imm_expr.X_add_number); + INSERT_OPERAND (CSR, *ip, imm_expr.X_add_number); + imm_expr.X_op = O_absent; + s = expr_end; + } + continue; + + case 'm': /* rounding mode */ + if (arg_lookup (&s, riscv_rm, ARRAY_SIZE(riscv_rm), ®no)) + { + INSERT_OPERAND (RM, *ip, regno); + continue; + } + break; + + case 'P': + case 'Q': /* fence predecessor/successor */ + if (arg_lookup (&s, riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ), ®no)) + { + if (*args == 'P') + INSERT_OPERAND(PRED, *ip, regno); + else + INSERT_OPERAND(SUCC, *ip, regno); + continue; + } + break; + + case 'd': /* destination register */ + case 's': /* source register */ + case 't': /* target register */ + ok = reg_lookup (&s, RCLASS_GPR, ®no); + if (ok) + { + c = *args; + if (*s == ' ') + ++s; + + /* Now that we have assembled one operand, we use the args string + * to figure out where it goes in the instruction. */ + switch (c) + { + case 's': + INSERT_OPERAND (RS1, *ip, regno); + break; + case 'd': + INSERT_OPERAND (RD, *ip, regno); + break; + case 't': + INSERT_OPERAND (RS2, *ip, regno); + break; + } + continue; + } + break; + + case 'D': /* floating point rd */ + case 'S': /* floating point rs1 */ + case 'T': /* floating point rs2 */ + case 'U': /* floating point rs1 and rs2 */ + case 'R': /* floating point rs3 */ + if (reg_lookup (&s, RCLASS_FPR, ®no)) + { + c = *args; + if (*s == ' ') + ++s; + switch (c) + { + case 'D': + INSERT_OPERAND (RD, *ip, regno); + break; + case 'S': + INSERT_OPERAND (RS1, *ip, regno); + break; + case 'U': + INSERT_OPERAND (RS1, *ip, regno); + /* fallthru */ + case 'T': + INSERT_OPERAND (RS2, *ip, regno); + break; + case 'R': + INSERT_OPERAND (RS3, *ip, regno); + break; + } + continue; + } + + break; + + case 'I': + my_getExpression (&imm_expr, s); + if (imm_expr.X_op != O_big + && imm_expr.X_op != O_constant) + insn_error = _("absolute expression required"); + normalize_constant_expr (&imm_expr); + s = expr_end; + continue; + + case 'A': + my_getExpression (&offset_expr, s); + normalize_constant_expr (&offset_expr); + imm_reloc = BFD_RELOC_32; + s = expr_end; + continue; + + case 'j': /* sign-extended immediate */ + imm_reloc = BFD_RELOC_RISCV_LO12_I; + p = percent_op_itype; + goto alu_op; + case 'q': /* store displacement */ + p = percent_op_stype; + offset_reloc = BFD_RELOC_RISCV_LO12_S; + goto load_store; + case 'o': /* load displacement */ + p = percent_op_itype; + offset_reloc = BFD_RELOC_RISCV_LO12_I; + goto load_store; + case '0': /* AMO "displacement," which must be zero */ + p = percent_op_rtype; + offset_reloc = BFD_RELOC_UNUSED; +load_store: + /* Check whether there is only a single bracketed expression + left. If so, it must be the base register and the + constant must be zero. */ + offset_expr.X_op = O_constant; + offset_expr.X_add_number = 0; + if (*s == '(' && strchr (s + 1, '(') == 0) + continue; +alu_op: + /* If this value won't fit into a 16 bit offset, then go + find a macro that will generate the 32 bit offset + code pattern. */ + if (!my_getSmallExpression (&offset_expr, &offset_reloc, s, p)) + { + normalize_constant_expr (&offset_expr); + if (offset_expr.X_op != O_constant + || (*args == '0' && offset_expr.X_add_number != 0) + || offset_expr.X_add_number >= (signed)RISCV_IMM_REACH/2 + || offset_expr.X_add_number < -(signed)RISCV_IMM_REACH/2) + break; + } + + s = expr_end; + continue; + + case 'p': /* pc relative offset */ + offset_reloc = BFD_RELOC_12_PCREL; + my_getExpression (&offset_expr, s); + s = expr_end; + continue; + + case 'u': /* upper 20 bits */ + p = percent_op_utype; + if (!my_getSmallExpression (&imm_expr, &imm_reloc, s, p) + && imm_expr.X_op == O_constant) + { + if (imm_expr.X_add_number < 0 + || imm_expr.X_add_number >= (signed)RISCV_BIGIMM_REACH) + as_bad (_("lui expression not in range 0..1048575")); + + imm_reloc = BFD_RELOC_RISCV_HI20; + imm_expr.X_add_number <<= RISCV_IMM_BITS; + } + s = expr_end; + continue; + + case 'a': /* 26 bit address */ + my_getExpression (&offset_expr, s); + s = expr_end; + offset_reloc = BFD_RELOC_RISCV_JMP; + continue; + + case 'c': + my_getExpression (&offset_expr, s); + s = expr_end; + offset_reloc = BFD_RELOC_RISCV_CALL; + if (*s == '@') + offset_reloc = BFD_RELOC_RISCV_CALL_PLT, s++; + continue; + + default: + as_bad (_("bad char = '%c'\n"), *args); + internalError (); + } + break; + } + /* Args don't match. */ + if (insn + 1 < &riscv_opcodes[NUMOPCODES] && + !strcmp (insn->name, insn[1].name)) + { + ++insn; + s = argsStart; + insn_error = _("illegal operands"); + continue; + } + if (save_c) + *(--argsStart) = save_c; + insn_error = _("illegal operands"); + return; + } +} + +void +md_assemble (char *str) +{ + struct riscv_cl_insn insn; + + imm_expr.X_op = O_absent; + offset_expr.X_op = O_absent; + imm_reloc = BFD_RELOC_UNUSED; + offset_reloc = BFD_RELOC_UNUSED; + + riscv_ip (str, &insn); + + if (insn_error) + { + as_bad ("%s `%s'", insn_error, str); + return; + } + + if (insn.insn_mo->pinfo == INSN_MACRO) + macro (&insn); + else + { + if (imm_expr.X_op != O_absent) + append_insn (&insn, &imm_expr, imm_reloc); + else if (offset_expr.X_op != O_absent) + append_insn (&insn, &offset_expr, offset_reloc); + else + append_insn (&insn, NULL, BFD_RELOC_UNUSED); + } +} + +char * +md_atof (int type, char *litP, int *sizeP) +{ + return ieee_md_atof (type, litP, sizeP, TARGET_BYTES_BIG_ENDIAN); +} + +void +md_number_to_chars (char *buf, valueT val, int n) +{ + number_to_chars_littleendian (buf, val, n); +} + +const char *md_shortopts = "O::g::G:"; + +enum options + { + OPTION_M32 = OPTION_MD_BASE, + OPTION_M64, + OPTION_MARCH, + OPTION_PIC, + OPTION_NO_PIC, + OPTION_MRVC, + OPTION_MNO_RVC, + OPTION_END_OF_ENUM + }; + +struct option md_longopts[] = +{ + {"m32", no_argument, NULL, OPTION_M32}, + {"m64", no_argument, NULL, OPTION_M64}, + {"march", required_argument, NULL, OPTION_MARCH}, + {"fPIC", no_argument, NULL, OPTION_PIC}, + {"fpic", no_argument, NULL, OPTION_PIC}, + {"fno-pic", no_argument, NULL, OPTION_NO_PIC}, + {"mrvc", no_argument, NULL, OPTION_MRVC}, + {"mno-rvc", no_argument, NULL, OPTION_MNO_RVC}, + + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof (md_longopts); + +int +md_parse_option (int c, char *arg) +{ + switch (c) + { + case OPTION_MRVC: + riscv_opts.rvc = 1; + break; + + case OPTION_MNO_RVC: + riscv_opts.rvc = 0; + break; + + case OPTION_M32: + rv64 = FALSE; + break; + + case OPTION_M64: + rv64 = TRUE; + break; + + case OPTION_MARCH: + riscv_set_arch(arg); + + case OPTION_NO_PIC: + riscv_opts.pic = FALSE; + break; + + case OPTION_PIC: + riscv_opts.pic = TRUE; + break; + + default: + return 0; + } + + return 1; +} + +void +riscv_after_parse_args (void) +{ + if (riscv_subsets == NULL) + riscv_set_arch("RVIMAFDXcustom"); +} + +void +riscv_init_after_args (void) +{ + /* initialize opcodes */ + bfd_riscv_num_opcodes = bfd_riscv_num_builtin_opcodes; + riscv_opcodes = (struct riscv_opcode *) riscv_builtin_opcodes; +} + +long +md_pcrel_from (fixS *fixP) +{ + return fixP->fx_where + fixP->fx_frag->fr_address; +} + +/* Apply a fixup to the object file. */ + +void +md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) +{ + bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where); + + /* Remember value for tc_gen_reloc. */ + fixP->fx_addnumber = *valP; + + switch (fixP->fx_r_type) + { + case BFD_RELOC_RISCV_TLS_GOT_HI20: + case BFD_RELOC_RISCV_TLS_GD_HI20: + case BFD_RELOC_RISCV_TLS_DTPREL32: + case BFD_RELOC_RISCV_TLS_DTPREL64: + case BFD_RELOC_RISCV_TPREL_HI20: + case BFD_RELOC_RISCV_TPREL_LO12_I: + case BFD_RELOC_RISCV_TPREL_LO12_S: + case BFD_RELOC_RISCV_TPREL_ADD: + S_SET_THREAD_LOCAL (fixP->fx_addsy); + /* fall through */ + + case BFD_RELOC_RISCV_GOT_HI20: + case BFD_RELOC_RISCV_PCREL_HI20: + case BFD_RELOC_RISCV_HI20: + case BFD_RELOC_RISCV_LO12_I: + case BFD_RELOC_RISCV_LO12_S: + case BFD_RELOC_RISCV_ADD8: + case BFD_RELOC_RISCV_ADD16: + case BFD_RELOC_RISCV_ADD32: + case BFD_RELOC_RISCV_ADD64: + case BFD_RELOC_RISCV_SUB8: + case BFD_RELOC_RISCV_SUB16: + case BFD_RELOC_RISCV_SUB32: + case BFD_RELOC_RISCV_SUB64: + gas_assert (fixP->fx_addsy != NULL); + /* Nothing needed to do. The value comes from the reloc entry. */ + break; + + case BFD_RELOC_64: + case BFD_RELOC_32: + case BFD_RELOC_16: + case BFD_RELOC_8: + if (fixP->fx_addsy && fixP->fx_subsy) + { + fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); + fixP->fx_next->fx_addsy = fixP->fx_subsy; + fixP->fx_next->fx_subsy = NULL; + fixP->fx_next->fx_offset = 0; + fixP->fx_subsy = NULL; + + if (fixP->fx_r_type == BFD_RELOC_64) + fixP->fx_r_type = BFD_RELOC_RISCV_ADD64, + fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB64; + else if (fixP->fx_r_type == BFD_RELOC_32) + fixP->fx_r_type = BFD_RELOC_RISCV_ADD32, + fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32; + else if (fixP->fx_r_type == BFD_RELOC_16) + fixP->fx_r_type = BFD_RELOC_RISCV_ADD16, + fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16; + else + fixP->fx_r_type = BFD_RELOC_RISCV_ADD8, + fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8; + } + /* fall through */ + + case BFD_RELOC_RVA: + /* If we are deleting this reloc entry, we must fill in the + value now. This can happen if we have a .word which is not + resolved when it appears but is later defined. */ + if (fixP->fx_addsy == NULL) + { + gas_assert (fixP->fx_size <= sizeof (valueT)); + md_number_to_chars ((char *) buf, *valP, fixP->fx_size); + fixP->fx_done = 1; + } + break; + + case BFD_RELOC_RISCV_JMP: + if (fixP->fx_addsy) + { + /* Fill in a tentative value to improve objdump readability. */ + bfd_vma delta = ENCODE_UJTYPE_IMM (S_GET_VALUE (fixP->fx_addsy) + *valP); + bfd_putl32 (bfd_getl32 (buf) | delta, buf); + } + break; + + case BFD_RELOC_12_PCREL: + if (fixP->fx_addsy) + { + /* Fill in a tentative value to improve objdump readability. */ + bfd_vma delta = ENCODE_SBTYPE_IMM (S_GET_VALUE (fixP->fx_addsy) + *valP); + bfd_putl32 (bfd_getl32 (buf) | delta, buf); + } + break; + + case BFD_RELOC_RISCV_PCREL_LO12_S: + case BFD_RELOC_RISCV_PCREL_LO12_I: + case BFD_RELOC_RISCV_CALL: + case BFD_RELOC_RISCV_CALL_PLT: + case BFD_RELOC_RISCV_ALIGN: + break; + + default: + /* We ignore generic BFD relocations we don't know about. */ + if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL) + internalError (); + } +} + +/* This structure is used to hold a stack of .set values. */ + +struct riscv_option_stack +{ + struct riscv_option_stack *next; + struct riscv_set_options options; +}; + +static struct riscv_option_stack *riscv_opts_stack; + +/* Handle the .set pseudo-op. */ + +static void +s_riscv_option (int x ATTRIBUTE_UNUSED) +{ + char *name = input_line_pointer, ch; + + while (!is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + ch = *input_line_pointer; + *input_line_pointer = '\0'; + + if (strcmp (name, "rvc") == 0) + riscv_opts.rvc = 1; + else if (strcmp (name, "norvc") == 0) + riscv_opts.rvc = 0; + else if (strcmp (name, "push") == 0) + { + struct riscv_option_stack *s; + + s = (struct riscv_option_stack *) xmalloc (sizeof *s); + s->next = riscv_opts_stack; + s->options = riscv_opts; + riscv_opts_stack = s; + } + else if (strcmp (name, "pop") == 0) + { + struct riscv_option_stack *s; + + s = riscv_opts_stack; + if (s == NULL) + as_bad (_(".option pop with no .option push")); + else + { + riscv_opts = s->options; + riscv_opts_stack = s->next; + free (s); + } + } + else + { + as_warn (_("Unrecognized .option directive: %s\n"), name); + } + *input_line_pointer = ch; + demand_empty_rest_of_line (); +} + +/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate + a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for + use in DWARF debug information. */ + +static void +s_dtprel (int bytes) +{ + expressionS ex; + char *p; + + expression (&ex); + + if (ex.X_op != O_symbol) + { + as_bad (_("Unsupported use of %s"), (bytes == 8 + ? ".dtpreldword" + : ".dtprelword")); + ignore_rest_of_line (); + } + + p = frag_more (bytes); + md_number_to_chars (p, 0, bytes); + fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, + (bytes == 8 + ? BFD_RELOC_RISCV_TLS_DTPREL64 + : BFD_RELOC_RISCV_TLS_DTPREL32)); + + demand_empty_rest_of_line (); +} + +/* Handle the .bss pseudo-op. */ + +static void +s_bss (int ignore ATTRIBUTE_UNUSED) +{ + subseg_set (bss_section, 0); + demand_empty_rest_of_line (); +} + +/* Align to a given power of two. */ + +static void +s_align (int x ATTRIBUTE_UNUSED) +{ + int alignment, fill_value = 0, fill_value_specified = 0; + + alignment = get_absolute_expression (); + if (alignment < 0 || alignment > 31) + as_bad (_("unsatisfiable alignment: %d"), alignment); + + if (*input_line_pointer == ',') + { + ++input_line_pointer; + fill_value = get_absolute_expression (); + fill_value_specified = 1; + } + + if (!fill_value_specified && subseg_text_p (now_seg) && alignment > 2) + { + /* Emit the worst-case NOP string. The linker will delete any + unnecessary NOPs. This allows us to support code alignment + in spite of linker relaxations. */ + bfd_vma i, worst_case_nop_bytes = (1L << alignment) - 4; + char *nops = frag_more (worst_case_nop_bytes); + for (i = 0; i < worst_case_nop_bytes; i += 4) + md_number_to_chars (nops + i, RISCV_NOP, 4); + + expressionS ex; + ex.X_op = O_constant; + ex.X_add_number = worst_case_nop_bytes; + + fix_new_exp (frag_now, nops - frag_now->fr_literal, 0, + &ex, TRUE, BFD_RELOC_RISCV_ALIGN); + } + else if (alignment) + frag_align (alignment, fill_value, 0); + + record_alignment (now_seg, alignment); + + demand_empty_rest_of_line (); +} + +int +md_estimate_size_before_relax (fragS *fragp, asection *segtype) +{ + return (fragp->fr_var = relaxed_branch_length (fragp, segtype, FALSE)); +} + +/* Translate internal representation of relocation info to BFD target + format. */ + +arelent * +tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) +{ + arelent *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_pcrel) + /* At this point, fx_addnumber is "symbol offset - pcrel address". + Relocations want only the symbol offset. */ + reloc->addend = fixp->fx_addnumber + reloc->address; + else + reloc->addend = fixp->fx_addnumber; + + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); + if (reloc->howto == NULL) + { + if ((fixp->fx_r_type == BFD_RELOC_16 || fixp->fx_r_type == BFD_RELOC_8) + && fixp->fx_addsy != NULL && fixp->fx_subsy != NULL) + { + /* We don't have R_RISCV_8/16, but for this special case, + we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */ + return reloc; + } + + as_bad_where (fixp->fx_file, fixp->fx_line, + _("cannot represent %s relocation in object file"), + bfd_get_reloc_code_name (fixp->fx_r_type)); + return NULL; + } + + return reloc; +} + +int +riscv_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED) +{ + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + offsetT old_var = fragp->fr_var; + fragp->fr_var = relaxed_branch_length (fragp, sec, TRUE); + return fragp->fr_var - old_var; + } + + return 0; +} + +/* Convert a machine dependent frag. */ + +static void +md_convert_frag_branch (fragS *fragp) +{ + bfd_byte *buf; + insn_t insn; + expressionS exp; + fixS *fixp; + + buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix; + + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + if (RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + { + gas_assert (fragp->fr_var == 8); + /* We could relax JAL to AUIPC/JALR, but we don't do this yet. */ + gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype)); + + /* Invert the branch condition. Branch over the jump. */ + insn = bfd_getl32 (buf); + insn ^= MATCH_BEQ ^ MATCH_BNE; + insn |= ENCODE_SBTYPE_IMM (8); + md_number_to_chars ((char *) buf, insn, 4); + buf += 4; + + /* Jump to the target. */ + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, FALSE, BFD_RELOC_RISCV_JMP); + md_number_to_chars ((char *) buf, MATCH_JAL, 4); + buf += 4; + } + else + { + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, FALSE, BFD_RELOC_12_PCREL); + buf += 4; + } + + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + fixp->fx_pcrel = 1; + + gas_assert (buf == (bfd_byte *)fragp->fr_literal + + fragp->fr_fix + fragp->fr_var); + + fragp->fr_fix += fragp->fr_var; +} + +/* Relax a machine dependent frag. This returns the amount by which + the current size of the frag should change. */ + +void +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED, + fragS *fragp) +{ + gas_assert (RELAX_BRANCH_P (fragp->fr_subtype)); + md_convert_frag_branch (fragp); +} + +void +md_show_usage (FILE *stream) +{ + fprintf (stream, _("\ +RISC-V options:\n\ + -m32 assemble RV32 code\n\ + -m64 assemble RV64 code (default)\n\ + -fpic generate position-independent code\n\ + -fno-pic don't generate position-independent code (default)\n\ +")); +} + +/* Standard calling conventions leave the CFA at SP on entry. */ +void +riscv_cfi_frame_initial_instructions (void) +{ + cfi_add_CFA_def_cfa_register (X_SP); +} + +int +tc_riscv_regname_to_dw2regnum (char *regname) +{ + int reg; + + if ((reg = reg_lookup_internal (regname, RCLASS_GPR)) >= 0) + return reg; + + if ((reg = reg_lookup_internal (regname, RCLASS_FPR)) >= 0) + return reg + 32; + + as_bad (_("unknown register `%s'"), regname); + return -1; +} + +void +riscv_elf_final_processing (void) +{ + struct riscv_subset* s; + + unsigned int Xlen = 0; + for (s = riscv_subsets; s != NULL; s = s->next) + if (s->name[0] == 'X') + Xlen += strlen(s->name); + + char extension[Xlen]; + extension[0] = 0; + for (s = riscv_subsets; s != NULL; s = s->next) + if (s->name[0] == 'X') + strcat(extension, s->name); + + EF_SET_RISCV_EXT(elf_elfheader (stdoutput)->e_flags, + riscv_elf_name_to_flag (extension)); +} + +/* Pseudo-op table. */ + +static const pseudo_typeS riscv_pseudo_table[] = +{ + /* RISC-V-specific pseudo-ops. */ + {"option", s_riscv_option, 0}, + {"half", cons, 2}, + {"word", cons, 4}, + {"dword", cons, 8}, + {"dtprelword", s_dtprel, 4}, + {"dtpreldword", s_dtprel, 8}, + {"bss", s_bss, 0}, + {"align", s_align, 0}, + + /* leb128 doesn't work with relaxation; disallow it */ + {"uleb128", s_err, 0}, + {"sleb128", s_err, 0}, + + { NULL, NULL, 0 }, +}; + +void +riscv_pop_insert (void) +{ + extern void pop_insert (const pseudo_typeS *); + + pop_insert (riscv_pseudo_table); +} diff -rNU3 dist.orig/gas/config/tc-riscv.h dist/gas/config/tc-riscv.h --- dist.orig/gas/config/tc-riscv.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/tc-riscv.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,102 @@ +/* tc-riscv.h -- header file for tc-riscv.c. + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + This file is part of GAS. + + 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. */ + +#ifndef TC_RISCV +#define TC_RISCV + +#include "opcode/riscv.h" + +struct frag; +struct expressionS; + +#define TARGET_BYTES_BIG_ENDIAN 0 + +#define TARGET_ARCH bfd_arch_riscv + +#define WORKING_DOT_WORD 1 +#define OLD_FLOAT_READS +#define REPEAT_CONS_EXPRESSIONS +#define LOCAL_LABELS_FB 1 +#define FAKE_LABEL_NAME ".L0 " + +#define md_relax_frag(segment, fragp, stretch) \ + riscv_relax_frag(segment, fragp, stretch) +extern int riscv_relax_frag (asection *, struct frag *, long); + +#define md_section_align(seg,size) (size) +#define md_undefined_symbol(name) (0) +#define md_operand(x) + +#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2) + +#define TC_SYMFIELD_TYPE int + +/* The ISA of the target may change based on command-line arguments. */ +#define TARGET_FORMAT riscv_target_format() +extern const char *riscv_target_format (void); + +#define md_after_parse_args() riscv_after_parse_args() +extern void riscv_after_parse_args (void); + +#define tc_init_after_args() riscv_init_after_args() +extern void riscv_init_after_args (void); + +#define md_parse_long_option(arg) riscv_parse_long_option (arg) +extern int riscv_parse_long_option (const char *); + +/* Let the linker resolve all the relocs due to relaxation. */ +#define tc_fix_adjustable(fixp) 0 +#define md_allow_local_subtract(l,r,s) 0 + +/* Values passed to md_apply_fix don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* Global syms must not be resolved, to support ELF shared libraries. */ +#define EXTERN_FORCE_RELOC \ + (OUTPUT_FLAVOR == bfd_target_elf_flavour) + +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) ((SEG)->flags & SEC_CODE) +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 +#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1 +#define TC_FORCE_RELOCATION_LOCAL(FIX) 1 +#define DIFF_EXPR_OK 1 + +extern void riscv_pop_insert (void); +#define md_pop_insert() riscv_pop_insert() + +#define TARGET_USE_CFIPOP 1 + +#define tc_cfi_frame_initial_instructions riscv_cfi_frame_initial_instructions +extern void riscv_cfi_frame_initial_instructions (void); + +#define tc_regname_to_dw2regnum tc_riscv_regname_to_dw2regnum +extern int tc_riscv_regname_to_dw2regnum (char *regname); + +extern bfd_boolean rv64; +#define DWARF2_DEFAULT_RETURN_COLUMN X_RA +#define DWARF2_CIE_DATA_ALIGNMENT (rv64 ? 8 : 4) + +#define elf_tc_final_processing riscv_elf_final_processing +extern void riscv_elf_final_processing (void); + +#endif /* TC_RISCV */ diff -rNU3 dist.orig/gas/config/tc-vax.c dist/gas/config/tc-vax.c --- dist.orig/gas/config/tc-vax.c 2010-06-28 16:06:57.000000000 +0200 +++ dist/gas/config/tc-vax.c 2015-10-18 13:11:13.000000000 +0200 @@ -24,6 +24,7 @@ #include "vax-inst.h" #include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */ +#include "dw2gencfi.h" #include "subsegs.h" #include "safe-ctype.h" @@ -392,6 +393,9 @@ && (PLT_symbol == NULL || fragP->fr_symbol != PLT_symbol) && fragP->fr_symbol != NULL && flag_want_pic +#ifdef OBJ_ELF + && ELF_ST_VISIBILITY (S_GET_OTHER (fragP->fr_symbol)) != STV_HIDDEN +#endif && (!S_IS_DEFINED (fragP->fr_symbol) || S_IS_WEAK (fragP->fr_symbol) || S_IS_EXTERNAL (fragP->fr_symbol))) @@ -1073,6 +1077,154 @@ return retval; } +#ifdef OBJ_AOUT +#ifndef BFD_ASSEMBLER +void +tc_aout_fix_to_chars (where, fixP, segment_address_in_file) + char *where; + fixS *fixP; + relax_addressT segment_address_in_file; +{ + /* + * In: length of relocation (or of address) in chars: 1, 2 or 4. + * Out: GNU LD relocation length code: 0, 1, or 2. + */ + + static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2}; + int r_symbolnum; + int r_flags; + + know (fixP->fx_addsy != NULL); + + md_number_to_chars (where, + fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + 4); + + r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) + ? S_GET_TYPE (fixP->fx_addsy) + : fixP->fx_addsy->sy_number); + r_flags = (fixP->fx_pcrel ? 1 : 0) + | (!S_IS_DEFINED (fixP->fx_addsy) ? 8 : 0) /* extern */ + | ((nbytes_r_length[fixP->fx_size] & 3) << 1); + +#if 0 + r_flags |= ((!S_IS_DEFINED(fixP->fx_addsy) + && fixP->fx_pcrel + && fixP->fx_addsy != GOT_symbol + && fixP->fx_addsy != PLT_symbol + && flags_want_pic) ? 0x10 : 0); +#endif + + switch (fixP->fx_r_type) { + case NO_RELOC: + break; + case NO_RELOC2: + if (r_flags & 8) + r_flags |= 0x80; /* setting the copy bit */ + /* says we can convert */ + /* to gotslot if needed */ + break; + case RELOC_32: + if (flag_want_pic && S_IS_EXTERNAL(fixP->fx_addsy)) { + r_symbolnum = fixP->fx_addsy->sy_number; + r_flags |= 8; /* set extern bit */ + } + break; + case RELOC_JMP_SLOT: + if (flag_want_pic) { + r_flags |= 0x20; /* set jmptable */ + r_flags &= ~0x08; /* clear extern bit */ + } + break; + case RELOC_JMP_TBL: + if (flag_want_pic) { + r_flags |= 0x20; /* set jmptable */ + r_flags |= 0x08; /* set extern bit */ + } + break; + case RELOC_GLOB_DAT: + if (flag_want_pic) { + r_flags |= 0x10; /* set baserel bit */ + r_symbolnum = fixP->fx_addsy->sy_number; + if (S_IS_EXTERNAL(fixP->fx_addsy)) + r_flags |= 8; /* set extern bit */ + } + break; + } + + where[4] = (r_symbolnum >> 0) & 0xff; + where[5] = (r_symbolnum >> 8) & 0xff; + where[6] = (r_symbolnum >> 16) & 0xff; + where[7] = r_flags; +} +#endif /* !BFD_ASSEMBLER */ +#endif /* OBJ_AOUT */ + +/* + * BUGS, GRIPES, APOLOGIA, etc. + * + * The opcode table 'votstrs' needs to be sorted on opcode frequency. + * That is, AFTER we hash it with hash_...(), we want most-used opcodes + * to come out of the hash table faster. + * + * I am sorry to inflict yet another VAX assembler on the world, but + * RMS says we must do everything from scratch, to prevent pin-heads + * restricting this software. + */ + +/* + * This is a vaguely modular set of routines in C to parse VAX + * assembly code using DEC mnemonics. It is NOT un*x specific. + * + * The idea here is that the assembler has taken care of all: + * labels + * macros + * listing + * pseudo-ops + * line continuation + * comments + * condensing any whitespace down to exactly one space + * and all we have to do is parse 1 line into a vax instruction + * partially formed. We will accept a line, and deliver: + * an error message (hopefully empty) + * a skeleton VAX instruction (tree structure) + * textual pointers to all the operand expressions + * a warning message that notes a silly operand (hopefully empty) + */ + +/* + * E D I T H I S T O R Y + * + * 17may86 Dean Elsner. Bug if line ends immediately after opcode. + * 30apr86 Dean Elsner. New vip_op() uses arg block so change call. + * 6jan86 Dean Elsner. Crock vip_begin() to call vip_op_defaults(). + * 2jan86 Dean Elsner. Invent synthetic opcodes. + * Widen vax_opcodeT to 32 bits. Use a bit for VIT_OPCODE_SYNTHETIC, + * which means this is not a real opcode, it is like a macro; it will + * be relax()ed into 1 or more instructions. + * Use another bit for VIT_OPCODE_SPECIAL if the op-code is not optimised + * like a regular branch instruction. Option added to vip_begin(): + * exclude synthetic opcodes. Invent synthetic_votstrs[]. + * 31dec85 Dean Elsner. Invent vit_opcode_nbytes. + * Also make vit_opcode into a char[]. We now have n-byte vax opcodes, + * so caller's don't have to know the difference between a 1-byte & a + * 2-byte op-code. Still need vax_opcodeT concept, so we know how + * big an object must be to hold an op.code. + * 30dec85 Dean Elsner. Widen typedef vax_opcodeT in "vax-inst.h" + * because vax opcodes may be 16 bits. Our crufty C compiler was + * happily initialising 8-bit vot_codes with 16-bit numbers! + * (Wouldn't the 'phone company like to compress data so easily!) + * 29dec85 Dean Elsner. New static table vax_operand_width_size[]. + * Invented so we know hw many bytes a "I^#42" needs in its immediate + * operand. Revised struct vop in "vax-inst.h": explicitly include + * byte length of each operand, and it's letter-code datum type. + * 17nov85 Dean Elsner. Name Change. + * Due to ar(1) truncating names, we learned the hard way that + * "vax-inst-parse.c" -> "vax-inst-parse." dropping the "o" off + * the archived object name. SO... we shortened the name of this + * source file, and changed the makefile. + */ + /* Parse a vax operand in DEC assembler notation. For speed, expect a string of whitespace to be reduced to a single ' '. This is the case for GNU AS, and is easy for other DEC-compatible @@ -3150,7 +3302,7 @@ if (flag_want_pic && operandP->vop_mode == 8 && this_add_symbol != NULL) { - as_warn (_("Symbol %s used as immediate operand in PIC mode."), + as_warn (_("Symbol '%s' used as immediate operand in PIC mode."), S_GET_NAME (this_add_symbol)); } #endif @@ -3226,7 +3378,15 @@ length = 4; } } +#ifdef OBJ_ELF + if (flag_want_pic && this_add_symbol != NULL) + { + as_warn (_("Symbol '%s' used as displacement in PIC mode."), + S_GET_NAME (this_add_symbol)); + } +#endif p = frag_more (1 + length); + know (operandP->vop_reg != 0xf); know (operandP->vop_reg >= 0); p[0] = operandP->vop_reg | ((at | "?\12\14?\16"[length]) << 4); @@ -3411,3 +3571,38 @@ { return vax_md_atof (type, litP, sizeP); } + +void +vax_cfi_frame_initial_instructions (void) +{ + cfi_add_CFA_def_cfa (14, 0); +} + +int +tc_vax_regname_to_dw2regnum (char *regname) +{ + unsigned int i; + static const struct { char *name; int dw2regnum; } regnames[] = + { + { "r0", 0 }, { "r1", 1 }, { "r2", 2 }, { "r3", 3 }, + { "r4", 4 }, { "r5", 5 }, { "r6", 6 }, { "r7", 7 }, + { "r8", 8 }, { "r9", 9 }, { "r10", 10 }, { "r11", 11 }, + { "ap", 12 }, { "fp", 13 }, { "sp", 14 }, { "pc", 15 }, + { "psw", 16 }, + }; + + for (i = 0; i < ARRAY_SIZE (regnames); ++i) + if (strcmp (regnames[i].name, regname) == 0) + return regnames[i].dw2regnum; + + return -1; +} + +void +vax_cfi_emit_pcrel_expr (expressionS *expP, unsigned int nbytes) +{ + vax_cons_special_reloc = "pcrel"; + expP->X_add_number += nbytes; + emit_expr (expP, nbytes); + vax_cons_special_reloc = NULL; +} diff -rNU3 dist.orig/gas/config/tc-vax.h dist/gas/config/tc-vax.h --- dist.orig/gas/config/tc-vax.h 2007-07-03 13:01:05.000000000 +0200 +++ dist/gas/config/tc-vax.h 2015-10-18 13:11:13.000000000 +0200 @@ -71,9 +71,17 @@ == S_GET_SEGMENT ((FIX)->fx_addsy))) \ || S_IS_LOCAL ((FIX)->fx_addsy))) -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ +#define TARGET_USE_CFIPOP 1 + +#define tc_cfi_frame_initial_instructions vax_cfi_frame_initial_instructions +extern void vax_cfi_frame_initial_instructions (void); + +#define tc_regname_to_dw2regnum tc_vax_regname_to_dw2regnum +extern int tc_vax_regname_to_dw2regnum (char *); + +#define tc_cfi_emit_pcrel_expr vax_cfi_emit_pcrel_expr +extern void vax_cfi_emit_pcrel_expr (expressionS *, unsigned int); + +#define DWARF2_LINE_MIN_INSN_LENGTH 1 +#define DWARF2_DEFAULT_RETURN_COLUMN 15 +#define DWARF2_CIE_DATA_ALIGNMENT -4 diff -rNU3 dist.orig/gas/config/te-armnbsd.h dist/gas/config/te-armnbsd.h --- dist.orig/gas/config/te-armnbsd.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/te-armnbsd.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,22 @@ +/* Copyright 2004, 2005, 2007, 2009 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. */ + +#include "te-nbsd.h" + +#define CPU_DEFAULT ARM_ARCH_V4 diff -rNU3 dist.orig/gas/config/te-armnbsdeabi.h dist/gas/config/te-armnbsdeabi.h --- dist.orig/gas/config/te-armnbsdeabi.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/te-armnbsdeabi.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,25 @@ +/* Copyright 2004, 2005, 2007, 2009 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. */ + +#include "te-nbsd.h" + +/* The EABI requires the use of VFP. */ +#define CPU_DEFAULT ARM_ARCH_V5TEJ +#define FPU_DEFAULT FPU_ARCH_VFP +#define EABI_DEFAULT EF_ARM_EABI_VER5 diff -rNU3 dist.orig/gas/config/te-armnbsdeabihf.h dist/gas/config/te-armnbsdeabihf.h --- dist.orig/gas/config/te-armnbsdeabihf.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/gas/config/te-armnbsdeabihf.h 2015-10-18 13:11:13.000000000 +0200 @@ -0,0 +1,25 @@ +/* Copyright 2004, 2005, 2007, 2009 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. */ + +#include "te-nbsd.h" + +/* The EABI requires the use of VFP. */ +#define CPU_DEFAULT ARM_ARCH_V5TEJ +#define FPU_DEFAULT FPU_ARCH_VFP_V2 +#define EABI_DEFAULT EF_ARM_EABI_VER5 diff -rNU3 dist.orig/gas/config/vax-inst.h dist/gas/config/vax-inst.h --- dist.orig/gas/config/vax-inst.h 2009-09-02 09:24:21.000000000 +0200 +++ dist/gas/config/vax-inst.h 2015-10-18 13:11:13.000000000 +0200 @@ -66,6 +66,8 @@ #define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */ #define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/ /* Needs VAX_PC_RELATIVE_MODE byte after it*/ +#define VAX_CALLS (0xFB) /* Call with arg list on stack */ +#define VAX_CALLG (0xFA) /* Call with arg list in memory */ struct vit /* vax instruction tree */ { diff -rNU3 dist.orig/gas/configure dist/gas/configure --- dist.orig/gas/configure 2012-06-18 06:43:06.000000000 +0200 +++ dist/gas/configure 2015-10-18 13:11:13.000000000 +0200 @@ -12146,7 +12146,7 @@ fi ;; - epiphany | fr30 | ip2k | iq2000 | lm32 | m32r | openrisc) + epiphany | fr30 | ip2k | iq2000 | lm32 | m32r | or1k | or1knd) using_cgen=yes ;; @@ -12340,6 +12340,8 @@ cgen_cpu_prefix="" if test $using_cgen = yes ; then case ${target_cpu} in + or1knd) + cgen_cpu_prefix=or1k ;; *) cgen_cpu_prefix=${target_cpu} ;; esac diff -rNU3 dist.orig/gas/configure.in dist/gas/configure.in --- dist.orig/gas/configure.in 2012-11-05 17:27:44.000000000 +0100 +++ dist/gas/configure.in 2015-10-18 13:11:13.000000000 +0200 @@ -314,7 +314,7 @@ fi ;; - epiphany | fr30 | ip2k | iq2000 | lm32 | m32r | openrisc) + epiphany | fr30 | ip2k | iq2000 | lm32 | m32r | or1k | or1knd) using_cgen=yes ;; @@ -504,6 +504,8 @@ cgen_cpu_prefix="" if test $using_cgen = yes ; then case ${target_cpu} in + or1knd) + cgen_cpu_prefix=or1k ;; *) cgen_cpu_prefix=${target_cpu} ;; esac AC_SUBST(cgen_cpu_prefix) diff -rNU3 dist.orig/gas/configure.tgt dist/gas/configure.tgt --- dist.orig/gas/configure.tgt 2012-09-04 14:53:45.000000000 +0200 +++ dist/gas/configure.tgt 2015-10-18 13:11:13.000000000 +0200 @@ -51,7 +51,7 @@ m32c) cpu_type=m32c endian=little ;; m32r) cpu_type=m32r endian=big ;; m32rle) cpu_type=m32r endian=little ;; - m5200) cpu_type=m68k ;; + m5200|m5407) cpu_type=m68k ;; m68008) cpu_type=m68k ;; m680[012346]0) cpu_type=m68k ;; m6811|m6812|m68hc12) cpu_type=m68hc11 ;; @@ -61,11 +61,13 @@ mips*el) cpu_type=mips endian=little ;; mips*) cpu_type=mips endian=big ;; mt) cpu_type=mt endian=big ;; - or32*) cpu_type=or32 endian=big ;; + or1k*) cpu_type=or1k endian=big ;; pjl*) cpu_type=pj endian=little ;; pj*) cpu_type=pj endian=big ;; powerpc*le*) cpu_type=ppc endian=little ;; powerpc*) cpu_type=ppc endian=big ;; + riscv*eb) cpu_type=riscv endian=big ;; + riscv*) cpu_type=riscv endian=little ;; rs6000*) cpu_type=ppc ;; rl78*) cpu_type=rl78 ;; rx) cpu_type=rx ;; @@ -100,6 +102,7 @@ case ${generic_target} in aarch64*-*-elf) fmt=elf;; aarch64*-*-linux*) fmt=elf em=linux ;; + aarch64*-*-netbsd*) fmt=elf em=nbsd ;; alpha-*-*vms*) fmt=evax ;; alpha-*-osf*) fmt=ecoff ;; @@ -111,9 +114,11 @@ arc-*-elf*) fmt=elf ;; arm-*-aout) fmt=aout ;; - arm-*-coff) fmt=coff ;; - arm-*-rtems*) fmt=elf ;; - arm-*-elf) fmt=elf ;; + arm-*-coff | thumb-*-coff) fmt=coff ;; + arm-*-rtems* | thumb-*-rtems*) fmt=elf ;; + arm-*-elf | thumb-*-elf) fmt=elf ;; + arm-*-netbsdelf*-*eabihf*) fmt=elf em=armnbsdeabihf ;; + arm-*-netbsdelf*-*eabi*) fmt=elf em=armnbsdeabi ;; arm-*-eabi*) fmt=elf em=armeabi ;; arm-*-symbianelf*) fmt=elf em=symbian ;; arm-*-kaos*) fmt=elf ;; @@ -124,8 +129,8 @@ arm-*-uclinux*eabi*) fmt=elf em=armlinuxeabi ;; arm-*-uclinux*) fmt=elf em=linux ;; arm-*-nacl*) fmt=elf em=nacl ;; - arm-*-netbsdelf*) fmt=elf em=nbsd ;; - arm-*-*n*bsd*) fmt=aout em=nbsd ;; + arm-*-netbsdelf*) fmt=elf em=armnbsd ;; + arm-*-*n*bsd*) fmt=aout em=armnbsd ;; arm-*-nto*) fmt=elf ;; arm-epoc-pe) fmt=coff em=epoc-pe ;; arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*) @@ -334,10 +339,9 @@ ns32k-pc532-lites*) fmt=aout em=nbsd532 ;; ns32k-*-*n*bsd*) fmt=aout em=nbsd532 ;; - openrisc-*-*) fmt=elf ;; - - or32-*-rtems*) fmt=elf ;; - or32-*-elf) fmt=elf ;; + or1k-*-elf) fmt=elf ;; + or1k-*-linux*) fmt=elf em=linux ;; + or1k-*-netbsd*) fmt=elf em=nbsd ;; pj*) fmt=elf ;; @@ -357,6 +361,11 @@ ppc-*-kaos*) fmt=elf ;; ppc-*-lynxos*) fmt=elf em=lynx ;; + riscv*eb-*-linux*) fmt=elf endian=big em=linux ;; + riscv*eb-*-netbsd*) fmt=elf endian=big em=nbsd ;; + riscv*-*-linux*) fmt=elf endian=little em=linux ;; + riscv*-*-netbsd*) fmt=elf endian=little em=nbsd ;; + s390-*-linux-*) fmt=elf em=linux ;; s390-*-tpf*) fmt=elf ;; @@ -451,7 +460,7 @@ esac case ${cpu_type} in - aarch64 | alpha | arm | i386 | ia64 | microblaze | mips | ns32k | pdp11 | ppc | sparc | z80 | z8k) + aarch64 | alpha | arm | i386 | ia64 | microblaze | mips | ns32k | or1k | or1knd | pdp11 | ppc | riscv | sparc | z80 | z8k) bfd_gas=yes ;; esac diff -rNU3 dist.orig/gas/doc/Makefile.am dist/gas/doc/Makefile.am --- dist.orig/gas/doc/Makefile.am 2012-09-04 14:53:45.000000000 +0200 +++ dist/gas/doc/Makefile.am 2015-10-18 13:11:13.000000000 +0200 @@ -24,6 +24,8 @@ -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc asconfig.texi: $(CONFIG).texi + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_asconfig.text: rm -f asconfig.texi cp $(srcdir)/$(CONFIG).texi ./asconfig.texi chmod u+w ./asconfig.texi @@ -103,6 +105,8 @@ # The sed command removes the no-adjust Nroff command so that # the man output looks standard. as.1: $(srcdir)/as.texinfo asconfig.texi $(CPU_DOCS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_as.1: touch $@ -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod -($(POD2MAN) as.pod | \ diff -rNU3 dist.orig/gas/doc/Makefile.in dist/gas/doc/Makefile.in --- dist.orig/gas/doc/Makefile.in 2012-09-04 14:53:45.000000000 +0200 +++ dist/gas/doc/Makefile.in 2015-10-18 13:11:13.000000000 +0200 @@ -374,6 +374,8 @@ -rm -rf .libs _libs as.info: as.texinfo $(as_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_as.info: as.texinfo $(as_TEXINFOS) restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ @@ -756,6 +758,8 @@ asconfig.texi: $(CONFIG).texi + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_asconfig.texi: rm -f asconfig.texi cp $(srcdir)/$(CONFIG).texi ./asconfig.texi chmod u+w ./asconfig.texi @@ -773,6 +777,8 @@ # The sed command removes the no-adjust Nroff command so that # the man output looks standard. as.1: $(srcdir)/as.texinfo asconfig.texi $(CPU_DOCS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_as.1: touch $@ -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod -($(POD2MAN) as.pod | \ diff -rNU3 dist.orig/gas/doc/as.info dist/gas/doc/as.info --- dist.orig/gas/doc/as.info 2013-03-25 10:10:23.000000000 +0100 +++ dist/gas/doc/as.info 2015-10-18 13:11:13.000000000 +0200 @@ -22275,8 +22275,8 @@ * -g command line option, Alpha: Alpha Options. (line 47) * -G command line option, Alpha: Alpha Options. (line 53) * -G option (MIPS): MIPS Opts. (line 8) -* -H option, VAX/VMS: VAX-Opts. (line 81) * -h option, VAX/VMS: VAX-Opts. (line 45) +* -H option, VAX/VMS: VAX-Opts. (line 81) * -I PATH: I. (line 6) * -ignore-parallel-conflicts option, M32RX: M32R-Opts. (line 87) * -Ip option, M32RX: M32R-Opts. (line 97) @@ -22876,8 +22876,8 @@ * BSD syntax: PDP-11-Syntax. (line 6) * bss directive, i960: Directives-i960. (line 6) * bss directive, TIC54X: TIC54X-Directives. (line 29) -* bss section <1>: bss. (line 6) -* bss section: Ld Sections. (line 20) +* bss section <1>: Ld Sections. (line 20) +* bss section: bss. (line 6) * bug criteria: Bug Criteria. (line 6) * bug reports: Bug Reporting. (line 6) * bugs in assembler: Reporting Bugs. (line 6) diff -rNU3 dist.orig/gas/doc/c-mips.texi dist/gas/doc/c-mips.texi --- dist.orig/gas/doc/c-mips.texi 2012-09-04 16:16:07.000000000 +0200 +++ dist/gas/doc/c-mips.texi 2015-10-18 13:11:13.000000000 +0200 @@ -210,6 +210,14 @@ @itemx -mno-fix-vr4130 Insert nops to work around the VR4130 @samp{mflo}/@samp{mfhi} errata. +@item -mfix-loongson2f-btb +@itemx -mno-fix-loongson2f-btb +Clear the Branch Target Buffer before any jump through a register. This +option is intended to be used on kernel code for the Loongson 2F processor +only; userland code compiled with this option will fault, and kernel code +compiled with this option run on another processor than Loongson 2F will +yield unpredictable results. + @item -mfix-24k @itemx -mno-fix-24k Insert nops to work around the 24K @samp{eret}/@samp{deret} errata. diff -rNU3 dist.orig/gas/remap.c dist/gas/remap.c --- dist.orig/gas/remap.c 2011-03-11 15:18:24.000000000 +0100 +++ dist/gas/remap.c 2015-10-18 13:11:13.000000000 +0200 @@ -84,8 +84,8 @@ return xstrdup (filename); name = filename + map->old_len; name_len = strlen (name) + 1; - s = (char *) alloca (name_len + map->new_len); + s = (char *) xmalloc (name_len + map->new_len); memcpy (s, map->new_prefix, map->new_len); memcpy (s + map->new_len, name, name_len); - return xstrdup (s); + return s; } diff -rNU3 dist.orig/gprof/corefile.c dist/gprof/corefile.c --- dist.orig/gprof/corefile.c 2012-03-06 14:54:59.000000000 +0100 +++ dist/gprof/corefile.c 2015-10-18 13:11:17.000000000 +0200 @@ -30,6 +30,8 @@ #include "corefile.h" #include "safe-ctype.h" +#include + bfd *core_bfd; static int core_num_syms; static asymbol **core_syms; diff -rNU3 dist.orig/gprof/gprof.c dist/gprof/gprof.c --- dist.orig/gprof/gprof.c 2009-06-12 17:33:30.000000000 +0200 +++ dist/gprof/gprof.c 2015-10-18 13:11:17.000000000 +0200 @@ -47,6 +47,8 @@ static void usage (FILE *, int) ATTRIBUTE_NORETURN; +#include + const char * whoami; const char * function_mapping_file; static const char * external_symbol_table; diff -rNU3 dist.orig/gprof/gprof.info dist/gprof/gprof.info --- dist.orig/gprof/gprof.info 2012-11-13 15:19:35.000000000 +0100 +++ dist/gprof/gprof.info 2015-10-18 13:11:17.000000000 +0200 @@ -2441,34 +2441,34 @@  Tag Table: Node: Top777 -Node: Introduction2102 -Node: Compiling4594 -Node: Executing8650 -Node: Invoking11438 -Node: Output Options12853 -Node: Analysis Options19942 -Node: Miscellaneous Options23640 -Node: Deprecated Options24895 -Node: Symspecs26964 -Node: Output28790 -Node: Flat Profile29830 -Node: Call Graph34783 -Node: Primary38015 -Node: Callers40603 -Node: Subroutines42720 -Node: Cycles44561 -Node: Line-by-line51338 -Node: Annotated Source55411 -Node: Inaccuracy58410 -Node: Sampling Error58668 -Node: Assumptions61572 -Node: How do I?63042 -Node: Incompatibilities64596 -Node: Details66090 -Node: Implementation66483 -Node: File Format72380 -Node: Internals76670 -Node: Debugging85165 -Node: GNU Free Documentation License86766 +Node: Introduction2103 +Node: Compiling4595 +Node: Executing8651 +Node: Invoking11439 +Node: Output Options12854 +Node: Analysis Options19943 +Node: Miscellaneous Options23641 +Node: Deprecated Options24896 +Node: Symspecs26965 +Node: Output28791 +Node: Flat Profile29831 +Node: Call Graph34784 +Node: Primary38016 +Node: Callers40604 +Node: Subroutines42721 +Node: Cycles44562 +Node: Line-by-line51339 +Node: Annotated Source55412 +Node: Inaccuracy58411 +Node: Sampling Error58669 +Node: Assumptions61573 +Node: How do I?63043 +Node: Incompatibilities64597 +Node: Details66091 +Node: Implementation66484 +Node: File Format72381 +Node: Internals76671 +Node: Debugging85166 +Node: GNU Free Documentation License86767  End Tag Table diff -rNU3 dist.orig/include/bfdlink.h dist/include/bfdlink.h --- dist.orig/include/bfdlink.h 2012-04-09 18:27:18.000000000 +0200 +++ dist/include/bfdlink.h 2015-10-18 13:11:17.000000000 +0200 @@ -435,6 +435,10 @@ option). If this is NULL, no symbols are being wrapped. */ struct bfd_hash_table *wrap_hash; + /* Hash table of symbols which may be left unresolved during + a link. If this is NULL, no symbols can be left unresolved. */ + struct bfd_hash_table *ignore_hash; + /* The output BFD. */ bfd *output_bfd; diff -rNU3 dist.orig/include/dis-asm.h dist/include/dis-asm.h --- dist.orig/include/dis-asm.h 2012-09-04 14:53:46.000000000 +0200 +++ dist/include/dis-asm.h 2015-10-18 13:11:17.000000000 +0200 @@ -226,7 +226,6 @@ extern int print_insn_bfin (bfd_vma, disassemble_info *); extern int print_insn_big_arm (bfd_vma, disassemble_info *); extern int print_insn_big_mips (bfd_vma, disassemble_info *); -extern int print_insn_big_or32 (bfd_vma, disassemble_info *); extern int print_insn_big_powerpc (bfd_vma, disassemble_info *); extern int print_insn_big_score (bfd_vma, disassemble_info *); extern int print_insn_cr16 (bfd_vma, disassemble_info *); @@ -253,7 +252,6 @@ extern int print_insn_iq2000 (bfd_vma, disassemble_info *); extern int print_insn_little_arm (bfd_vma, disassemble_info *); extern int print_insn_little_mips (bfd_vma, disassemble_info *); -extern int print_insn_little_or32 (bfd_vma, disassemble_info *); extern int print_insn_little_powerpc (bfd_vma, disassemble_info *); extern int print_insn_little_score (bfd_vma, disassemble_info *); extern int print_insn_lm32 (bfd_vma, disassemble_info *); @@ -275,9 +273,10 @@ extern int print_insn_msp430 (bfd_vma, disassemble_info *); extern int print_insn_mt (bfd_vma, disassemble_info *); extern int print_insn_ns32k (bfd_vma, disassemble_info *); -extern int print_insn_openrisc (bfd_vma, disassemble_info *); +extern int print_insn_or1k (bfd_vma, disassemble_info *); extern int print_insn_pdp11 (bfd_vma, disassemble_info *); extern int print_insn_pj (bfd_vma, disassemble_info *); +extern int print_insn_riscv (bfd_vma, disassemble_info *); extern int print_insn_rs6000 (bfd_vma, disassemble_info *); extern int print_insn_s390 (bfd_vma, disassemble_info *); extern int print_insn_sh (bfd_vma, disassemble_info *); diff -rNU3 dist.orig/include/elf/common.h dist/include/elf/common.h --- dist.orig/include/elf/common.h 2012-09-04 14:53:47.000000000 +0200 +++ dist/include/elf/common.h 2015-10-18 13:11:17.000000000 +0200 @@ -194,7 +194,7 @@ #define EM_MN10300 89 /* Matsushita MN10300 */ #define EM_MN10200 90 /* Matsushita MN10200 */ #define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_OR1K 92 /* OpenRISC 1000 32-bit embedded processor */ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */ @@ -298,6 +298,7 @@ #define EM_TILEGX 191 /* Tilera TILE-Gx multicore architecture family */ #define EM_RL78 197 /* Renesas RL78 family. */ #define EM_78K0R 199 /* Renesas 78K0R. */ +#define EM_RISCV 243 /* RISC-V */ /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision @@ -357,9 +358,6 @@ /* Ubicom IP2xxx; Written in the absense of an ABI. */ #define EM_IP2K_OLD 0x8217 -/* (Deprecated) Temporary number for the OpenRISC processor. */ -#define EM_OR32 0x8472 - /* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */ #define EM_CYGNUS_POWERPC 0x9025 @@ -607,6 +605,16 @@ /* Values for NetBSD .note.netbsd.ident notes. Note name is "NetBSD". */ #define NT_NETBSD_IDENT 1 +#define NT_NETBSD_MARCH 5 + +/* Values for NetBSD .note.netbsd.ident notes. Note name is "PaX". */ +#define NT_NETBSD_PAX 3 +#define NT_NETBSD_PAX_MPROTECT 0x01 /* Force enable Mprotect */ +#define NT_NETBSD_PAX_NOMPROTECT 0x02 /* Force disable Mprotect */ +#define NT_NETBSD_PAX_GUARD 0x04 /* Force enable Segvguard */ +#define NT_NETBSD_PAX_NOGUARD 0x08 /* Force disable Servguard */ +#define NT_NETBSD_PAX_ASLR 0x10 /* Force enable ASLR */ +#define NT_NETBSD_PAX_NOASLR 0x20 /* Force disable ASLR */ /* Values for OpenBSD .note.openbsd.ident notes. Note name is "OpenBSD". */ diff -rNU3 dist.orig/include/elf/openrisc.h dist/include/elf/openrisc.h --- dist.orig/include/elf/openrisc.h 2010-04-15 12:26:08.000000000 +0200 +++ dist/include/elf/openrisc.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,39 +0,0 @@ -/* OpenRISC ELF support for BFD. - Copyright 2001, 2010 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _ELF_OPENRISC_H -#define _ELF_OPENRISC_H - -#include "elf/reloc-macros.h" - -/* Relocations. */ -START_RELOC_NUMBERS (elf_openrisc_reloc_type) - RELOC_NUMBER (R_OPENRISC_NONE, 0) - RELOC_NUMBER (R_OPENRISC_INSN_REL_26, 1) - RELOC_NUMBER (R_OPENRISC_INSN_ABS_26, 2) - RELOC_NUMBER (R_OPENRISC_LO_16_IN_INSN, 3) - RELOC_NUMBER (R_OPENRISC_HI_16_IN_INSN, 4) - RELOC_NUMBER (R_OPENRISC_8, 5) - RELOC_NUMBER (R_OPENRISC_16, 6) - RELOC_NUMBER (R_OPENRISC_32, 7) - RELOC_NUMBER (R_OPENRISC_GNU_VTINHERIT, 8) - RELOC_NUMBER (R_OPENRISC_GNU_VTENTRY, 9) -END_RELOC_NUMBERS (R_OPENRISC_max) - -#endif /* _ELF_OPENRISC_H */ diff -rNU3 dist.orig/include/elf/or1k.h dist/include/elf/or1k.h --- dist.orig/include/elf/or1k.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/include/elf/or1k.h 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,65 @@ +/* Or1k ELF support for BFD. + Copyright 2001-2014 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see */ + +#ifndef _ELF_OR1K_H +#define _ELF_OR1K_H + +#include "elf/reloc-macros.h" + +/* Relocations. */ +START_RELOC_NUMBERS (elf_or1k_reloc_type) + RELOC_NUMBER (R_OR1K_NONE, 0) + RELOC_NUMBER (R_OR1K_32, 1) + RELOC_NUMBER (R_OR1K_16, 2) + RELOC_NUMBER (R_OR1K_8, 3) + RELOC_NUMBER (R_OR1K_LO_16_IN_INSN, 4) + RELOC_NUMBER (R_OR1K_HI_16_IN_INSN, 5) + RELOC_NUMBER (R_OR1K_INSN_REL_26, 6) + RELOC_NUMBER (R_OR1K_GNU_VTENTRY, 7) + RELOC_NUMBER (R_OR1K_GNU_VTINHERIT, 8) + RELOC_NUMBER (R_OR1K_32_PCREL, 9) + RELOC_NUMBER (R_OR1K_16_PCREL, 10) + RELOC_NUMBER (R_OR1K_8_PCREL, 11) + RELOC_NUMBER (R_OR1K_GOTPC_HI16, 12) + RELOC_NUMBER (R_OR1K_GOTPC_LO16, 13) + RELOC_NUMBER (R_OR1K_GOT16, 14) + RELOC_NUMBER (R_OR1K_PLT26, 15) + RELOC_NUMBER (R_OR1K_GOTOFF_HI16, 16) + RELOC_NUMBER (R_OR1K_GOTOFF_LO16, 17) + RELOC_NUMBER (R_OR1K_COPY, 18) + RELOC_NUMBER (R_OR1K_GLOB_DAT, 19) + RELOC_NUMBER (R_OR1K_JMP_SLOT, 20) + RELOC_NUMBER (R_OR1K_RELATIVE, 21) + RELOC_NUMBER (R_OR1K_TLS_GD_HI16, 22) + RELOC_NUMBER (R_OR1K_TLS_GD_LO16, 23) + RELOC_NUMBER (R_OR1K_TLS_LDM_HI16, 24) + RELOC_NUMBER (R_OR1K_TLS_LDM_LO16, 25) + RELOC_NUMBER (R_OR1K_TLS_LDO_HI16, 26) + RELOC_NUMBER (R_OR1K_TLS_LDO_LO16, 27) + RELOC_NUMBER (R_OR1K_TLS_IE_HI16, 28) + RELOC_NUMBER (R_OR1K_TLS_IE_LO16, 29) + RELOC_NUMBER (R_OR1K_TLS_LE_HI16, 30) + RELOC_NUMBER (R_OR1K_TLS_LE_LO16, 31) + RELOC_NUMBER (R_OR1K_TLS_TPOFF, 32) + RELOC_NUMBER (R_OR1K_TLS_DTPOFF, 33) + RELOC_NUMBER (R_OR1K_TLS_DTPMOD, 34) +END_RELOC_NUMBERS (R_OR1K_max) + +#define EF_OR1K_NODELAY (1UL << 0) + +#endif /* _ELF_OR1K_H */ diff -rNU3 dist.orig/include/elf/or32.h dist/include/elf/or32.h --- dist.orig/include/elf/or32.h 2010-05-18 05:31:06.000000000 +0200 +++ dist/include/elf/or32.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,56 +0,0 @@ -/* OR1K ELF support for BFD. Derived from ppc.h. - Copyright (C) 2002, 2010 Free Software Foundation, Inc. - Contributed by Ivan Guzvinec - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef _ELF_OR1K_H -#define _ELF_OR1K_H - -#include "elf/reloc-macros.h" - -/* Relocations. */ -START_RELOC_NUMBERS (elf_or32_reloc_type) - RELOC_NUMBER (R_OR32_NONE, 0) - RELOC_NUMBER (R_OR32_32, 1) - RELOC_NUMBER (R_OR32_16, 2) - RELOC_NUMBER (R_OR32_8, 3) - RELOC_NUMBER (R_OR32_CONST, 4) - RELOC_NUMBER (R_OR32_CONSTH, 5) - RELOC_NUMBER (R_OR32_JUMPTARG, 6) - RELOC_NUMBER (R_OR32_GNU_VTENTRY, 7) - RELOC_NUMBER (R_OR32_GNU_VTINHERIT, 8) -END_RELOC_NUMBERS (R_OR32_max) - -/* Four bit OR32 machine type field. */ -#define EF_OR32_MACH 0x0000000f - -/* Various CPU types. */ -#define E_OR32_MACH_BASE 0x00000000 -#define E_OR32_MACH_UNUSED1 0x00000001 -#define E_OR32_MACH_UNUSED2 0x00000002 -#define E_OR32_MACH_UNUSED4 0x00000003 - -/* Processor specific section headers, sh_type field */ -#define SHT_ORDERED SHT_HIPROC /* Link editor is to sort the \ - entries in this section \ - based on the address \ - specified in the associated \ - symbol table entry. */ - -#endif /* _ELF_OR1K_H */ diff -rNU3 dist.orig/include/elf/riscv.h dist/include/elf/riscv.h --- dist.orig/include/elf/riscv.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/include/elf/riscv.h 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,138 @@ +/* RISC-V ELF support for BFD. + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrw Waterman at UC Berkeley. + Based on MIPS ELF support for BFD, by Ian Lance Taylor. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* This file holds definitions specific to the RISCV ELF ABI. Note + that most of this is not actually implemented by BFD. */ + +#ifndef _ELF_RISCV_H +#define _ELF_RISCV_H + +#include "elf/reloc-macros.h" + +/* Relocation types. */ +START_RELOC_NUMBERS (elf_riscv_reloc_type) + /* Relocation types used by the dynamic linker. */ + RELOC_NUMBER (R_RISCV_NONE, 0) + RELOC_NUMBER (R_RISCV_32, 1) + RELOC_NUMBER (R_RISCV_64, 2) + RELOC_NUMBER (R_RISCV_RELATIVE, 3) + RELOC_NUMBER (R_RISCV_COPY, 4) + RELOC_NUMBER (R_RISCV_JUMP_SLOT, 5) + RELOC_NUMBER (R_RISCV_TLS_DTPMOD32, 6) + RELOC_NUMBER (R_RISCV_TLS_DTPMOD64, 7) + RELOC_NUMBER (R_RISCV_TLS_DTPREL32, 8) + RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9) + RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10) + RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11) + + /* Relocation types not used by the dynamic linker. */ + RELOC_NUMBER (R_RISCV_BRANCH, 16) + RELOC_NUMBER (R_RISCV_JAL, 17) + RELOC_NUMBER (R_RISCV_CALL, 18) + RELOC_NUMBER (R_RISCV_CALL_PLT, 19) + RELOC_NUMBER (R_RISCV_GOT_HI20, 20) + RELOC_NUMBER (R_RISCV_TLS_GOT_HI20, 21) + RELOC_NUMBER (R_RISCV_TLS_GD_HI20, 22) + RELOC_NUMBER (R_RISCV_PCREL_HI20, 23) + RELOC_NUMBER (R_RISCV_PCREL_LO12_I, 24) + RELOC_NUMBER (R_RISCV_PCREL_LO12_S, 25) + RELOC_NUMBER (R_RISCV_HI20, 26) + RELOC_NUMBER (R_RISCV_LO12_I, 27) + RELOC_NUMBER (R_RISCV_LO12_S, 28) + RELOC_NUMBER (R_RISCV_TPREL_HI20, 29) + RELOC_NUMBER (R_RISCV_TPREL_LO12_I, 30) + RELOC_NUMBER (R_RISCV_TPREL_LO12_S, 31) + RELOC_NUMBER (R_RISCV_TPREL_ADD, 32) + RELOC_NUMBER (R_RISCV_ADD8, 33) + RELOC_NUMBER (R_RISCV_ADD16, 34) + RELOC_NUMBER (R_RISCV_ADD32, 35) + RELOC_NUMBER (R_RISCV_ADD64, 36) + RELOC_NUMBER (R_RISCV_SUB8, 37) + RELOC_NUMBER (R_RISCV_SUB16, 38) + RELOC_NUMBER (R_RISCV_SUB32, 39) + RELOC_NUMBER (R_RISCV_SUB64, 40) + RELOC_NUMBER (R_RISCV_GNU_VTINHERIT, 41) + RELOC_NUMBER (R_RISCV_GNU_VTENTRY, 42) + RELOC_NUMBER (R_RISCV_ALIGN, 43) +END_RELOC_NUMBERS (R_RISCV_max) + +/* Processor specific flags for the ELF header e_flags field. */ + +/* Custom flag definitions. */ + +#define EF_RISCV_EXT_MASK 0xffff +#define EF_RISCV_EXT_SH 16 +#define E_RISCV_EXT_Xcustom 0x0000 +#define E_RISCV_EXT_Xhwacha 0x0001 +#define E_RISCV_EXT_RESERVED 0xffff + +#define EF_GET_RISCV_EXT(x) \ + ((x >> EF_RISCV_EXT_SH) & EF_RISCV_EXT_MASK) + +#define EF_SET_RISCV_EXT(x, ext) \ + do { x |= ((ext & EF_RISCV_EXT_MASK) << EF_RISCV_EXT_SH); } while (0) + +#define EF_IS_RISCV_EXT_Xcustom(x) \ + (EF_GET_RISCV_EXT(x) == E_RISCV_EXT_Xcustom) + +/* A mapping from extension names to elf flags */ + +struct riscv_extension_entry +{ + const char* name; + unsigned int flag; +}; + +static const struct riscv_extension_entry riscv_extension_map[] = +{ + {"Xcustom", E_RISCV_EXT_Xcustom}, + {"Xhwacha", E_RISCV_EXT_Xhwacha}, +}; + +/* Given an extension name, return an elf flag. */ + +static inline const char* riscv_elf_flag_to_name(unsigned int flag) +{ + unsigned int i; + + for (i=0; icurrent_space \ + (__len != 0 && __len <= __o->current_space \ ? (__o->current_ptr += __len, \ __o->current_space -= __len, \ (void *) (__o->current_ptr - __len)) \ diff -rNU3 dist.orig/include/opcode/mips.h dist/include/opcode/mips.h --- dist.orig/include/opcode/mips.h 2012-09-04 16:21:05.000000000 +0200 +++ dist/include/opcode/mips.h 2015-10-18 13:11:17.000000000 +0200 @@ -1035,7 +1035,11 @@ M_DSUB_I, M_DSUBU_I, M_DSUBU_I_2, + M_JR_S, + M_J_S, M_J_A, + M_JALR_S, + M_JALR_DS, M_JAL_1, M_JAL_2, M_JAL_A, diff -rNU3 dist.orig/include/opcode/riscv-opc.h dist/include/opcode/riscv-opc.h --- dist.orig/include/opcode/riscv-opc.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/include/opcode/riscv-opc.h 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,1234 @@ +/* Automatically generated by parse-opcodes */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define MATCH_VLSEGSTWU 0xc00305b +#define MASK_VLSEGSTWU 0x1e00707f +#define MATCH_C_LW0 0x12 +#define MASK_C_LW0 0x801f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_VLH 0x200205b +#define MASK_VLH 0xfff0707f +#define MATCH_C_LI 0x0 +#define MASK_C_LI 0x1f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_C_LD 0x9 +#define MASK_C_LD 0x1f +#define MATCH_VLD 0x600205b +#define MASK_VLD 0xfff0707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_C_LW 0xa +#define MASK_C_LW 0x1f +#define MATCH_VLW 0x400205b +#define MASK_VLW 0xfff0707f +#define MATCH_VSSEGSTW 0x400307b +#define MASK_VSSEGSTW 0x1e00707f +#define MATCH_UTIDX 0x6077 +#define MASK_UTIDX 0xfffff07f +#define MATCH_C_FLW 0x14 +#define MASK_C_FLW 0x1f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_VSSEGSTD 0x600307b +#define MASK_VSSEGSTD 0x1e00707f +#define MATCH_VSSEGSTB 0x307b +#define MASK_VSSEGSTB 0x1e00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_FMV_H_X 0xf4000053 +#define MASK_FMV_H_X 0xfff0707f +#define MATCH_C_FLD 0x15 +#define MASK_C_FLD 0x1f +#define MATCH_FRRM 0x202073 +#define MASK_FRRM 0xfffff07f +#define MATCH_VFMSV_S 0x1000202b +#define MASK_VFMSV_S 0xfff0707f +#define MATCH_C_LWSP 0x5 +#define MASK_C_LWSP 0x1f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FNMSUB_H 0x400004b +#define MASK_FNMSUB_H 0x600007f +#define MATCH_FLE_H 0xbc000053 +#define MASK_FLE_H 0xfe00707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_VSETVL 0x600b +#define MASK_VSETVL 0xfff0707f +#define MATCH_VFMSV_D 0x1200202b +#define MASK_VFMSV_D 0xfff0707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_VSSTW 0x400307b +#define MASK_VSSTW 0xfe00707f +#define MATCH_VSSTH 0x200307b +#define MASK_VSSTH 0xfe00707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_VSSTB 0x307b +#define MASK_VSSTB 0xfe00707f +#define MATCH_VSSTD 0x600307b +#define MASK_VSSTD 0xfe00707f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_RDTIMEH 0xc8102073 +#define MASK_RDTIMEH 0xfffff07f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f +#define MATCH_VENQIMM1 0xc00302b +#define MASK_VENQIMM1 0xfe007fff +#define MATCH_VENQIMM2 0xe00302b +#define MASK_VENQIMM2 0xfe007fff +#define MATCH_RDINSTRET 0xc0202073 +#define MASK_RDINSTRET 0xfffff07f +#define MATCH_C_SWSP 0x8 +#define MASK_C_SWSP 0x1f +#define MATCH_VLSTW 0x400305b +#define MASK_VLSTW 0xfe00707f +#define MATCH_VLSTH 0x200305b +#define MASK_VLSTH 0xfe00707f +#define MATCH_VLSTB 0x305b +#define MASK_VLSTB 0xfe00707f +#define MATCH_VLSTD 0x600305b +#define MASK_VLSTD 0xfe00707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_FMV_X_S 0xe0000053 +#define MASK_FMV_X_S 0xfff0707f +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_CUSTOM0_RS1 0x200b +#define MASK_CUSTOM0_RS1 0x707f +#define MATCH_VLSEGSTBU 0x800305b +#define MASK_VLSEGSTBU 0x1e00707f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_C_SRAI 0x1019 +#define MASK_C_SRAI 0x1c1f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FSUB_H 0xc000053 +#define MASK_FSUB_H 0xfe00007f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_VLSTBU 0x800305b +#define MASK_VLSTBU 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_FLH 0x1007 +#define MASK_FLH 0x707f +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FCVT_H_LU 0x6c000053 +#define MASK_FCVT_H_LU 0xfff0007f +#define MATCH_CUSTOM0 0xb +#define MASK_CUSTOM0 0x707f +#define MATCH_CUSTOM1 0x2b +#define MASK_CUSTOM1 0x707f +#define MATCH_CUSTOM2 0x5b +#define MASK_CUSTOM2 0x707f +#define MATCH_CUSTOM3 0x7b +#define MASK_CUSTOM3 0x707f +#define MATCH_VXCPTSAVE 0x302b +#define MASK_VXCPTSAVE 0xfff07fff +#define MATCH_VMSV 0x200202b +#define MASK_VMSV 0xfff0707f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_FRFLAGS 0x102073 +#define MASK_FRFLAGS 0xfffff07f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_FADD_H 0x4000053 +#define MASK_FADD_H 0xfe00007f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_VXCPTKILL 0x400302b +#define MASK_VXCPTKILL 0xffffffff +#define MATCH_STOP 0x5077 +#define MASK_STOP 0xffffffff +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJN_H 0x34000053 +#define MASK_FSGNJN_H 0xfe00707f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSQRT_H 0x24000053 +#define MASK_FSQRT_H 0xfff0007f +#define MATCH_VSSEGSTH 0x200307b +#define MASK_VSSEGSTH 0x1e00707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_VLSTWU 0xc00305b +#define MASK_VLSTWU 0xfe00707f +#define MATCH_VFSSEGW 0x1400207b +#define MASK_VFSSEGW 0x1ff0707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_FMSUB_H 0x4000047 +#define MASK_FMSUB_H 0x600007f +#define MATCH_VXCPTAUX 0x200402b +#define MASK_VXCPTAUX 0xfffff07f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_VFSSEGD 0x1600207b +#define MASK_VFSSEGD 0x1ff0707f +#define MATCH_VLSEGHU 0xa00205b +#define MASK_VLSEGHU 0x1ff0707f +#define MATCH_MOVN 0x2007077 +#define MASK_MOVN 0xfe00707f +#define MATCH_CUSTOM1_RS1 0x202b +#define MASK_CUSTOM1_RS1 0x707f +#define MATCH_VLSTHU 0xa00305b +#define MASK_VLSTHU 0xfe00707f +#define MATCH_MOVZ 0x7077 +#define MASK_MOVZ 0xfe00707f +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_VLWU 0xc00205b +#define MASK_VLWU 0xfff0707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_FCVT_LU_H 0x4c000053 +#define MASK_FCVT_LU_H 0xfff0007f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_VFLSTD 0x1600305b +#define MASK_VFLSTD 0xfe00707f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_H 0x84000053 +#define MASK_FCVT_S_H 0xfff0007f +#define MATCH_FSCSR 0x301073 +#define MASK_FSCSR 0xfff0707f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_VFLSTW 0x1400305b +#define MASK_VFLSTW 0xfe00707f +#define MATCH_VXCPTEVAC 0x600302b +#define MASK_VXCPTEVAC 0xfff07fff +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_FSFLAGS 0x101073 +#define MASK_FSFLAGS 0xfff0707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_C_SRLI 0x819 +#define MASK_C_SRLI 0x1c1f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_VFLSEGW 0x1400205b +#define MASK_VFLSEGW 0x1ff0707f +#define MATCH_C_LD0 0x8012 +#define MASK_C_LD0 0x801f +#define MATCH_VLSEGBU 0x800205b +#define MASK_VLSEGBU 0x1ff0707f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_CUSTOM2_RD_RS1 0x605b +#define MASK_CUSTOM2_RD_RS1 0x707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_SFENCE_VM 0x10100073 +#define MASK_SFENCE_VM 0xfff07fff +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_RDCYCLEH 0xc8002073 +#define MASK_RDCYCLEH 0xfffff07f +#define MATCH_VLSEGSTHU 0xa00305b +#define MASK_VLSEGSTHU 0x1e00707f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_FMUL_H 0x14000053 +#define MASK_FMUL_H 0xfe00007f +#define MATCH_VFLSEGD 0x1600205b +#define MASK_VFLSEGD 0x1ff0707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_FSGNJX_H 0x3c000053 +#define MASK_FSGNJX_H 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_CUSTOM1_RD_RS1 0x602b +#define MASK_CUSTOM1_RD_RS1 0x707f +#define MATCH_FEQ_H 0xac000053 +#define MASK_FEQ_H 0xfe00707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_SRAI_RV32 0x40005013 +#define MASK_SRAI_RV32 0xfe00707f +#define MATCH_C_SRLI32 0xc19 +#define MASK_C_SRLI32 0x1c1f +#define MATCH_VFSSTW 0x1400307b +#define MASK_VFSSTW 0xfe00707f +#define MATCH_CUSTOM0_RD 0x400b +#define MASK_CUSTOM0_RD 0x707f +#define MATCH_C_BEQ 0x10 +#define MASK_C_BEQ 0x1f +#define MATCH_VFSSTD 0x1600307b +#define MASK_VFSSTD 0xfe00707f +#define MATCH_CUSTOM3_RD_RS1 0x607b +#define MASK_CUSTOM3_RD_RS1 0x707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_FCVT_H_WU 0x7c000053 +#define MASK_FCVT_H_WU 0xfff0007f +#define MATCH_VMVV 0x200002b +#define MASK_VMVV 0xfff0707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_C_SUB3 0x11c +#define MASK_C_SUB3 0x31f +#define MATCH_FSGNJ_H 0x2c000053 +#define MASK_FSGNJ_H 0xfe00707f +#define MATCH_VLB 0x205b +#define MASK_VLB 0xfff0707f +#define MATCH_C_ADDIW 0x1d +#define MASK_C_ADDIW 0x1f +#define MATCH_CUSTOM3_RS1_RS2 0x307b +#define MASK_CUSTOM3_RS1_RS2 0x707f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_VLSEGWU 0xc00205b +#define MASK_VLSEGWU 0x1ff0707f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_CUSTOM3_RS1 0x207b +#define MASK_CUSTOM3_RS1 0x707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_VFSW 0x1400207b +#define MASK_VFSW 0xfff0707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_VFSD 0x1600207b +#define MASK_VFSD 0xfff0707f +#define MATCH_CUSTOM2_RS1 0x205b +#define MASK_CUSTOM2_RS1 0x707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_FMV_S_X 0xf0000053 +#define MASK_FMV_S_X 0xfff0707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_C_FSD 0x18 +#define MASK_C_FSD 0x1f +#define MATCH_RDCYCLE 0xc0002073 +#define MASK_RDCYCLE 0xfffff07f +#define MATCH_C_BNE 0x11 +#define MASK_C_BNE 0x1f +#define MATCH_C_ADD 0x1a +#define MASK_C_ADD 0x801f +#define MATCH_VXCPTCAUSE 0x402b +#define MASK_VXCPTCAUSE 0xfffff07f +#define MATCH_VGETCFG 0x400b +#define MASK_VGETCFG 0xfffff07f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_VSETCFG 0x200b +#define MASK_VSETCFG 0x7fff +#define MATCH_C_SDSP 0x6 +#define MASK_C_SDSP 0x1f +#define MATCH_C_LDSP 0x4 +#define MASK_C_LDSP 0x1f +#define MATCH_FNMADD_H 0x400004f +#define MASK_FNMADD_H 0x600007f +#define MATCH_CUSTOM0_RS1_RS2 0x300b +#define MASK_CUSTOM0_RS1_RS2 0x707f +#define MATCH_SLLI_RV32 0x1013 +#define MASK_SLLI_RV32 0xfe00707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_C_SRAI32 0x1419 +#define MASK_C_SRAI32 0x1c1f +#define MATCH_FLT_H 0xb4000053 +#define MASK_FLT_H 0xfe00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_CUSTOM2_RD 0x405b +#define MASK_CUSTOM2_RD 0x707f +#define MATCH_MRTS 0x30500073 +#define MASK_MRTS 0xffffffff +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_WU_H 0x5c000053 +#define MASK_FCVT_WU_H 0xfff0007f +#define MATCH_C_SLLI 0x19 +#define MASK_C_SLLI 0x1c1f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_CUSTOM3_RD 0x407b +#define MASK_CUSTOM3_RD 0x707f +#define MATCH_FMAX_H 0xcc000053 +#define MASK_FMAX_H 0xfe00707f +#define MATCH_VENQCNT 0x1000302b +#define MASK_VENQCNT 0xfe007fff +#define MATCH_VLBU 0x800205b +#define MASK_VLBU 0xfff0707f +#define MATCH_VLHU 0xa00205b +#define MASK_VLHU 0xfff0707f +#define MATCH_C_SW 0xd +#define MASK_C_SW 0x1f +#define MATCH_C_SD 0xc +#define MASK_C_SD 0x1f +#define MATCH_C_OR3 0x21c +#define MASK_C_OR3 0x31f +#define MATCH_C_AND3 0x31c +#define MASK_C_AND3 0x31f +#define MATCH_VFSSEGSTW 0x1400307b +#define MASK_VFSSEGSTW 0x1e00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_VFSSEGSTD 0x1600307b +#define MASK_VFSSEGSTD 0x1e00707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_CUSTOM2_RS1_RS2 0x305b +#define MASK_CUSTOM2_RS1_RS2 0x707f +#define MATCH_VF 0x10202b +#define MASK_VF 0x1f0707f +#define MATCH_VFMVV 0x1000002b +#define MASK_VFMVV 0xfff0707f +#define MATCH_VFLSEGSTW 0x1400305b +#define MASK_VFLSEGSTW 0x1e00707f +#define MATCH_VXCPTRESTORE 0x200302b +#define MASK_VXCPTRESTORE 0xfff07fff +#define MATCH_VXCPTHOLD 0x800302b +#define MASK_VXCPTHOLD 0xfff07fff +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_VFLSEGSTD 0x1600305b +#define MASK_VFLSEGSTD 0x1e00707f +#define MATCH_VFLD 0x1600205b +#define MASK_VFLD 0xfff0707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_VFLW 0x1400205b +#define MASK_VFLW 0xfff0707f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMADD_H 0x4000043 +#define MASK_FMADD_H 0x600007f +#define MATCH_SRET 0x10000073 +#define MASK_SRET 0xffffffff +#define MATCH_VSSEGW 0x400207b +#define MASK_VSSEGW 0x1ff0707f +#define MATCH_CUSTOM0_RD_RS1 0x600b +#define MASK_CUSTOM0_RD_RS1 0x707f +#define MATCH_VSSEGH 0x200207b +#define MASK_VSSEGH 0x1ff0707f +#define MATCH_FRCSR 0x302073 +#define MASK_FRCSR 0xfffff07f +#define MATCH_VSSEGD 0x600207b +#define MASK_VSSEGD 0x1ff0707f +#define MATCH_VSSEGB 0x207b +#define MASK_VSSEGB 0x1ff0707f +#define MATCH_FMIN_H 0xc4000053 +#define MASK_FMIN_H 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_SRLI_RV32 0x5013 +#define MASK_SRLI_RV32 0xfe00707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FCVT_D_H 0x8c000053 +#define MASK_FCVT_D_H 0xfff0007f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_CUSTOM1_RD 0x402b +#define MASK_CUSTOM1_RD 0x707f +#define MATCH_FSRM 0x201073 +#define MASK_FSRM 0xfff0707f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_VSW 0x400207b +#define MASK_VSW 0xfff0707f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FDIV_H 0x1c000053 +#define MASK_FDIV_H 0xfe00007f +#define MATCH_VSB 0x207b +#define MASK_VSB 0xfff0707f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FSRMI 0x205073 +#define MASK_FSRMI 0xfff0707f +#define MATCH_FCVT_L_H 0x44000053 +#define MASK_FCVT_L_H 0xfff0007f +#define MATCH_VSH 0x200207b +#define MASK_VSH 0xfff0707f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_H_S 0x90000053 +#define MASK_FCVT_H_S 0xfff0007f +#define MATCH_SCALL 0x73 +#define MASK_SCALL 0xffffffff +#define MATCH_FSFLAGSI 0x105073 +#define MASK_FSFLAGSI 0xfff0707f +#define MATCH_FCVT_H_W 0x74000053 +#define MASK_FCVT_H_W 0xfff0007f +#define MATCH_FCVT_H_L 0x64000053 +#define MASK_FCVT_H_L 0xfff0007f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FCVT_H_D 0x92000053 +#define MASK_FCVT_H_D 0xfff0007f +#define MATCH_SBREAK 0x100073 +#define MASK_SBREAK 0xffffffff +#define MATCH_RDINSTRETH 0xc8202073 +#define MASK_RDINSTRETH 0xfffff07f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_VENQCMD 0xa00302b +#define MASK_VENQCMD 0xfe007fff +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_RDTIME 0xc0102073 +#define MASK_RDTIME 0xfffff07f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_C_MOVE 0x2 +#define MASK_C_MOVE 0x801f +#define MATCH_FMOVN 0x6007077 +#define MASK_FMOVN 0xfe00707f +#define MATCH_C_FSW 0x16 +#define MASK_C_FSW 0x1f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_FMOVZ 0x4007077 +#define MASK_FMOVZ 0xfe00707f +#define MATCH_CUSTOM1_RS1_RS2 0x302b +#define MASK_CUSTOM1_RS1_RS2 0x707f +#define MATCH_FMV_X_H 0xe4000053 +#define MASK_FMV_X_H 0xfff0707f +#define MATCH_VSD 0x600207b +#define MASK_VSD 0xfff0707f +#define MATCH_VLSEGSTW 0x400305b +#define MASK_VLSEGSTW 0x1e00707f +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0x1f +#define MATCH_C_SLLIW 0x1819 +#define MASK_C_SLLIW 0x1c1f +#define MATCH_VLSEGSTB 0x305b +#define MASK_VLSEGSTB 0x1e00707f +#define MATCH_VLSEGSTD 0x600305b +#define MASK_VLSEGSTD 0x1e00707f +#define MATCH_VLSEGSTH 0x200305b +#define MASK_VLSEGSTH 0x1e00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_C_SLLI32 0x419 +#define MASK_C_SLLI32 0x1c1f +#define MATCH_C_ADD3 0x1c +#define MASK_C_ADD3 0x31f +#define MATCH_VGETVL 0x200400b +#define MASK_VGETVL 0xfffff07f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_FCVT_W_H 0x54000053 +#define MASK_FCVT_W_H 0xfff0007f +#define MATCH_VLSEGB 0x205b +#define MASK_VLSEGB 0x1ff0707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_VLSEGD 0x600205b +#define MASK_VLSEGD 0x1ff0707f +#define MATCH_FSH 0x1027 +#define MASK_FSH 0x707f +#define MATCH_VLSEGH 0x200205b +#define MASK_VLSEGH 0x1ff0707f +#define MATCH_C_SUB 0x801a +#define MASK_C_SUB 0x801f +#define MATCH_VLSEGW 0x400205b +#define MASK_VLSEGW 0x1ff0707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_C_J 0x8002 +#define MASK_C_J 0x801f +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_STATS 0xc0 +#define CSR_UARCH0 0xcc0 +#define CSR_UARCH1 0xcc1 +#define CSR_UARCH2 0xcc2 +#define CSR_UARCH3 0xcc3 +#define CSR_UARCH4 0xcc4 +#define CSR_UARCH5 0xcc5 +#define CSR_UARCH6 0xcc6 +#define CSR_UARCH7 0xcc7 +#define CSR_UARCH8 0xcc8 +#define CSR_UARCH9 0xcc9 +#define CSR_UARCH10 0xcca +#define CSR_UARCH11 0xccb +#define CSR_UARCH12 0xccc +#define CSR_UARCH13 0xccd +#define CSR_UARCH14 0xcce +#define CSR_UARCH15 0xccf +#define CSR_SSTATUS 0x100 +#define CSR_STVEC 0x101 +#define CSR_STIMECMP 0x121 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SPTBR 0x188 +#define CSR_SASID 0x189 +#define CSR_SCYCLE 0x900 +#define CSR_STIME 0x901 +#define CSR_SINSTRET 0x902 +#define CSR_SCAUSE 0xd40 +#define CSR_SBADADDR 0xd41 +#define CSR_MSTATUS 0x300 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MBADADDR 0x343 +#define CSR_RESET 0x780 +#define CSR_TOHOST 0x781 +#define CSR_FROMHOST 0x782 +#define CSR_SEND_IPI 0x783 +#define CSR_HARTID 0xfc0 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_SCYCLEH 0x980 +#define CSR_STIMEH 0x981 +#define CSR_SINSTRETH 0x982 +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_ECALL 0x8 +#define CAUSE_BREAKPOINT 0x9 +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +DECLARE_INSN(vlsegstwu, MATCH_VLSEGSTWU, MASK_VLSEGSTWU) +DECLARE_INSN(c_lw0, MATCH_C_LW0, MASK_C_LW0) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(vlh, MATCH_VLH, MASK_VLH) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(vld, MATCH_VLD, MASK_VLD) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(vlw, MATCH_VLW, MASK_VLW) +DECLARE_INSN(vssegstw, MATCH_VSSEGSTW, MASK_VSSEGSTW) +DECLARE_INSN(utidx, MATCH_UTIDX, MASK_UTIDX) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(vssegstd, MATCH_VSSEGSTD, MASK_VSSEGSTD) +DECLARE_INSN(vssegstb, MATCH_VSSEGSTB, MASK_VSSEGSTB) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM) +DECLARE_INSN(vfmsv_s, MATCH_VFMSV_S, MASK_VFMSV_S) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H) +DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL) +DECLARE_INSN(vfmsv_d, MATCH_VFMSV_D, MASK_VFMSV_D) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(vsstw, MATCH_VSSTW, MASK_VSSTW) +DECLARE_INSN(vssth, MATCH_VSSTH, MASK_VSSTH) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(vsstb, MATCH_VSSTB, MASK_VSSTB) +DECLARE_INSN(vsstd, MATCH_VSSTD, MASK_VSSTD) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(venqimm1, MATCH_VENQIMM1, MASK_VENQIMM1) +DECLARE_INSN(venqimm2, MATCH_VENQIMM2, MASK_VENQIMM2) +DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(vlstw, MATCH_VLSTW, MASK_VLSTW) +DECLARE_INSN(vlsth, MATCH_VLSTH, MASK_VLSTH) +DECLARE_INSN(vlstb, MATCH_VLSTB, MASK_VLSTB) +DECLARE_INSN(vlstd, MATCH_VLSTD, MASK_VLSTD) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(vlsegstbu, MATCH_VLSEGSTBU, MASK_VLSEGSTBU) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(vlstbu, MATCH_VLSTBU, MASK_VLSTBU) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(flh, MATCH_FLH, MASK_FLH) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(vxcptsave, MATCH_VXCPTSAVE, MASK_VXCPTSAVE) +DECLARE_INSN(vmsv, MATCH_VMSV, MASK_VMSV) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(vxcptkill, MATCH_VXCPTKILL, MASK_VXCPTKILL) +DECLARE_INSN(stop, MATCH_STOP, MASK_STOP) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H) +DECLARE_INSN(vssegsth, MATCH_VSSEGSTH, MASK_VSSEGSTH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(vlstwu, MATCH_VLSTWU, MASK_VLSTWU) +DECLARE_INSN(vfssegw, MATCH_VFSSEGW, MASK_VFSSEGW) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H) +DECLARE_INSN(vxcptaux, MATCH_VXCPTAUX, MASK_VXCPTAUX) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(vfssegd, MATCH_VFSSEGD, MASK_VFSSEGD) +DECLARE_INSN(vlseghu, MATCH_VLSEGHU, MASK_VLSEGHU) +DECLARE_INSN(movn, MATCH_MOVN, MASK_MOVN) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(vlsthu, MATCH_VLSTHU, MASK_VLSTHU) +DECLARE_INSN(movz, MATCH_MOVZ, MASK_MOVZ) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(vlwu, MATCH_VLWU, MASK_VLWU) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(vflstd, MATCH_VFLSTD, MASK_VFLSTD) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H) +DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(vflstw, MATCH_VFLSTW, MASK_VFLSTW) +DECLARE_INSN(vxcptevac, MATCH_VXCPTEVAC, MASK_VXCPTEVAC) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(vflsegw, MATCH_VFLSEGW, MASK_VFLSEGW) +DECLARE_INSN(c_ld0, MATCH_C_LD0, MASK_C_LD0) +DECLARE_INSN(vlsegbu, MATCH_VLSEGBU, MASK_VLSEGBU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH) +DECLARE_INSN(vlsegsthu, MATCH_VLSEGSTHU, MASK_VLSEGSTHU) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H) +DECLARE_INSN(vflsegd, MATCH_VFLSEGD, MASK_VFLSEGD) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32) +DECLARE_INSN(c_srli32, MATCH_C_SRLI32, MASK_C_SRLI32) +DECLARE_INSN(vfsstw, MATCH_VFSSTW, MASK_VFSSTW) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(c_beq, MATCH_C_BEQ, MASK_C_BEQ) +DECLARE_INSN(vfsstd, MATCH_VFSSTD, MASK_VFSSTD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU) +DECLARE_INSN(vmvv, MATCH_VMVV, MASK_VMVV) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(c_sub3, MATCH_C_SUB3, MASK_C_SUB3) +DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H) +DECLARE_INSN(vlb, MATCH_VLB, MASK_VLB) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(vlsegwu, MATCH_VLSEGWU, MASK_VLSEGWU) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(vfsw, MATCH_VFSW, MASK_VFSW) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(vfsd, MATCH_VFSD, MASK_VFSD) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE) +DECLARE_INSN(c_bne, MATCH_C_BNE, MASK_C_BNE) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(vxcptcause, MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE) +DECLARE_INSN(vgetcfg, MATCH_VGETCFG, MASK_VGETCFG) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(vsetcfg, MATCH_VSETCFG, MASK_VSETCFG) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(c_srai32, MATCH_C_SRAI32, MASK_C_SRAI32) +DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(mrts, MATCH_MRTS, MASK_MRTS) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H) +DECLARE_INSN(venqcnt, MATCH_VENQCNT, MASK_VENQCNT) +DECLARE_INSN(vlbu, MATCH_VLBU, MASK_VLBU) +DECLARE_INSN(vlhu, MATCH_VLHU, MASK_VLHU) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_or3, MATCH_C_OR3, MASK_C_OR3) +DECLARE_INSN(c_and3, MATCH_C_AND3, MASK_C_AND3) +DECLARE_INSN(vfssegstw, MATCH_VFSSEGSTW, MASK_VFSSEGSTW) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(vfssegstd, MATCH_VFSSEGSTD, MASK_VFSSEGSTD) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(vf, MATCH_VF, MASK_VF) +DECLARE_INSN(vfmvv, MATCH_VFMVV, MASK_VFMVV) +DECLARE_INSN(vflsegstw, MATCH_VFLSEGSTW, MASK_VFLSEGSTW) +DECLARE_INSN(vxcptrestore, MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE) +DECLARE_INSN(vxcpthold, MATCH_VXCPTHOLD, MASK_VXCPTHOLD) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(vflsegstd, MATCH_VFLSEGSTD, MASK_VFLSEGSTD) +DECLARE_INSN(vfld, MATCH_VFLD, MASK_VFLD) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(vflw, MATCH_VFLW, MASK_VFLW) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(vssegw, MATCH_VSSEGW, MASK_VSSEGW) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(vssegh, MATCH_VSSEGH, MASK_VSSEGH) +DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR) +DECLARE_INSN(vssegd, MATCH_VSSEGD, MASK_VSSEGD) +DECLARE_INSN(vssegb, MATCH_VSSEGB, MASK_VSSEGB) +DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(vsw, MATCH_VSW, MASK_VSW) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H) +DECLARE_INSN(vsb, MATCH_VSB, MASK_VSB) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI) +DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H) +DECLARE_INSN(vsh, MATCH_VSH, MASK_VSH) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S) +DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL) +DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI) +DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W) +DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D) +DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK) +DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(venqcmd, MATCH_VENQCMD, MASK_VENQCMD) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(c_move, MATCH_C_MOVE, MASK_C_MOVE) +DECLARE_INSN(fmovn, MATCH_FMOVN, MASK_FMOVN) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(fmovz, MATCH_FMOVZ, MASK_FMOVZ) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H) +DECLARE_INSN(vsd, MATCH_VSD, MASK_VSD) +DECLARE_INSN(vlsegstw, MATCH_VLSEGSTW, MASK_VLSEGSTW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_slliw, MATCH_C_SLLIW, MASK_C_SLLIW) +DECLARE_INSN(vlsegstb, MATCH_VLSEGSTB, MASK_VLSEGSTB) +DECLARE_INSN(vlsegstd, MATCH_VLSEGSTD, MASK_VLSEGSTD) +DECLARE_INSN(vlsegsth, MATCH_VLSEGSTH, MASK_VLSEGSTH) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(c_slli32, MATCH_C_SLLI32, MASK_C_SLLI32) +DECLARE_INSN(c_add3, MATCH_C_ADD3, MASK_C_ADD3) +DECLARE_INSN(vgetvl, MATCH_VGETVL, MASK_VGETVL) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H) +DECLARE_INSN(vlsegb, MATCH_VLSEGB, MASK_VLSEGB) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(vlsegd, MATCH_VLSEGD, MASK_VLSEGD) +DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH) +DECLARE_INSN(vlsegh, MATCH_VLSEGH, MASK_VLSEGH) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(vlsegw, MATCH_VLSEGW, MASK_VLSEGW) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(stats, CSR_STATS) +DECLARE_CSR(uarch0, CSR_UARCH0) +DECLARE_CSR(uarch1, CSR_UARCH1) +DECLARE_CSR(uarch2, CSR_UARCH2) +DECLARE_CSR(uarch3, CSR_UARCH3) +DECLARE_CSR(uarch4, CSR_UARCH4) +DECLARE_CSR(uarch5, CSR_UARCH5) +DECLARE_CSR(uarch6, CSR_UARCH6) +DECLARE_CSR(uarch7, CSR_UARCH7) +DECLARE_CSR(uarch8, CSR_UARCH8) +DECLARE_CSR(uarch9, CSR_UARCH9) +DECLARE_CSR(uarch10, CSR_UARCH10) +DECLARE_CSR(uarch11, CSR_UARCH11) +DECLARE_CSR(uarch12, CSR_UARCH12) +DECLARE_CSR(uarch13, CSR_UARCH13) +DECLARE_CSR(uarch14, CSR_UARCH14) +DECLARE_CSR(uarch15, CSR_UARCH15) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(stimecmp, CSR_STIMECMP) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(sasid, CSR_SASID) +DECLARE_CSR(scycle, CSR_SCYCLE) +DECLARE_CSR(stime, CSR_STIME) +DECLARE_CSR(sinstret, CSR_SINSTRET) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(reset, CSR_RESET) +DECLARE_CSR(tohost, CSR_TOHOST) +DECLARE_CSR(fromhost, CSR_FROMHOST) +DECLARE_CSR(send_ipi, CSR_SEND_IPI) +DECLARE_CSR(hartid, CSR_HARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(scycleh, CSR_SCYCLEH) +DECLARE_CSR(stimeh, CSR_STIMEH) +DECLARE_CSR(sinstreth, CSR_SINSTRETH) +#endif +#ifdef DECLARE_CAUSE +DECLARE_CAUSE("fflags", CAUSE_FFLAGS) +DECLARE_CAUSE("frm", CAUSE_FRM) +DECLARE_CAUSE("fcsr", CAUSE_FCSR) +DECLARE_CAUSE("cycle", CAUSE_CYCLE) +DECLARE_CAUSE("time", CAUSE_TIME) +DECLARE_CAUSE("instret", CAUSE_INSTRET) +DECLARE_CAUSE("stats", CAUSE_STATS) +DECLARE_CAUSE("uarch0", CAUSE_UARCH0) +DECLARE_CAUSE("uarch1", CAUSE_UARCH1) +DECLARE_CAUSE("uarch2", CAUSE_UARCH2) +DECLARE_CAUSE("uarch3", CAUSE_UARCH3) +DECLARE_CAUSE("uarch4", CAUSE_UARCH4) +DECLARE_CAUSE("uarch5", CAUSE_UARCH5) +DECLARE_CAUSE("uarch6", CAUSE_UARCH6) +DECLARE_CAUSE("uarch7", CAUSE_UARCH7) +DECLARE_CAUSE("uarch8", CAUSE_UARCH8) +DECLARE_CAUSE("uarch9", CAUSE_UARCH9) +DECLARE_CAUSE("uarch10", CAUSE_UARCH10) +DECLARE_CAUSE("uarch11", CAUSE_UARCH11) +DECLARE_CAUSE("uarch12", CAUSE_UARCH12) +DECLARE_CAUSE("uarch13", CAUSE_UARCH13) +DECLARE_CAUSE("uarch14", CAUSE_UARCH14) +DECLARE_CAUSE("uarch15", CAUSE_UARCH15) +DECLARE_CAUSE("sstatus", CAUSE_SSTATUS) +DECLARE_CAUSE("stvec", CAUSE_STVEC) +DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP) +DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH) +DECLARE_CAUSE("sepc", CAUSE_SEPC) +DECLARE_CAUSE("sptbr", CAUSE_SPTBR) +DECLARE_CAUSE("sasid", CAUSE_SASID) +DECLARE_CAUSE("scycle", CAUSE_SCYCLE) +DECLARE_CAUSE("stime", CAUSE_STIME) +DECLARE_CAUSE("sinstret", CAUSE_SINSTRET) +DECLARE_CAUSE("scause", CAUSE_SCAUSE) +DECLARE_CAUSE("sbadaddr", CAUSE_SBADADDR) +DECLARE_CAUSE("mstatus", CAUSE_MSTATUS) +DECLARE_CAUSE("mscratch", CAUSE_MSCRATCH) +DECLARE_CAUSE("mepc", CAUSE_MEPC) +DECLARE_CAUSE("mcause", CAUSE_MCAUSE) +DECLARE_CAUSE("mbadaddr", CAUSE_MBADADDR) +DECLARE_CAUSE("reset", CAUSE_RESET) +DECLARE_CAUSE("tohost", CAUSE_TOHOST) +DECLARE_CAUSE("fromhost", CAUSE_FROMHOST) +DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI) +DECLARE_CAUSE("hartid", CAUSE_HARTID) +DECLARE_CAUSE("cycleh", CAUSE_CYCLEH) +DECLARE_CAUSE("timeh", CAUSE_TIMEH) +DECLARE_CAUSE("instreth", CAUSE_INSTRETH) +DECLARE_CAUSE("scycleh", CAUSE_SCYCLEH) +DECLARE_CAUSE("stimeh", CAUSE_STIMEH) +DECLARE_CAUSE("sinstreth", CAUSE_SINSTRETH) +#endif diff -rNU3 dist.orig/include/opcode/riscv.h dist/include/opcode/riscv.h --- dist.orig/include/opcode/riscv.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/include/opcode/riscv.h 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,320 @@ +/* riscv.h. RISC-V opcode list for GDB, the GNU debugger. + Copyright 2011 + Free Software Foundation, Inc. + Contributed by Andrew Waterman + +This file is part of GDB, GAS, and the GNU binutils. + +GDB, GAS, and the GNU binutils are free software; you can redistribute +them and/or modify them under the terms of the GNU General Public +License as published by the Free Software Foundation; either version +1, or (at your option) any later version. + +GDB, GAS, and the GNU binutils are distributed in the hope that they +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 _RISCV_H_ +#define _RISCV_H_ + +#include "riscv-opc.h" +#include +#include + +/* RVC fields */ + +#define OP_MASK_CRD 0x1f +#define OP_SH_CRD 5 +#define OP_MASK_CRS2 0x1f +#define OP_SH_CRS2 5 +#define OP_MASK_CRS1 0x1f +#define OP_SH_CRS1 10 +#define OP_MASK_CRDS 0x7 +#define OP_SH_CRDS 13 +#define OP_MASK_CRS2S 0x7 +#define OP_SH_CRS2S 13 +#define OP_MASK_CRS2BS 0x7 +#define OP_SH_CRS2BS 5 +#define OP_MASK_CRS1S 0x7 +#define OP_SH_CRS1S 10 +#define OP_MASK_CIMM6 0x3f +#define OP_SH_CIMM6 10 +#define OP_MASK_CIMM5 0x1f +#define OP_SH_CIMM5 5 +#define OP_MASK_CIMM10 0x3ff +#define OP_SH_CIMM10 5 + +static const char rvc_rs1_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 7 }; +#define rvc_rd_regmap rvc_rs1_regmap +#define rvc_rs2b_regmap rvc_rs1_regmap +static const char rvc_rs2_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 0 }; + +typedef uint64_t insn_t; + +static inline unsigned int riscv_insn_length (insn_t insn) +{ + if ((insn & 0x3) != 3) /* RVC */ + return 2; + if ((insn & 0x1f) != 0x1f) /* base ISA and extensions in 32-bit space */ + return 4; + if ((insn & 0x3f) == 0x1f) /* 48-bit extensions */ + return 6; + if ((insn & 0x7f) == 0x3f) /* 64-bit extensions */ + return 8; + /* longer instructions not supported at the moment */ + return 2; +} + +static const char * const riscv_rm[8] = { + "rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn" +}; +static const char* const riscv_pred_succ[16] = { + 0, "w", "r", "rw", "o", "ow", "or", "orw", + "i", "iw", "ir", "irw", "io", "iow", "ior", "iorw", +}; + +#define RVC_JUMP_BITS 10 +#define RVC_JUMP_ALIGN_BITS 1 +#define RVC_JUMP_ALIGN (1 << RVC_JUMP_ALIGN_BITS) +#define RVC_JUMP_REACH ((1ULL<> (s)) & ((1<<(n))-1)) +#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1)) + +#define EXTRACT_ITYPE_IMM(x) \ + (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12)) +#define EXTRACT_STYPE_IMM(x) \ + (RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12)) +#define EXTRACT_SBTYPE_IMM(x) \ + ((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12)) +#define EXTRACT_UTYPE_IMM(x) \ + ((RV_X(x, 12, 20) << 12) | (RV_IMM_SIGN(x) << 32)) +#define EXTRACT_UJTYPE_IMM(x) \ + ((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20)) + +#define ENCODE_ITYPE_IMM(x) \ + (RV_X(x, 0, 12) << 20) +#define ENCODE_STYPE_IMM(x) \ + ((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25)) +#define ENCODE_SBTYPE_IMM(x) \ + ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31)) +#define ENCODE_UTYPE_IMM(x) \ + (RV_X(x, 12, 20) << 12) +#define ENCODE_UJTYPE_IMM(x) \ + ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31)) + +#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x)) +#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x)) +#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x)) +#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x)) +#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x)) + +#define RISCV_RTYPE(insn, rd, rs1, rs2) \ + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2)) +#define RISCV_ITYPE(insn, rd, rs1, imm) \ + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm)) +#define RISCV_STYPE(insn, rs1, rs2, imm) \ + ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm)) +#define RISCV_SBTYPE(insn, rs1, rs2, target) \ + ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target)) +#define RISCV_UTYPE(insn, rd, bigimm) \ + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm)) +#define RISCV_UJTYPE(insn, rd, target) \ + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target)) + +#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0) + +#define RISCV_CONST_HIGH_PART(VALUE) \ + (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1)) +#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE)) +#define RISCV_PCREL_HIGH_PART(VALUE, PC) RISCV_CONST_HIGH_PART((VALUE) - (PC)) +#define RISCV_PCREL_LOW_PART(VALUE, PC) RISCV_CONST_LOW_PART((VALUE) - (PC)) + +/* RV fields */ + +#define OP_MASK_OP 0x7f +#define OP_SH_OP 0 +#define OP_MASK_RS2 0x1f +#define OP_SH_RS2 20 +#define OP_MASK_RS1 0x1f +#define OP_SH_RS1 15 +#define OP_MASK_RS3 0x1f +#define OP_SH_RS3 27 +#define OP_MASK_RD 0x1f +#define OP_SH_RD 7 +#define OP_MASK_SHAMT 0x3f +#define OP_SH_SHAMT 20 +#define OP_MASK_SHAMTW 0x1f +#define OP_SH_SHAMTW 20 +#define OP_MASK_RM 0x7 +#define OP_SH_RM 12 +#define OP_MASK_PRED 0xf +#define OP_SH_PRED 24 +#define OP_MASK_SUCC 0xf +#define OP_SH_SUCC 20 +#define OP_MASK_AQ 0x1 +#define OP_SH_AQ 26 +#define OP_MASK_RL 0x1 +#define OP_SH_RL 25 + +#define OP_MASK_VRD 0x1f +#define OP_SH_VRD 7 +#define OP_MASK_VRS 0x1f +#define OP_SH_VRS 15 +#define OP_MASK_VRT 0x1f +#define OP_SH_VRT 20 +#define OP_MASK_VRR 0x1f +#define OP_SH_VRR 27 + +#define OP_MASK_VFD 0x1f +#define OP_SH_VFD 7 +#define OP_MASK_VFS 0x1f +#define OP_SH_VFS 15 +#define OP_MASK_VFT 0x1f +#define OP_SH_VFT 20 +#define OP_MASK_VFR 0x1f +#define OP_SH_VFR 27 + +#define OP_MASK_IMMNGPR 0x3f +#define OP_SH_IMMNGPR 20 +#define OP_MASK_IMMNFPR 0x3f +#define OP_SH_IMMNFPR 26 +#define OP_MASK_IMMSEGNELM 0x7 +#define OP_SH_IMMSEGNELM 29 +#define OP_MASK_CUSTOM_IMM 0x7f +#define OP_SH_CUSTOM_IMM 25 +#define OP_MASK_CSR 0xfff +#define OP_SH_CSR 20 + +#define X_RA 1 +#define X_SP 2 +#define X_GP 3 +#define X_TP 4 +#define X_T0 5 +#define X_T1 6 +#define X_T2 7 +#define X_T3 28 + +#define NGPR 32 +#define NFPR 32 +#define NVGPR 32 +#define NVFPR 32 + +#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS +#define RISCV_JUMP_ALIGN_BITS 1 +#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS) +#define RISCV_JUMP_REACH ((1ULL< ld.pod -($(POD2MAN) ld.pod | \ diff -rNU3 dist.orig/ld/Makefile.in dist/ld/Makefile.in --- dist.orig/ld/Makefile.in 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/Makefile.in 2015-10-18 13:11:17.000000000 +0200 @@ -452,12 +452,16 @@ earmelf_linux_eabi.c \ earmelf_nacl.c \ earmelf_nbsd.c \ + earmelf_nbsd_eabi.c \ + earmelf_nbsd_eabihf.c \ earmelf_vxworks.c \ earmelfb.c \ earmelfb_linux.c \ earmelfb_linux_eabi.c \ earmelfb_nacl.c \ earmelfb_nbsd.c \ + earmelfb_nbsd_eabi.c \ + earmelfb_nbsd_eabihf.c \ earmnbsd.c \ earmnto.c \ earmpe.c \ @@ -535,6 +539,7 @@ eelf32lppc.c \ eelf32lppcnto.c \ eelf32lppcsim.c \ + eelf32lriscv.c \ eelf32lsmip.c \ eelf32ltsmip.c \ eelf32ltsmip_fbsd.c \ @@ -548,9 +553,12 @@ eelf32mipswindiss.c \ eelf32moxie.c \ eelf32mt.c \ - eelf32openrisc.c \ + eelf32or1k.c \ + eelf32or1k_linux.c \ + eelf32or1k_nbsd.c \ eelf32ppc.c \ eelf32ppc_fbsd.c \ + eelf32ppc_nbsd.c \ eelf32ppclinux.c \ eelf32ppcnto.c \ eelf32ppcsim.c \ @@ -709,8 +717,6 @@ emsp430xW427.c \ enews.c \ ens32knbsd.c \ - eor32.c \ - eor32elf.c \ epc532macha.c \ epdp11.c \ epjelf.c \ @@ -775,6 +781,8 @@ eaarch64elfb.c \ eaarch64linux.c \ eaarch64linuxb.c \ + eaarch64nbsd.c \ + eaarch64nbsdb.c \ eelf32_x86_64.c \ eelf32_x86_64_nacl.c \ eelf64_aix.c \ @@ -793,6 +801,7 @@ eelf64btsmip_fbsd.c \ eelf64hppa.c \ eelf64lppc.c \ + eelf64lriscv.c \ eelf64ltsmip.c \ eelf64ltsmip_fbsd.c \ eelf64mmix.c \ @@ -1060,6 +1069,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elfb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64nbsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64nbsdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@ @@ -1078,12 +1089,16 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd_eabi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd_eabihf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_vxworks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd_eabi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd_eabihf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmpe.Po@am__quote@ @@ -1156,6 +1171,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@ @@ -1169,9 +1185,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32openrisc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_linux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_nbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_fbsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_nbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppclinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcnto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcsim.Po@am__quote@ @@ -1204,6 +1223,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@ @@ -1363,8 +1383,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW427.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enews.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eor32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eor32elf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epc532macha.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdp11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjelf.Po@am__quote@ @@ -1490,6 +1508,8 @@ -rm -f libtool config.lt ld.info: ld.texinfo $(ld_TEXINFOS) + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ld.info: ld.texinfo $(ld_TEXINFOS) restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ @@ -2201,6 +2221,18 @@ $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} armelf_nbsd "$(tdir_armelf_nbsd)" +earmelf_nbsd_eabi.c: $(srcdir)/emulparams/armelf_nbsd_eabi.sh \ + $(srcdir)/emulparams/armelf_nbsd.sh \ + $(srcdir)/emulparams/armelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_nbsd_eabi "$(tdir_armelf_nbsd_eabi)" +earmelf_nbsd_eabihf.c: $(srcdir)/emulparams/armelf_nbsd_eabihf.sh \ + $(srcdir)/emulparams/armelf_nbsd.sh \ + $(srcdir)/emulparams/armelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_nbsd_eabihf "$(tdir_armelf_nbsd_eabihf)" earmelf_vxworks.c: $(srcdir)/emulparams/armelf_vxworks.sh \ $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/armelf.sh \ $(ELF_DEPS) $(srcdir)/emultempl/vxworks.em \ @@ -2236,6 +2268,20 @@ $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} armelfb_nbsd "$(tdir_armelfb_nbsd)" +earmelfb_nbsd_eabi.c: $(srcdir)/emulparams/armelfb_nbsd_eabi.sh \ + $(srcdir)/emulparams/armelf_nbsd_eabi.sh \ + $(srcdir)/emulparams/armelf_nbsd.sh \ + $(srcdir)/emulparams/armelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelfb_nbsd_eabi "$(tdir_armelfb_nbsd_eabi)" +earmelfb_nbsd_eabihf.c: $(srcdir)/emulparams/armelfb_nbsd_eabihf.sh \ + $(srcdir)/emulparams/armelf_nbsd_eabihf.sh \ + $(srcdir)/emulparams/armelf_nbsd.sh \ + $(srcdir)/emulparams/armelf.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelfb_nbsd_eabihf "$(tdir_armelfb_nbsd_eabihf)" earmnbsd.c: $(srcdir)/emulparams/armnbsd.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} armnbsd "$(tdir_armnbsd)" @@ -2550,6 +2596,10 @@ ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)" +eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \ + $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \ + $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lriscv "$(tdir_elf32lriscv)" eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \ $(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \ $(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \ @@ -2600,9 +2650,17 @@ eelf32mt.c: $(srcdir)/emulparams/elf32mt.sh \ $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32mt "$(tdir_mt)" -eelf32openrisc.c: $(srcdir)/emulparams/elf32openrisc.sh \ +eelf32or1k.c: $(srcdir)/emulparams/elf32or1k.sh \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32or1k "$(tdir_or1k)" +eelf32or1k_linux.c: $(srcdir)/emulparams/elf32or1k_linux.sh \ + $(srcdir)/emulparams/elf32or1k.sh \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32or1k_linux "$(tdir_or1k_linux)" +eelf32or1k_nbsd.c: $(srcdir)/emulparams/elf32or1k_nbsd.sh \ + $(srcdir)/emulparams/elf32or1k.sh \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} - ${GENSCRIPTS} elf32openrisc "$(tdir_openrisc)" + ${GENSCRIPTS} elf32or1k_nbsd "$(tdir_or1k_nbsd)" eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \ ldemul-list.h \ @@ -2614,6 +2672,12 @@ ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppc_fbsd "$(tdir_elf32ppc_fbsd)" +eelf32ppc_nbsd.c: $(srcdir)/emulparams/elf32ppc_nbsd.sh \ + $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ + $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32ppc_nbsd "$(tdir_elf32ppc_nbsd)" eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ @@ -3211,12 +3275,14 @@ $(ELF_DEPS) $(srcdir)/emultempl/aarch64elf.em \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} aarch64linuxb "$(tdir_aarch64linuxb)" -eor32.c: $(srcdir)/emulparams/or32.sh \ - $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/or32.sc ${GEN_DEPENDS} - ${GENSCRIPTS} or32 "$(tdir_or32)" -eor32elf.c: $(srcdir)/emulparams/or32elf.sh \ - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} - ${GENSCRIPTS} or32elf "$(tdir_or32elf)" +eaarch64nbsd.c: $(srcdir)/emulparams/aarch64nbsd.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/aarch64elf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aarch64nbsd "$(tdir_aarch64nbsd)" +eaarch64nbsdb.c: $(srcdir)/emulparams/aarch64nbsdb.sh $(srcdir)/emulparams/aarch64nbsd.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/aarch64elf.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aarch64nbsdb "$(tdir_aarch64nbsdb)" epc532macha.c: $(srcdir)/emulparams/pc532macha.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} pc532macha "$(tdir_pc532macha)" @@ -3499,6 +3565,11 @@ ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf64lppc "$(tdir_elf64lppc)" +eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \ + $(srcdir)/emulparams/elf64lriscv-defs.sh \ + $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \ + $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf64lriscv "$(tdir_elf64lriscv)" eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \ $(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \ $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \ @@ -3632,6 +3703,8 @@ # because almost all configs use "gen" version of manual. # Set DOCVER above to change. configdoc.texi: ${DOCVER}-doc.texi + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_configdoc.texi: cp ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi chmod u+w ./configdoc.texi @@ -3639,6 +3712,8 @@ # The sed command removes the no-adjust Nroff command so that # the man output looks standard. ld.1: $(srcdir)/ld.texinfo configdoc.texi + @echo "NOT REBUILDING $@" +NetBSD_DISABLED_ld.1: touch $@ -$(TEXI2POD) $(MANCONF) < $(srcdir)/ld.texinfo > ld.pod -($(POD2MAN) ld.pod | \ diff -rNU3 dist.orig/ld/configdoc.texi dist/ld/configdoc.texi --- dist.orig/ld/configdoc.texi 2012-11-13 15:19:33.000000000 +0100 +++ dist/ld/configdoc.texi 1970-01-01 01:00:00.000000000 +0100 @@ -1,27 +0,0 @@ -@c ------------------------------ CONFIGURATION VARS: -@c 1. Inclusiveness of this manual -@set GENERIC - -@c 2. Specific target machines -@set ARM -@set C6X -@set H8300 -@set HPPA -@set I960 -@set M68HC11 -@set M68K -@set MMIX -@set MSP430 -@set POWERPC -@set POWERPC64 -@set Renesas -@set SPU -@set TICOFF -@set WIN32 -@set XTENSA - -@c 3. Properties of this configuration -@clear SingleFormat -@set UsesEnvVars -@c ------------------------------ end CONFIGURATION VARS - diff -rNU3 dist.orig/ld/configure.tgt dist/ld/configure.tgt --- dist.orig/ld/configure.tgt 2012-09-04 14:53:47.000000000 +0200 +++ dist/ld/configure.tgt 2015-10-18 13:11:17.000000000 +0200 @@ -35,6 +35,10 @@ targ_extra_emuls="aarch64linux aarch64elfb aarch64elf armelfb_linux_eabi armelf_linux_eabi armelfb armelf" ;; aarch64-*-linux*) targ_emul=aarch64linux targ_extra_emuls="aarch64linuxb aarch64elf aarch64elfb armelf_linux_eabi armelfb_linux_eabi armelf armelfb" ;; +aarch64_be-*-netbsd*) targ_emul=aarch64nbsdb + targ_extra_emuls="aarch64nbsd aarch64elfb aarch64elf armelfb_nbsd_eabihf armelf_nbsd_eabihf armelfb_nbsd_eabi armelf_nbsd_eabi armelfb_nbsd armelf_nbsd armelf armelfb" ;; +aarch64-*-netbsd*) targ_emul=aarch64nbsd + targ_extra_emuls="aarch64nbsdb aarch64elf aarch64elfb armelf_nbsd_eabihf armelfb_nbsd_eabihf armelf_nbsd_eabi armelfb_nbsd_eabi armelf_nbsd armelfb_nbsd armelf armelfb" ;; alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) targ_emul=elf64alpha_fbsd targ_extra_emuls="elf64alpha alpha" @@ -64,7 +68,19 @@ arm-*-freebsd* | arm-*-kfreebsd*-gnu) targ_emul=armelf_fbsd targ_extra_emuls="armelf" ;; -armeb-*-netbsdelf*) targ_emul=armelfb_nbsd; +arm*eb-*-netbsdelf*-*eabihf*) + targ_emul=armelfb_nbsd_eabihf; + targ_extra_emuls="armelf_nbsd_eabihf armelf_nbsd_eabi armelfb_nbsd_eabi armelf_nbsd armelfb_nbsd armelf armnbsd" ;; +arm*eb-*-netbsdelf*-*eabi*) + targ_emul=armelfb_nbsd_eabi; + targ_extra_emuls="armelf_nbsd_eabi armelf_nbsd_eabihf armelfb_nbsd_eabihf armelf_nbsd armelfb_nbsd armelf armnbsd" ;; +arm*-*-netbsdelf*-*eabihf*) + targ_emul=armelf_nbsd_eabihf; + targ_extra_emuls="armelfb_nbsd_eabihf armelf_nbsd_eabi armelfb_nbsd_eabi armelf_nbsd armelfb_nbsd armelf armnbsd" ;; +arm*-*-netbsdelf*-*eabi*) + targ_emul=armelf_nbsd_eabi; + targ_extra_emuls="armelfb_nbsd_eabi armelf_nbsd_eabihf armelfb_nbsd_eabihf armelf_nbsd armelfb_nbsd armelf armnbsd" ;; +arm*eb-*-netbsdelf*) targ_emul=armelfb_nbsd; targ_extra_emuls="armelf_nbsd armelf armnbsd" ;; arm-*-netbsdelf*) targ_emul=armelf_nbsd; targ_extra_emuls="armelfb_nbsd armelf armnbsd" ;; @@ -379,7 +395,8 @@ m68*-*-gnu*) targ_emul=m68kelf ;; m68*-*-netbsd*4k*) targ_emul=m68k4knbsd targ_extra_emuls="m68knbsd m68kelfnbsd" ;; -m68*-*-netbsdelf*) targ_emul=m68kelfnbsd +m68*-*-netbsdelf* | m5407*-*-netbsdelf*) + targ_emul=m68kelfnbsd targ_extra_emuls="m68knbsd m68k4knbsd" ;; m68*-*-netbsdaout* | m68*-*-netbsd*) targ_emul=m68knbsd @@ -409,12 +426,18 @@ mips*-sgi-irix*) targ_emul=mipsbig ;; mips*el-*-ecoff*) targ_emul=mipsidtl ;; mips*-*-ecoff*) targ_emul=mipsidt ;; +mips64*el-*-netbsd*) targ_emul=elf32ltsmipn32 + targ_extra_emuls="elf64btsmip elf64ltsmip elf32ltsmip elf32btsmipn32 elf32btsmip" + ;; +mips64*-*-netbsd*) targ_emul=elf32btsmipn32 + targ_extra_emuls="elf64ltsmip elf64btsmip elf32btsmip elf32ltsmipn32 elf32ltsmip" + ;; mips*el-*-netbsd*) targ_emul=elf32ltsmip targ_extra_emuls="elf32btsmip elf64ltsmip elf64btsmip" ;; mips*-*-netbsd*) targ_emul=elf32btsmip targ_extra_emuls="elf32ltsmip elf64btsmip elf64ltsmip" - ;; + ;; mips*-*-bsd*) targ_emul=mipsbig ;; mips*vr4300el-*-elf*) targ_emul=elf32l4300 ;; mips*vr4300-*-elf*) targ_emul=elf32b4300 ;; @@ -481,11 +504,11 @@ ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;; ns32k-*-netbsd* | ns32k-pc532-lites*) targ_emul=ns32knbsd ;; -openrisc-*-*) targ_emul=elf32openrisc ;; -or32-*-coff) targ_emul=or32 ;; -or32-*-elf) targ_emul=or32elf ;; -or32-*-rtems*) targ_emul=or32elf - ;; +or1k-*-elf | or1knd-*-elf) targ_emul=elf32or1k ;; +or1k-*-linux* | or1knd-*-linux*) targ_emul=elf32or1k_linux ;; +or1k-*-netbsd* | or1knd-*-netbsd*) targ_emul=elf32or1k_nbsd ;; +or1k-*-rtems* | or1knd-*-rtems*) targ_emul=elf32or1k ;; + pdp11-*-*) targ_emul=pdp11 ;; pjl*-*-*) targ_emul=pjlelf ; targ_extra_emuls="elf_i386" ;; @@ -529,8 +552,18 @@ *) targ_emul=elf32lppc targ_extra_emuls="elf32ppcsim" ;; esac ;; +powerpc64*-*-netbsd*) + targ_emul=elf64ppc + targ_extra_emuls="elf32ppc elf32ppc_nbsd elf32ppcsim" + tdir_elf32ppc=`echo "${targ_alias}" | sed -e 's/64//'` + tdir_elf32ppc_nbsd=$tdir_elf32ppc + tdir_elf32ppcsim=$tdir_elf32ppc + ;; +powerpc*-*-netbsd*) + targ_emul=elf32ppc_nbsd + targ_extra_emuls="elf32ppc elf32ppcsim" ;; powerpc*-*-elf* | powerpc*-*-eabi* | powerpc*-*-sysv* \ - | powerpc*-*-netbsd* | powerpc-*-openbsd* | powerpc*-*-kaos*) + | powerpc-*-openbsd* | powerpc*-*-kaos*) case "${targ}" in *64*) targ_emul=elf64ppc targ_extra_emuls="elf32ppc elf32ppclinux elf32ppcsim" @@ -557,6 +590,12 @@ powerpc-*-beos*) targ_emul=aixppc ;; powerpc-*-windiss*) targ_emul=elf32ppcwindiss ;; powerpc-*-lynxos*) targ_emul=ppclynx ;; +riscv32-*-*) targ_emul=elf32lriscv + targ_extra_emuls="elf64lriscv" + targ_extra_libpath=$targ_extra_emuls ;; +riscv*-*-*) targ_emul=elf64lriscv + targ_extra_emuls="elf32lriscv" + targ_extra_libpath=$targ_extra_emuls ;; rs6000-*-aix[5-9]*) targ_emul=aix5rs6 ;; rs6000-*-aix*) targ_emul=aixrs6 ;; @@ -654,10 +693,15 @@ tdir_sparclinux=${targ_alias}aout tdir_elf64_sparc=`echo ${targ_alias} | sed -e 's/32//'` tdir_sun4=sparc-sun-sunos4 ;; -sparc64-*-netbsd* | sparc64-*-openbsd*) - targ_emul=elf64_sparc - targ_extra_emuls="elf32_sparc" ;; -sparc*-*-netbsd*elf*) targ_emul=elf32_sparc ;; +sparc64-*-netbsd*) targ_emul=elf64_sparc + targ_extra_emuls="elf32_sparc sparcnbsd" + ;; +sparc64-*-openbsd*) targ_emul=elf64_sparc + targ_extra_emuls="elf32_sparc" + ;; +sparc*-*-netbsd*elf*) targ_emul=elf32_sparc + targ_extra_emuls=sparcnbsd + ;; sparc*-*-netbsd*) targ_emul=sparcnbsd ;; sparc-*-solaris2.[0-6] | sparc-*-solaris2.[0-6].*) targ_emul=elf32_sparc_sol2 diff -rNU3 dist.orig/ld/emulparams/aarch64nbsd.sh dist/ld/emulparams/aarch64nbsd.sh --- dist.orig/ld/emulparams/aarch64nbsd.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/aarch64nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,36 @@ +ARCH=aarch64 +MACHINE= +NOP=0 + +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf64-littleaarch64" +BIG_OUTPUT_FORMAT="elf64-bigaarch64" +LITTLE_OUTPUT_FORMAT="elf64-littleaarch64" +NO_REL_RELOCS=yes + +TEMPLATE_NAME=elf32 +EXTRA_EM_FILE=aarch64elf + +GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes + +MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" +COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" +SEPARATE_GOTPLT=24 +IREL_IN_PLT= + +TEXT_START_ADDR=0x200100000 + +DATA_START_SYMBOLS='PROVIDE (__data_start = .);'; + +# AArch64 does not support .s* sections. +NO_SMALL_DATA=yes + +OTHER_BSS_SYMBOLS='__bss_start__ = .;' +OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;' +OTHER_END_SYMBOLS='__end__ = . ;' + +OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }' +ATTRS_SECTIONS='.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }' +# Ensure each PLT entry is aligned to a cache line. +PLT=".plt ${RELOCATING-0} : ALIGN(16) { *(.plt)${IREL_IN_PLT+ *(.iplt)} }" diff -rNU3 dist.orig/ld/emulparams/aarch64nbsdb.sh dist/ld/emulparams/aarch64nbsdb.sh --- dist.orig/ld/emulparams/aarch64nbsdb.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/aarch64nbsdb.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +. ${srcdir}/emulparams/aarch64nbsd.sh +OUTPUT_FORMAT="elf64-bigaarch64" diff -rNU3 dist.orig/ld/emulparams/armelf_nbsd.sh dist/ld/emulparams/armelf_nbsd.sh --- dist.orig/ld/emulparams/armelf_nbsd.sh 2006-05-30 18:45:32.000000000 +0200 +++ dist/ld/emulparams/armelf_nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -1,7 +1,14 @@ . ${srcdir}/emulparams/armelf.sh MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" -TEXT_START_ADDR=0x00008000 +TEXT_START_ADDR=0x00010000 TARGET2_TYPE=got-rel +unset DATA_START_SYMBOLS unset STACK_ADDR unset EMBEDDED + +case "$target" in + aarch64*-*-netbsd* | arm*-*-netbsdelf*-*eabi*) + LIB_PATH='=/usr/lib/oabi' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/armelf_nbsd_eabi.sh dist/ld/emulparams/armelf_nbsd_eabi.sh --- dist.orig/ld/emulparams/armelf_nbsd_eabi.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/armelf_nbsd_eabi.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,20 @@ +. ${srcdir}/emulparams/armelf_nbsd.sh + +# Use the ARM ABI-compliant exception-handling sections. +OTHER_READONLY_SECTIONS=" + .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) } + ${RELOCATING+ PROVIDE_HIDDEN (__exidx_start = .); } + .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) } + ${RELOCATING+ PROVIDE_HIDDEN (__exidx_end = .); }" + +case "$target" in + arm*-*-netbsdelf*-*eabihf*) + LIB_PATH='=/usr/lib/eabi' + ;; + arm*-*-netbsdelf*-*eabi*) + LIB_PATH='=/usr/lib' + ;; + aarch64*-*-netbsd* | arm*-*-netbsdelf*) + LIB_PATH='=/usr/lib/eabi' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/armelf_nbsd_eabihf.sh dist/ld/emulparams/armelf_nbsd_eabihf.sh --- dist.orig/ld/emulparams/armelf_nbsd_eabihf.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/armelf_nbsd_eabihf.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,17 @@ +. ${srcdir}/emulparams/armelf_nbsd.sh + +# Use the ARM ABI-compliant exception-handling sections. +OTHER_READONLY_SECTIONS=" + .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) } + ${RELOCATING+ PROVIDE_HIDDEN (__exidx_start = .); } + .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) } + ${RELOCATING+ PROVIDE_HIDDEN (__exidx_end = .); }" + +case "$target" in + arm*-*-netbsdelf*-*eabihf*) + LIB_PATH='=/usr/lib' + ;; + aarch64*-*-netbsd* | arm*-*-netbsdelf*) + LIB_PATH='=/usr/lib/eabihf' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/armelfb_nbsd_eabi.sh dist/ld/emulparams/armelfb_nbsd_eabi.sh --- dist.orig/ld/emulparams/armelfb_nbsd_eabi.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/armelfb_nbsd_eabi.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +. ${srcdir}/emulparams/armelf_nbsd_eabi.sh +OUTPUT_FORMAT="elf32-bigarm" diff -rNU3 dist.orig/ld/emulparams/armelfb_nbsd_eabihf.sh dist/ld/emulparams/armelfb_nbsd_eabihf.sh --- dist.orig/ld/emulparams/armelfb_nbsd_eabihf.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/armelfb_nbsd_eabihf.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +. ${srcdir}/emulparams/armelf_nbsd_eabihf.sh +OUTPUT_FORMAT="elf32-bigarm" diff -rNU3 dist.orig/ld/emulparams/elf32_sparc.sh dist/ld/emulparams/elf32_sparc.sh --- dist.orig/ld/emulparams/elf32_sparc.sh 2010-09-20 20:41:15.000000000 +0200 +++ dist/ld/emulparams/elf32_sparc.sh 2015-10-18 13:11:17.000000000 +0200 @@ -13,6 +13,13 @@ TEMPLATE_NAME=elf32 DATA_PLT= GENERATE_SHLIB_SCRIPT=yes +#ELFSIZE=32 GENERATE_PIE_SCRIPT=yes NOP=0x01000000 NO_SMALL_DATA=yes + +case "$target" in + sparc64-*-netbsd*) + LIB_PATH='=/usr/lib/sparc' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/elf32bmipn32-defs.sh dist/ld/emulparams/elf32bmipn32-defs.sh --- dist.orig/ld/emulparams/elf32bmipn32-defs.sh 2012-09-04 16:14:28.000000000 +0200 +++ dist/ld/emulparams/elf32bmipn32-defs.sh 2015-10-18 13:11:17.000000000 +0200 @@ -6,6 +6,7 @@ # Handle both big- and little-ended 32-bit MIPS objects. ARCH=mips +MACHINE= OUTPUT_FORMAT="elf32-bigmips" BIG_OUTPUT_FORMAT="elf32-bigmips" LITTLE_OUTPUT_FORMAT="elf32-littlemips" diff -rNU3 dist.orig/ld/emulparams/elf32lriscv-defs.sh dist/ld/emulparams/elf32lriscv-defs.sh --- dist.orig/ld/emulparams/elf32lriscv-defs.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32lriscv-defs.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,39 @@ +# This is an ELF platform. +SCRIPT_NAME=elf +ARCH=riscv +OUTPUT_FORMAT="elf32-littleriscv" +NO_REL_RELOCS=yes + +TEMPLATE_NAME=elf32 +EXTRA_EM_FILE=riscvelf + +case "$EMULATION_NAME" in +elf32*) ELFSIZE=32; LIBPATH_SUFFIX=32 ;; +elf64*) ELFSIZE=64; LIBPATH_SUFFIX= ;; +*) echo $0: unhandled emulation $EMULATION_NAME >&2; exit 1 ;; +esac + +if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then + case " $EMULATION_LIBPATH " in + *" ${EMULATION_NAME} "*) + NATIVE=yes + ;; + esac +fi + +GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes + +TEXT_START_ADDR=0x800000 +MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" +COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" + +INITIAL_READONLY_SECTIONS=".interp ${RELOCATING-0} : { *(.interp) }" +SDATA_START_SYMBOLS="_gp = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)" +if test -n "${CREATE_SHLIB}"; then + INITIAL_READONLY_SECTIONS= + SDATA_START_SYMBOLS= + OTHER_READONLY_SECTIONS=".srodata ${RELOCATING-0} : { *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) }" + unset GOT +fi diff -rNU3 dist.orig/ld/emulparams/elf32lriscv.sh dist/ld/emulparams/elf32lriscv.sh --- dist.orig/ld/emulparams/elf32lriscv.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32lriscv.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +. ${srcdir}/emulparams/elf32lriscv-defs.sh +OUTPUT_FORMAT="elf32-littleriscv" diff -rNU3 dist.orig/ld/emulparams/elf32openrisc.sh dist/ld/emulparams/elf32openrisc.sh --- dist.orig/ld/emulparams/elf32openrisc.sh 2008-10-22 07:20:44.000000000 +0200 +++ dist/ld/emulparams/elf32openrisc.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +0,0 @@ -MACHINE= -SCRIPT_NAME=elf -OUTPUT_FORMAT="elf32-openrisc" -NO_RELA_RELOCS=yes -TEXT_START_ADDR=0x10000 -ARCH=openrisc -MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" -ENTRY=_start -EMBEDDED=yes -NOP=0x15000000 - diff -rNU3 dist.orig/ld/emulparams/elf32or1k.sh dist/ld/emulparams/elf32or1k.sh --- dist.orig/ld/emulparams/elf32or1k.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32or1k.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,14 @@ +SCRIPT_NAME=elf +MACHINE= +TEMPLATE_NAME=elf32 +OUTPUT_FORMAT="elf32-or1k" +NOP=0x15000000 +TEXT_START_ADDR=0x0000 +TARGET_PAGE_SIZE=0x2000 +MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" +EMBEDDED=yes +ARCH=or1k +ELFSIZE=32 +INITIAL_READONLY_SECTIONS=".vectors ${RELOCATING-0} : { KEEP (*(.vectors)) }" +NO_REL_RELOCS=yes +COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" diff -rNU3 dist.orig/ld/emulparams/elf32or1k_linux.sh dist/ld/emulparams/elf32or1k_linux.sh --- dist.orig/ld/emulparams/elf32or1k_linux.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32or1k_linux.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,6 @@ +. ${srcdir}/emulparams/elf32or1k.sh +unset EMBEDDED +GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes +GENERATE_COMBRELOC_SCRIPT=yes +TEXT_START_ADDR=0x00002000 diff -rNU3 dist.orig/ld/emulparams/elf32or1k_nbsd.sh dist/ld/emulparams/elf32or1k_nbsd.sh --- dist.orig/ld/emulparams/elf32or1k_nbsd.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32or1k_nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,6 @@ +. ${srcdir}/emulparams/elf32or1k.sh +unset EMBEDDED +GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes +GENERATE_COMBRELOC_SCRIPT=yes +TEXT_START_ADDR=0x00002000 diff -rNU3 dist.orig/ld/emulparams/elf32ppc_nbsd.sh dist/ld/emulparams/elf32ppc_nbsd.sh --- dist.orig/ld/emulparams/elf32ppc_nbsd.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf32ppc_nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,7 @@ +. ${srcdir}/emulparams/elf32ppc.sh + +case "$target" in + powerpc64*-*-netbsd*) + LIB_PATH='=/usr/lib/powerpc' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/elf64alpha_nbsd.sh dist/ld/emulparams/elf64alpha_nbsd.sh --- dist.orig/ld/emulparams/elf64alpha_nbsd.sh 2001-12-18 00:54:58.000000000 +0100 +++ dist/ld/emulparams/elf64alpha_nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -1,2 +1,8 @@ . ${srcdir}/emulparams/elf64alpha.sh ENTRY=__start + +NOP=0x47ff041f +# XXX binutils 2.13 +# Note that the number is always big-endian, thus we have to +# reverse the digit string. +#NOP=0x0000fe2f1f04ff47 # unop; nop diff -rNU3 dist.orig/ld/emulparams/elf64lriscv-defs.sh dist/ld/emulparams/elf64lriscv-defs.sh --- dist.orig/ld/emulparams/elf64lriscv-defs.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf64lriscv-defs.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1 @@ +. ${srcdir}/emulparams/elf32lriscv-defs.sh diff -rNU3 dist.orig/ld/emulparams/elf64lriscv.sh dist/ld/emulparams/elf64lriscv.sh --- dist.orig/ld/emulparams/elf64lriscv.sh 1970-01-01 01:00:00.000000000 +0100 +++ dist/ld/emulparams/elf64lriscv.sh 2015-10-18 13:11:17.000000000 +0200 @@ -0,0 +1,2 @@ +. ${srcdir}/emulparams/elf64lriscv-defs.sh +OUTPUT_FORMAT="elf64-littleriscv" diff -rNU3 dist.orig/ld/emulparams/elf_i386.sh dist/ld/emulparams/elf_i386.sh --- dist.orig/ld/emulparams/elf_i386.sh 2012-06-11 15:23:50.000000000 +0200 +++ dist/ld/emulparams/elf_i386.sh 2015-10-18 13:11:17.000000000 +0200 @@ -9,7 +9,14 @@ MACHINE= TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes +#ELFSIZE=32 GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 12 ? 12 : 0" IREL_IN_PLT= + +case "$target" in + x86_64-*-netbsd*) + LIB_PATH='=/usr/lib/i386' + ;; +esac diff -rNU3 dist.orig/ld/emulparams/hppalinux.sh dist/ld/emulparams/hppalinux.sh --- dist.orig/ld/emulparams/hppalinux.sh 2011-02-18 19:20:29.000000000 +0100 +++ dist/ld/emulparams/hppalinux.sh 2015-10-18 13:11:17.000000000 +0200 @@ -1,5 +1,5 @@ # If you change this file, please also look at files which source this one: -# hppanbsd.sh +# hppanbsd.sh hppaobsd.sh SCRIPT_NAME=elf ELFSIZE=32 diff -rNU3 dist.orig/ld/emulparams/hppaobsd.sh dist/ld/emulparams/hppaobsd.sh --- dist.orig/ld/emulparams/hppaobsd.sh 2006-05-30 18:45:32.000000000 +0200 +++ dist/ld/emulparams/hppaobsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -1,4 +1,4 @@ -. ${srcdir}/emulparams/hppanbsd.sh +. ${srcdir}/emulparams/hppalinux.sh OUTPUT_FORMAT="elf32-hppa" TEXT_START_ADDR=0x1000 diff -rNU3 dist.orig/ld/emulparams/m68kelf.sh dist/ld/emulparams/m68kelf.sh --- dist.orig/ld/emulparams/m68kelf.sh 2009-09-29 18:28:52.000000000 +0200 +++ dist/ld/emulparams/m68kelf.sh 2015-10-18 13:11:17.000000000 +0200 @@ -10,5 +10,6 @@ TEMPLATE_NAME=elf32 EXTRA_EM_FILE=m68kelf GENERATE_SHLIB_SCRIPT=yes +ELFSIZE=32 GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes diff -rNU3 dist.orig/ld/emulparams/m68kelfnbsd.sh dist/ld/emulparams/m68kelfnbsd.sh --- dist.orig/ld/emulparams/m68kelfnbsd.sh 2001-12-18 14:26:26.000000000 +0100 +++ dist/ld/emulparams/m68kelfnbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -1,4 +1,4 @@ . ${srcdir}/emulparams/m68kelf.sh TEXT_START_ADDR=0x2000 TARGET_PAGE_SIZE=0x2000 -MACHINE= +NONPAGED_TEXT_START_ADDR=${TEXT_START_ADDR} diff -rNU3 dist.orig/ld/emulparams/or32.sh dist/ld/emulparams/or32.sh --- dist.orig/ld/emulparams/or32.sh 2006-06-20 04:22:14.000000000 +0200 +++ dist/ld/emulparams/or32.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,5 +0,0 @@ -SCRIPT_NAME=or32 -OUTPUT_FORMAT="coff-or32-big" -TEXT_START_ADDR=0x1000000 -TARGET_PAGE_SIZE=0x1000000 -ARCH=or32 diff -rNU3 dist.orig/ld/emulparams/or32elf.sh dist/ld/emulparams/or32elf.sh --- dist.orig/ld/emulparams/or32elf.sh 2008-10-22 07:20:44.000000000 +0200 +++ dist/ld/emulparams/or32elf.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,9 +0,0 @@ -SCRIPT_NAME=elf -TEMPLATE_NAME=generic -EXTRA_EM_FILE=genelf -OUTPUT_FORMAT="elf32-or32" -NO_RELA_RELOCS=yes -TEXT_START_ADDR=0x1000000 -TARGET_PAGE_SIZE=0x1000000 -MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" -ARCH=or32 diff -rNU3 dist.orig/ld/emulparams/sh.sh dist/ld/emulparams/sh.sh --- dist.orig/ld/emulparams/sh.sh 2001-11-22 10:08:04.000000000 +0100 +++ dist/ld/emulparams/sh.sh 2015-10-18 13:11:17.000000000 +0200 @@ -3,6 +3,6 @@ SCRIPT_NAME=sh OUTPUT_FORMAT="coff-sh" -TEXT_START_ADDR=0x8000 -TARGET_PAGE_SIZE=128 +TEXT_START_ADDR=0x1000 +TARGET_PAGE_SIZE=0x1000 ARCH=sh diff -rNU3 dist.orig/ld/emulparams/shelf_nbsd.sh dist/ld/emulparams/shelf_nbsd.sh --- dist.orig/ld/emulparams/shelf_nbsd.sh 2008-01-16 00:05:46.000000000 +0100 +++ dist/ld/emulparams/shelf_nbsd.sh 2015-10-18 13:11:17.000000000 +0200 @@ -9,7 +9,11 @@ DATA_START_SYMBOLS='PROVIDE (__data_start = .);'; -ENTRY=_start +ENTRY=__start unset EMBEDDED unset OTHER_SECTIONS + +OTHER_READWRITE_SECTIONS=' + .note.ABI-tag : { *(.note.ABI-tag) } +' diff -rNU3 dist.orig/ld/emultempl/aarch64elf.em dist/ld/emultempl/aarch64elf.em --- dist.orig/ld/emultempl/aarch64elf.em 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/emultempl/aarch64elf.em 2015-10-18 13:11:17.000000000 +0200 @@ -38,6 +38,7 @@ ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown); #endif /* not TARGET_ */ input_flags.dynamic = ${DYNAMIC_LINK-TRUE}; + input_flags.add_DT_NEEDED_for_dynamic = TRUE; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; } diff -rNU3 dist.orig/ld/emultempl/armelf.em dist/ld/emultempl/armelf.em --- dist.orig/ld/emultempl/armelf.em 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/emultempl/armelf.em 2015-10-18 13:11:17.000000000 +0200 @@ -51,6 +51,7 @@ ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown); #endif /* not TARGET_ */ input_flags.dynamic = ${DYNAMIC_LINK-TRUE}; + input_flags.add_DT_NEEDED_for_dynamic = TRUE; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; } diff -rNU3 dist.orig/ld/emultempl/elf32.em dist/ld/emultempl/elf32.em --- dist.orig/ld/emultempl/elf32.em 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/emultempl/elf32.em 2015-10-18 13:11:17.000000000 +0200 @@ -72,6 +72,9 @@ if [ "x${USE_LIBPATH}" = xyes ] ; then case ${target} in + *-*-netbsd*) + ;; + *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*) fragment <name; size_t len; struct dt_needed needed; - if (name[0] == '/') + if (name[0] == '/') { + if (prepend_sysroot && ld_sysroot) { + bfd_boolean rv; + needed.by = n->by; + char *filename= concat(ld_sysroot, n->name, (const char *)NULL); + needed.name = filename; + rv = gld${EMULATION_NAME}_try_needed (&needed, force); + free(filename); + return rv; + } return gld${EMULATION_NAME}_try_needed (n, force); + } if (path == NULL || *path == '\0') return FALSE; @@ -501,6 +518,13 @@ } strcpy (sset, name); + if (prepend_sysroot && filename[0] == '=') + abort(); + if (filename[0] == '/' && prepend_sysroot && ld_sysroot) { + char *filename2 = concat(ld_sysroot, filename, (const char *)NULL); + free(filename); + filename = filename2; + } needed.name = filename; if (gld${EMULATION_NAME}_try_needed (&needed, force)) return TRUE; @@ -621,6 +645,9 @@ # FreeBSD ;; + *-*-netbsd*) + ;; + *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*) fragment <next) { - char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); found = (rp->by == l->by - && gld${EMULATION_NAME}_search_needed (tmpname, + && gld${EMULATION_NAME}_search_needed (rp->name, &n, - force)); - free (tmpname); + force, 1)); } if (found) break; @@ -1315,6 +1340,9 @@ # FreeBSD ;; + *-*-netbsd*) + ;; + *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*) # Linux fragment <ignore_hash != NULL + && bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL) + return TRUE; + if (config.warn_once) { - static struct bfd_hash_table *hash; - /* Only warn once about a particular undefined symbol. */ - if (hash == NULL) + if (info->ignore_hash == NULL) { - hash = (struct bfd_hash_table *) - xmalloc (sizeof (struct bfd_hash_table)); - if (!bfd_hash_table_init (hash, bfd_hash_newfunc, + info->ignore_hash = xmalloc (sizeof (struct bfd_hash_table)); + if (!bfd_hash_table_init (info->ignore_hash, bfd_hash_newfunc, sizeof (struct bfd_hash_entry))) einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); } - if (bfd_hash_lookup (hash, name, FALSE, FALSE) != NULL) + if (bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL) return TRUE; - if (bfd_hash_lookup (hash, name, TRUE, TRUE) == NULL) + if (bfd_hash_lookup (info->ignore_hash, name, TRUE, TRUE) == NULL) einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); } diff -rNU3 dist.orig/ld/ldmain.h dist/ld/ldmain.h --- dist.orig/ld/ldmain.h 2012-07-13 15:20:26.000000000 +0200 +++ dist/ld/ldmain.h 2015-10-18 13:11:17.000000000 +0200 @@ -41,6 +41,7 @@ extern void add_ysym (const char *); extern void add_wrap (const char *); +extern void add_ignoresym (const char *); extern void add_keepsyms_file (const char *); #endif diff -rNU3 dist.orig/ld/lexsup.c dist/ld/lexsup.c --- dist.orig/ld/lexsup.c 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/lexsup.c 2015-10-18 13:11:17.000000000 +0200 @@ -398,7 +398,7 @@ ONE_DASH }, { {"shared", no_argument, NULL, OPTION_SHARED}, '\0', NULL, N_("Create a shared library"), ONE_DASH }, - { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */ + { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD, NetBSD. */ '\0', NULL, NULL, ONE_DASH }, { {"pie", no_argument, NULL, OPTION_PIE}, '\0', NULL, N_("Create a position independent executable"), ONE_DASH }, @@ -496,8 +496,14 @@ { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE}, '\0', NULL, N_("Include all objects from following archives"), TWO_DASHES }, + { {"Bforcearchive", no_argument, NULL, OPTION_WHOLE_ARCHIVE}, + '\0', NULL, NULL, TWO_DASHES }, /* NetBSD. */ { {"wrap", required_argument, NULL, OPTION_WRAP}, '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, + { {"ignore-unresolved-symbol", required_argument, NULL, + OPTION_IGNORE_UNRESOLVED_SYMBOL}, + '\0', N_("SYMBOL"), + N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES }, }; #define OPTION_COUNT ARRAY_SIZE (ld_options) @@ -1344,6 +1350,9 @@ case OPTION_WRAP: add_wrap (optarg); break; + case OPTION_IGNORE_UNRESOLVED_SYMBOL: + add_ignoresym (optarg); + break; case OPTION_DISCARD_NONE: link_info.discard = discard_none; break; diff -rNU3 dist.orig/ld/scripttempl/elf.sc dist/ld/scripttempl/elf.sc --- dist.orig/ld/scripttempl/elf.sc 2013-03-25 09:06:23.000000000 +0100 +++ dist/ld/scripttempl/elf.sc 2015-10-18 13:11:17.000000000 +0200 @@ -94,6 +94,8 @@ # # Each of these can also have corresponding .rel.* and .rela.* sections. +test -z "$TEXT_START_SYMBOLS" && TEXT_START_SYMBOLS="PROVIDE_HIDDEN (__eprol = .);" +test -z "$ENTRY" && ENTRY=_start if test -n "$NOP"; then FILL="=$NOP" else @@ -471,11 +473,12 @@ .text ${RELOCATING-0} : { ${RELOCATING+${TEXT_START_SYMBOLS}} + *(.text) ${RELOCATING+*(.text.unlikely .text.*_unlikely)} ${RELOCATING+*(.text.exit .text.exit.*)} ${RELOCATING+*(.text.startup .text.startup.*)} ${RELOCATING+*(.text.hot .text.hot.*)} - *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*}) + *(.stub${RELOCATING+ .text.* .gnu.linkonce.t.*}) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) ${RELOCATING+${OTHER_TEXT_SECTIONS}} diff -rNU3 dist.orig/ld/scripttempl/sh.sc dist/ld/scripttempl/sh.sc --- dist.orig/ld/scripttempl/sh.sc 2002-09-25 19:06:09.000000000 +0200 +++ dist/ld/scripttempl/sh.sc 2015-10-18 13:11:17.000000000 +0200 @@ -6,16 +6,13 @@ ___dtors = . ; *(.dtors) ___dtors_end = . ; - } > ram" + }" + cat < ram} + } ${CONSTRUCTING+${TORS}} - .data : + .data ${RELOCATING+ ALIGN(${TARGET_PAGE_SIZE})} : { *(.data) ${RELOCATING+*(.gcc_exc*)} @@ -35,19 +32,19 @@ ${RELOCATING+___EH_FRAME_END__ = . ;} ${RELOCATING+LONG(0);} ${RELOCATING+ _edata = . ; } - } ${RELOCATING+ > ram} - .bss : + } + .bss ${RELOCATING+ ALIGN(${TARGET_PAGE_SIZE})} : { ${RELOCATING+ _bss_start = . ; } *(.bss) *(COMMON) ${RELOCATING+ _end = . ; } - } ${RELOCATING+ > ram} - .stack ${RELOCATING+ 0x30000 } : + } + .stack : { ${RELOCATING+ _stack = . ; } *(.stack) - } ${RELOCATING+ > ram} + } .stab 0 ${RELOCATING+(NOLOAD)} : { *(.stab) diff -rNU3 dist.orig/libiberty/floatformat.c dist/libiberty/floatformat.c --- dist.orig/libiberty/floatformat.c 2011-01-03 22:05:58.000000000 +0100 +++ dist/libiberty/floatformat.c 2015-10-18 13:11:19.000000000 +0200 @@ -489,7 +489,11 @@ if (nan) dto = NAN; else +#ifdef __vax__ + dto = HUGE_VAL; +#else dto = INFINITY; +#endif if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) dto = -dto; diff -rNU3 dist.orig/libiberty/make-temp-file.c dist/libiberty/make-temp-file.c --- dist.orig/libiberty/make-temp-file.c 2011-01-03 22:05:58.000000000 +0100 +++ dist/libiberty/make-temp-file.c 2015-10-18 13:11:19.000000000 +0200 @@ -130,10 +130,10 @@ base = try_dir (P_tmpdir, base); #endif - /* Try /var/tmp, /usr/tmp, then /tmp. */ + /* Try /tmp, /var/tmp, then /usr/tmp. */ + base = try_dir (tmp, base); base = try_dir (vartmp, base); base = try_dir (usrtmp, base); - base = try_dir (tmp, base); /* If all else fails, use the current directory! */ if (base == 0) diff -rNU3 dist.orig/libiberty/objalloc.c dist/libiberty/objalloc.c --- dist.orig/libiberty/objalloc.c 2005-07-22 05:26:05.000000000 +0200 +++ dist/libiberty/objalloc.c 2015-10-18 13:11:19.000000000 +0200 @@ -1,5 +1,5 @@ /* objalloc.c -- routines to allocate memory for objects - Copyright 1997 Free Software Foundation, Inc. + Copyright 1997-2012 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Solutions. This program is free software; you can redistribute it and/or modify it @@ -112,8 +112,10 @@ /* Allocate space from an objalloc structure. */ PTR -_objalloc_alloc (struct objalloc *o, unsigned long len) +_objalloc_alloc (struct objalloc *o, unsigned long original_len) { + unsigned long len = original_len; + /* We avoid confusion from zero sized objects by always allocating at least 1 byte. */ if (len == 0) @@ -121,6 +123,11 @@ len = (len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); + /* Check for overflow in the alignment operation above and the + malloc argument below. */ + if (len + CHUNK_HEADER_SIZE < original_len) + return NULL; + if (len <= o->current_space) { o->current_ptr += len; diff -rNU3 dist.orig/libiberty/strerror.c dist/libiberty/strerror.c --- dist.orig/libiberty/strerror.c 2005-03-28 04:09:01.000000000 +0200 +++ dist/libiberty/strerror.c 2015-10-18 13:11:19.000000000 +0200 @@ -347,7 +347,7 @@ ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), #endif #if defined (ENOPROTOOPT) - ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), + ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol option not available"), #endif #if defined (EPROTONOSUPPORT) ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), diff -rNU3 dist.orig/opcodes/Makefile.am dist/opcodes/Makefile.am --- dist.orig/opcodes/Makefile.am 2012-09-04 16:21:06.000000000 +0200 +++ dist/opcodes/Makefile.am 2015-10-18 13:11:20.000000000 +0200 @@ -62,7 +62,7 @@ mep-desc.h mep-opc.h \ microblaze-opc.h \ mt-desc.h mt-opc.h \ - openrisc-desc.h openrisc-opc.h \ + or1k-desc.h or1k-opc.h \ score-opc.h \ sh-opc.h \ sh64-opc.h \ @@ -188,13 +188,11 @@ mt-ibld.c \ mt-opc.c \ ns32k-dis.c \ - openrisc-asm.c \ - openrisc-desc.c \ - openrisc-dis.c \ - openrisc-ibld.c \ - openrisc-opc.c \ - or32-dis.c \ - or32-opc.c \ + or1k-asm.c \ + or1k-desc.c \ + or1k-dis.c \ + or1k-ibld.c \ + or1k-opc.c \ pdp11-dis.c \ pdp11-opc.c \ pj-dis.c \ @@ -332,7 +330,7 @@ CLEANFILES = \ stamp-epiphany stamp-fr30 stamp-frv stamp-ip2k stamp-iq2000 stamp-lm32 \ stamp-m32c stamp-m32r stamp-mep stamp-mt \ - stamp-openrisc stamp-xc16x stamp-xstormy16 \ + stamp-or1k stamp-xc16x stamp-xstormy16 \ libopcodes.a stamp-lib @@ -348,7 +346,7 @@ $(CGENDIR)/opc-opinst.scm \ cgen-asm.in cgen-dis.in cgen-ibld.in -CGEN_CPUS = epiphany fr30 frv ip2k iq2000 lm32 m32c m32r mep mt openrisc xc16x xstormy16 +CGEN_CPUS = epiphany fr30 frv ip2k iq2000 lm32 m32c m32r mep mt or1k xc16x xstormy16 if CGEN_MAINT EPIPHANY_DEPS = stamp-epiphany @@ -361,7 +359,7 @@ M32R_DEPS = stamp-m32r MEP_DEPS = stamp-mep MT_DEPS = stamp-mt -OPENRISC_DEPS = stamp-openrisc +OR1K_DEPS = stamp-or1k XC16X_DEPS = stamp-xc16x XSTORMY16_DEPS = stamp-xstormy16 else @@ -375,7 +373,7 @@ M32R_DEPS = MEP_DEPS = MT_DEPS = -OPENRISC_DEPS = +OR1K_DEPS = XC16X_DEPS = XSTORMY16_DEPS = endif @@ -469,11 +467,11 @@ archfile=$(CPUDIR)/mt.cpu \ opcfile=$(CPUDIR)/mt.opc extrafiles= -$(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(srcdir)/openrisc-opc.c $(srcdir)/openrisc-ibld.c $(srcdir)/openrisc-asm.c $(srcdir)/openrisc-dis.c: $(OPENRISC_DEPS) +$(srcdir)/or1k-desc.h $(srcdir)/or1k-desc.c $(srcdir)/or1k-opc.h $(srcdir)/or1k-opc.c $(srcdir)/or1k-ibld.c $(srcdir)/or1k-opinst.c $(srcdir)/or1k-asm.c $(srcdir)/or1k-dis.c: $(OR1K_DEPS) @true -stamp-openrisc: $(CGENDEPS) $(CPUDIR)/openrisc.cpu $(CPUDIR)/openrisc.opc - $(MAKE) run-cgen arch=openrisc prefix=openrisc options= \ - archfile=$(CPUDIR)/openrisc.cpu opcfile=$(CPUDIR)/openrisc.opc extrafiles= +stamp-or1k: $(CGENDEPS) $(CPUDIR)/or1k.cpu $(CPUDIR)/or1k.opc $(CPUDIR)/or1kcommon.cpu $(CPUDIR)/or1korbis.cpu $(CPUDIR)/or1korfpx.cpu + $(MAKE) run-cgen arch=or1k prefix=or1k options=opinst \ + archfile=$(CPUDIR)/or1k.cpu opcfile=$(CPUDIR)/or1k.opc extrafiles=opinst $(srcdir)/xc16x-desc.h $(srcdir)/xc16x-desc.c $(srcdir)/xc16x-opc.h $(srcdir)/xc16x-opc.c $(srcdir)/xc16x-ibld.c $(srcdir)/xc16x-asm.c $(srcdir)/xc16x-dis.c: $(XC16X_DEPS) @true diff -rNU3 dist.orig/opcodes/Makefile.in dist/opcodes/Makefile.in --- dist.orig/opcodes/Makefile.in 2012-09-04 16:21:06.000000000 +0200 +++ dist/opcodes/Makefile.in 2015-10-18 13:11:20.000000000 +0200 @@ -459,13 +459,11 @@ mt-ibld.c \ mt-opc.c \ ns32k-dis.c \ - openrisc-asm.c \ - openrisc-desc.c \ - openrisc-dis.c \ - openrisc-ibld.c \ - openrisc-opc.c \ - or32-dis.c \ - or32-opc.c \ + or1k-asm.c \ + or1k-desc.c \ + or1k-dis.c \ + or1k-ibld.c \ + or1k-opc.c \ pdp11-dis.c \ pdp11-opc.c \ pj-dis.c \ @@ -572,7 +570,7 @@ CLEANFILES = \ stamp-epiphany stamp-fr30 stamp-frv stamp-ip2k stamp-iq2000 stamp-lm32 \ stamp-m32c stamp-m32r stamp-mep stamp-mt \ - stamp-openrisc stamp-xc16x stamp-xstormy16 \ + stamp-or1k stamp-xc16x stamp-xstormy16 \ libopcodes.a stamp-lib CGENDIR = @cgendir@ @@ -586,7 +584,7 @@ $(CGENDIR)/opc-opinst.scm \ cgen-asm.in cgen-dis.in cgen-ibld.in -CGEN_CPUS = epiphany fr30 frv ip2k iq2000 lm32 m32c m32r mep mt openrisc xc16x xstormy16 +CGEN_CPUS = epiphany fr30 frv ip2k iq2000 lm32 m32c m32r mep mt or1k xc16x xstormy16 @CGEN_MAINT_FALSE@EPIPHANY_DEPS = @CGEN_MAINT_TRUE@EPIPHANY_DEPS = stamp-epiphany @CGEN_MAINT_FALSE@FR30_DEPS = @@ -607,8 +605,8 @@ @CGEN_MAINT_TRUE@MEP_DEPS = stamp-mep @CGEN_MAINT_FALSE@MT_DEPS = @CGEN_MAINT_TRUE@MT_DEPS = stamp-mt -@CGEN_MAINT_FALSE@OPENRISC_DEPS = -@CGEN_MAINT_TRUE@OPENRISC_DEPS = stamp-openrisc +@CGEN_MAINT_FALSE@OR1K_DEPS = +@CGEN_MAINT_TRUE@OR1K_DEPS = stamp-or1k @CGEN_MAINT_FALSE@XC16X_DEPS = @CGEN_MAINT_TRUE@XC16X_DEPS = stamp-xc16x @CGEN_MAINT_FALSE@XSTORMY16_DEPS = @@ -855,13 +853,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mt-ibld.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mt-opc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ns32k-dis.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openrisc-asm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openrisc-desc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openrisc-dis.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openrisc-ibld.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openrisc-opc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or32-dis.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or32-opc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-asm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-desc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-dis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-ibld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-opc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or1k-opinst.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11-dis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11-opc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj-dis.Plo@am__quote@ @@ -1340,11 +1337,11 @@ archfile=$(CPUDIR)/mt.cpu \ opcfile=$(CPUDIR)/mt.opc extrafiles= -$(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(srcdir)/openrisc-opc.c $(srcdir)/openrisc-ibld.c $(srcdir)/openrisc-asm.c $(srcdir)/openrisc-dis.c: $(OPENRISC_DEPS) +$(srcdir)/or1k-desc.h $(srcdir)/or1k-desc.c $(srcdir)/or1k-opc.h $(srcdir)/or1k-opc.c $(srcdir)/or1k-ibld.c $(srcdir)/or1k-opinst.c $(srcdir)/or1k-asm.c $(srcdir)/or1k-dis.c: $(OR1K_DEPS) @true -stamp-openrisc: $(CGENDEPS) $(CPUDIR)/openrisc.cpu $(CPUDIR)/openrisc.opc - $(MAKE) run-cgen arch=openrisc prefix=openrisc options= \ - archfile=$(CPUDIR)/openrisc.cpu opcfile=$(CPUDIR)/openrisc.opc extrafiles= +stamp-or1k: $(CGENDEPS) $(CPUDIR)/or1k.cpu $(CPUDIR)/or1k.opc $(CPUDIR)/or1kcommon.cpu $(CPUDIR)/or1korbis.cpu $(CPUDIR)/or1korfpx.cpu + $(MAKE) run-cgen arch=or1k prefix=or1k options=opinst \ + archfile=$(CPUDIR)/or1k.cpu opcfile=$(CPUDIR)/or1k.opc extrafiles=opinst $(srcdir)/xc16x-desc.h $(srcdir)/xc16x-desc.c $(srcdir)/xc16x-opc.h $(srcdir)/xc16x-opc.c $(srcdir)/xc16x-ibld.c $(srcdir)/xc16x-asm.c $(srcdir)/xc16x-dis.c: $(XC16X_DEPS) @true diff -rNU3 dist.orig/opcodes/cgen.sh dist/opcodes/cgen.sh --- dist.orig/opcodes/cgen.sh 2009-06-14 18:36:56.000000000 +0200 +++ dist/opcodes/cgen.sh 2015-10-18 13:11:19.000000000 +0200 @@ -61,6 +61,7 @@ shift ; extrafiles=$9 rootdir=${srcdir}/.. +move_if_change="${CONFIG_SHELL:-/bin/sh} ${rootdir}/move-if-change" # $arch is $6, as passed on the command line. # $ARCH is the same argument but in all uppercase. diff -rNU3 dist.orig/opcodes/configure dist/opcodes/configure --- dist.orig/opcodes/configure 2012-09-04 16:21:07.000000000 +0200 +++ dist/opcodes/configure 2015-10-18 13:11:19.000000000 +0200 @@ -12532,13 +12532,13 @@ bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;; bfd_msp430_arch) ta="$ta msp430-dis.lo" ;; bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;; - bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;; - bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;; + bfd_or1k_arch) ta="$ta or1k-asm.lo or1k-desc.lo or1k-dis.lo or1k-ibld.lo or1k-opc.lo" using_cgen=yes ;; bfd_pdp11_arch) ta="$ta pdp11-dis.lo pdp11-opc.lo" ;; bfd_pj_arch) ta="$ta pj-dis.lo pj-opc.lo" ;; bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_powerpc_64_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_pyramid_arch) ;; + bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;; bfd_romp_arch) ;; bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";; @@ -12551,6 +12551,14 @@ # specified, as in sh3-elf, sh3b-linux-gnu, etc. # Include it just for ELF targets, since the SH5 bfd:s are ELF only. for t in $target $canon_targets; do + # For NetBSD we do NOT want SH5 support unless sh5 or sh64 + # is specified + case $t in + sh5*-* | sh64*-*) # let the case below handle it + ;; + sh*-*-netbsd* | sh*l*-*-netbsd*) + continue ;; + esac case $t in all | sh5*-* | sh64*-* | sh-*-*elf* | shl*-*-*elf* | \ sh-*-linux* | shl-*-linux*) diff -rNU3 dist.orig/opcodes/configure.in dist/opcodes/configure.in --- dist.orig/opcodes/configure.in 2012-11-05 17:29:08.000000000 +0100 +++ dist/opcodes/configure.in 2015-10-18 13:11:19.000000000 +0200 @@ -277,13 +277,13 @@ bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;; bfd_msp430_arch) ta="$ta msp430-dis.lo" ;; bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;; - bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;; - bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;; + bfd_or1k_arch) ta="$ta or1k-asm.lo or1k-desc.lo or1k-dis.lo or1k-ibld.lo or1k-opc.lo" using_cgen=yes ;; bfd_pdp11_arch) ta="$ta pdp11-dis.lo pdp11-opc.lo" ;; bfd_pj_arch) ta="$ta pj-dis.lo pj-opc.lo" ;; bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_powerpc_64_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_pyramid_arch) ;; + bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;; bfd_romp_arch) ;; bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;; bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";; @@ -296,6 +296,14 @@ # specified, as in sh3-elf, sh3b-linux-gnu, etc. # Include it just for ELF targets, since the SH5 bfd:s are ELF only. for t in $target $canon_targets; do + # For NetBSD we do NOT want SH5 support unless sh5 or sh64 + # is specified + case $t in + sh5*-* | sh64*-*) # let the case below handle it + ;; + sh*-*-netbsd* | sh*l*-*-netbsd*) + continue ;; + esac case $t in all | sh5*-* | sh64*-* | sh-*-*elf* | shl*-*-*elf* | \ sh-*-linux* | shl-*-linux*) diff -rNU3 dist.orig/opcodes/disassemble.c dist/opcodes/disassemble.c --- dist.orig/opcodes/disassemble.c 2012-09-04 14:53:50.000000000 +0200 +++ dist/opcodes/disassemble.c 2015-10-18 13:11:19.000000000 +0200 @@ -67,11 +67,11 @@ #define ARCH_mt #define ARCH_msp430 #define ARCH_ns32k -#define ARCH_openrisc -#define ARCH_or32 +#define ARCH_or1k #define ARCH_pdp11 #define ARCH_pj #define ARCH_powerpc +#define ARCH_riscv #define ARCH_rs6000 #define ARCH_rl78 #define ARCH_rx @@ -332,17 +332,9 @@ disassemble = print_insn_mn10300; break; #endif -#ifdef ARCH_openrisc - case bfd_arch_openrisc: - disassemble = print_insn_openrisc; - break; -#endif -#ifdef ARCH_or32 - case bfd_arch_or32: - if (bfd_big_endian (abfd)) - disassemble = print_insn_big_or32; - else - disassemble = print_insn_little_or32; +#ifdef ARCH_or1k + case bfd_arch_or1k: + disassemble = print_insn_or1k; break; #endif #ifdef ARCH_pdp11 @@ -363,6 +355,11 @@ disassemble = print_insn_little_powerpc; break; #endif +#ifdef ARCH_riscv + case bfd_arch_riscv: + disassemble = print_insn_riscv; + break; +#endif #ifdef ARCH_rs6000 case bfd_arch_rs6000: if (bfd_get_mach (abfd) == bfd_mach_ppc_620) diff -rNU3 dist.orig/opcodes/mips-opc.c dist/opcodes/mips-opc.c --- dist.orig/opcodes/mips-opc.c 2012-09-04 16:21:10.000000000 +0200 +++ dist/opcodes/mips-opc.c 2015-10-18 13:11:20.000000000 +0200 @@ -791,10 +791,12 @@ {"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, {"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 }, {"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC }, +{"jr", "s", 0, (int) M_JR_S, INSN_MACRO, 0, I1 }, {"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with the same hazard barrier effect. */ {"jr.hb", "s", 0x00000408, 0xfc1fffff, UBD|RD_s, 0, I32 }, +{"j", "s", 0, (int) M_J_S, INSN_MACRO, 0, I1 }, {"j", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr */ /* SVR4 PIC code requires special handling for j, so it must be a macro. */ @@ -803,7 +805,9 @@ assembler, but will never match user input (because the line above will match first). */ {"j", "a", 0x08000000, 0xfc000000, UBD, 0, I1 }, +{"jalr", "s", 0, (int) M_JALR_S, INSN_MACRO, 0, I1 }, {"jalr", "s", 0x0000f809, 0xfc1fffff, UBD|RD_s|WR_d, 0, I1 }, +{"jalr", "d,s", 0, (int) M_JALR_DS, INSN_MACRO, 0, I1 }, {"jalr", "d,s", 0x00000009, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I1 }, /* jalr.hb is officially MIPS{32,64}R2, but it works on R1 as jalr with the same hazard barrier effect. */ diff -rNU3 dist.orig/opcodes/openrisc-asm.c dist/opcodes/openrisc-asm.c --- dist.orig/opcodes/openrisc-asm.c 2010-06-27 06:07:55.000000000 +0200 +++ dist/opcodes/openrisc-asm.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,649 +0,0 @@ -/* Assembler interface for targets using CGEN. -*- C -*- - CGEN: Cpu tools GENerator - - THIS FILE IS MACHINE GENERATED WITH CGEN. - - the resultant file is machine generated, cgen-asm.in isn't - - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008, 2010 - Free Software Foundation, Inc. - - This file is part of libopcodes. - - 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. */ - - -/* ??? Eventually more and more of this stuff can go to cpu-independent files. - Keep that in mind. */ - -#include "sysdep.h" -#include -#include "ansidecl.h" -#include "bfd.h" -#include "symcat.h" -#include "openrisc-desc.h" -#include "openrisc-opc.h" -#include "opintl.h" -#include "xregex.h" -#include "libiberty.h" -#include "safe-ctype.h" - -#undef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#undef max -#define max(a,b) ((a) > (b) ? (a) : (b)) - -static const char * parse_insn_normal - (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); - -/* -- assembler routines inserted here. */ - -/* -- asm.c */ - -static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); - -#define CGEN_VERBOSE_ASSEMBLER_ERRORS - -long -openrisc_sign_extend_16bit (long value) -{ - return ((value & 0xffff) ^ 0x8000) - 0x8000; -} - -/* Handle hi(). */ - -static const char * -parse_hi16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) -{ - const char *errmsg; - enum cgen_parse_operand_result result_type; - unsigned long ret; - - if (**strp == '#') - ++*strp; - - if (strncasecmp (*strp, "hi(", 3) == 0) - { - bfd_vma value; - - *strp += 3; - errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, - & result_type, & value); - if (**strp != ')') - return MISSING_CLOSING_PARENTHESIS; - - ++*strp; - if (errmsg == NULL - && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) - value >>= 16; - ret = value; - } - else - { - if (**strp == '-') - { - long value; - - errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); - ret = value; - } - else - { - unsigned long value; - - errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); - ret = value; - } - } - - *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; - return errmsg; -} - -/* Handle lo(). */ - -static const char * -parse_lo16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) -{ - const char *errmsg; - enum cgen_parse_operand_result result_type; - unsigned long ret; - - if (**strp == '#') - ++*strp; - - if (strncasecmp (*strp, "lo(", 3) == 0) - { - bfd_vma value; - - *strp += 3; - errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, - & result_type, & value); - if (**strp != ')') - return MISSING_CLOSING_PARENTHESIS; - - ++*strp; - ret = value; - } - else - { - if (**strp == '-') - { - long value; - - errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); - ret = value; - } - else - { - unsigned long value; - - errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); - ret = value; - } - } - - *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; - return errmsg; -} - -/* -- */ - -const char * openrisc_cgen_parse_operand - (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); - -/* Main entry point for operand parsing. - - This function is basically just a big switch statement. Earlier versions - used tables to look up the function to use, but - - if the table contains both assembler and disassembler functions then - the disassembler contains much of the assembler and vice-versa, - - there's a lot of inlining possibilities as things grow, - - using a switch statement avoids the function call overhead. - - This function could be moved into `parse_insn_normal', but keeping it - separate makes clear the interface between `parse_insn_normal' and each of - the handlers. */ - -const char * -openrisc_cgen_parse_operand (CGEN_CPU_DESC cd, - int opindex, - const char ** strp, - CGEN_FIELDS * fields) -{ - const char * errmsg = NULL; - /* Used by scalar operands that still need to be parsed. */ - long junk ATTRIBUTE_UNUSED; - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - { - bfd_vma value = 0; - errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_ABS_26, 0, NULL, & value); - fields->f_abs26 = value; - } - break; - case OPENRISC_OPERAND_DISP_26 : - { - bfd_vma value = 0; - errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_DISP_26, 0, NULL, & value); - fields->f_disp26 = value; - } - break; - case OPENRISC_OPERAND_HI16 : - errmsg = parse_hi16 (cd, strp, OPENRISC_OPERAND_HI16, (long *) (& fields->f_simm16)); - break; - case OPENRISC_OPERAND_LO16 : - errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_LO16, (long *) (& fields->f_lo16)); - break; - case OPENRISC_OPERAND_OP_F_23 : - errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_23, (unsigned long *) (& fields->f_op4)); - break; - case OPENRISC_OPERAND_OP_F_3 : - errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_3, (unsigned long *) (& fields->f_op5)); - break; - case OPENRISC_OPERAND_RA : - errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r2); - break; - case OPENRISC_OPERAND_RB : - errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r3); - break; - case OPENRISC_OPERAND_RD : - errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r1); - break; - case OPENRISC_OPERAND_SIMM_16 : - errmsg = cgen_parse_signed_integer (cd, strp, OPENRISC_OPERAND_SIMM_16, (long *) (& fields->f_simm16)); - break; - case OPENRISC_OPERAND_UI16NC : - errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_UI16NC, (long *) (& fields->f_i16nc)); - break; - case OPENRISC_OPERAND_UIMM_16 : - errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_16, (unsigned long *) (& fields->f_uimm16)); - break; - case OPENRISC_OPERAND_UIMM_5 : - errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_5, (unsigned long *) (& fields->f_uimm5)); - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); - abort (); - } - - return errmsg; -} - -cgen_parse_fn * const openrisc_cgen_parse_handlers[] = -{ - parse_insn_normal, -}; - -void -openrisc_cgen_init_asm (CGEN_CPU_DESC cd) -{ - openrisc_cgen_init_opcode_table (cd); - openrisc_cgen_init_ibld_table (cd); - cd->parse_handlers = & openrisc_cgen_parse_handlers[0]; - cd->parse_operand = openrisc_cgen_parse_operand; -#ifdef CGEN_ASM_INIT_HOOK -CGEN_ASM_INIT_HOOK -#endif -} - - - -/* Regex construction routine. - - This translates an opcode syntax string into a regex string, - by replacing any non-character syntax element (such as an - opcode) with the pattern '.*' - - It then compiles the regex and stores it in the opcode, for - later use by openrisc_cgen_assemble_insn - - Returns NULL for success, an error message for failure. */ - -char * -openrisc_cgen_build_insn_regex (CGEN_INSN *insn) -{ - CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); - const char *mnem = CGEN_INSN_MNEMONIC (insn); - char rxbuf[CGEN_MAX_RX_ELEMENTS]; - char *rx = rxbuf; - const CGEN_SYNTAX_CHAR_TYPE *syn; - int reg_err; - - syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); - - /* Mnemonics come first in the syntax string. */ - if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) - return _("missing mnemonic in syntax string"); - ++syn; - - /* Generate a case sensitive regular expression that emulates case - insensitive matching in the "C" locale. We cannot generate a case - insensitive regular expression because in Turkish locales, 'i' and 'I' - are not equal modulo case conversion. */ - - /* Copy the literal mnemonic out of the insn. */ - for (; *mnem; mnem++) - { - char c = *mnem; - - if (ISALPHA (c)) - { - *rx++ = '['; - *rx++ = TOLOWER (c); - *rx++ = TOUPPER (c); - *rx++ = ']'; - } - else - *rx++ = c; - } - - /* Copy any remaining literals from the syntax string into the rx. */ - for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) - { - if (CGEN_SYNTAX_CHAR_P (* syn)) - { - char c = CGEN_SYNTAX_CHAR (* syn); - - switch (c) - { - /* Escape any regex metacharacters in the syntax. */ - case '.': case '[': case '\\': - case '*': case '^': case '$': - -#ifdef CGEN_ESCAPE_EXTENDED_REGEX - case '?': case '{': case '}': - case '(': case ')': case '*': - case '|': case '+': case ']': -#endif - *rx++ = '\\'; - *rx++ = c; - break; - - default: - if (ISALPHA (c)) - { - *rx++ = '['; - *rx++ = TOLOWER (c); - *rx++ = TOUPPER (c); - *rx++ = ']'; - } - else - *rx++ = c; - break; - } - } - else - { - /* Replace non-syntax fields with globs. */ - *rx++ = '.'; - *rx++ = '*'; - } - } - - /* Trailing whitespace ok. */ - * rx++ = '['; - * rx++ = ' '; - * rx++ = '\t'; - * rx++ = ']'; - * rx++ = '*'; - - /* But anchor it after that. */ - * rx++ = '$'; - * rx = '\0'; - - CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); - reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); - - if (reg_err == 0) - return NULL; - else - { - static char msg[80]; - - regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); - regfree ((regex_t *) CGEN_INSN_RX (insn)); - free (CGEN_INSN_RX (insn)); - (CGEN_INSN_RX (insn)) = NULL; - return msg; - } -} - - -/* Default insn parser. - - The syntax string is scanned and operands are parsed and stored in FIELDS. - Relocs are queued as we go via other callbacks. - - ??? Note that this is currently an all-or-nothing parser. If we fail to - parse the instruction, we return 0 and the caller will start over from - the beginning. Backtracking will be necessary in parsing subexpressions, - but that can be handled there. Not handling backtracking here may get - expensive in the case of the m68k. Deal with later. - - Returns NULL for success, an error message for failure. */ - -static const char * -parse_insn_normal (CGEN_CPU_DESC cd, - const CGEN_INSN *insn, - const char **strp, - CGEN_FIELDS *fields) -{ - /* ??? Runtime added insns not handled yet. */ - const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); - const char *str = *strp; - const char *errmsg; - const char *p; - const CGEN_SYNTAX_CHAR_TYPE * syn; -#ifdef CGEN_MNEMONIC_OPERANDS - /* FIXME: wip */ - int past_opcode_p; -#endif - - /* For now we assume the mnemonic is first (there are no leading operands). - We can parse it without needing to set up operand parsing. - GAS's input scrubber will ensure mnemonics are lowercase, but we may - not be called from GAS. */ - p = CGEN_INSN_MNEMONIC (insn); - while (*p && TOLOWER (*p) == TOLOWER (*str)) - ++p, ++str; - - if (* p) - return _("unrecognized instruction"); - -#ifndef CGEN_MNEMONIC_OPERANDS - if (* str && ! ISSPACE (* str)) - return _("unrecognized instruction"); -#endif - - CGEN_INIT_PARSE (cd); - cgen_init_parse_operand (cd); -#ifdef CGEN_MNEMONIC_OPERANDS - past_opcode_p = 0; -#endif - - /* We don't check for (*str != '\0') here because we want to parse - any trailing fake arguments in the syntax string. */ - syn = CGEN_SYNTAX_STRING (syntax); - - /* Mnemonics come first for now, ensure valid string. */ - if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) - abort (); - - ++syn; - - while (* syn != 0) - { - /* Non operand chars must match exactly. */ - if (CGEN_SYNTAX_CHAR_P (* syn)) - { - /* FIXME: While we allow for non-GAS callers above, we assume the - first char after the mnemonic part is a space. */ - /* FIXME: We also take inappropriate advantage of the fact that - GAS's input scrubber will remove extraneous blanks. */ - if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) - { -#ifdef CGEN_MNEMONIC_OPERANDS - if (CGEN_SYNTAX_CHAR(* syn) == ' ') - past_opcode_p = 1; -#endif - ++ syn; - ++ str; - } - else if (*str) - { - /* Syntax char didn't match. Can't be this insn. */ - static char msg [80]; - - /* xgettext:c-format */ - sprintf (msg, _("syntax error (expected char `%c', found `%c')"), - CGEN_SYNTAX_CHAR(*syn), *str); - return msg; - } - else - { - /* Ran out of input. */ - static char msg [80]; - - /* xgettext:c-format */ - sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), - CGEN_SYNTAX_CHAR(*syn)); - return msg; - } - continue; - } - -#ifdef CGEN_MNEMONIC_OPERANDS - (void) past_opcode_p; -#endif - /* We have an operand of some sort. */ - errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); - if (errmsg) - return errmsg; - - /* Done with this operand, continue with next one. */ - ++ syn; - } - - /* If we're at the end of the syntax string, we're done. */ - if (* syn == 0) - { - /* FIXME: For the moment we assume a valid `str' can only contain - blanks now. IE: We needn't try again with a longer version of - the insn and it is assumed that longer versions of insns appear - before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ - while (ISSPACE (* str)) - ++ str; - - if (* str != '\0') - return _("junk at end of line"); /* FIXME: would like to include `str' */ - - return NULL; - } - - /* We couldn't parse it. */ - return _("unrecognized instruction"); -} - -/* Main entry point. - This routine is called for each instruction to be assembled. - STR points to the insn to be assembled. - We assume all necessary tables have been initialized. - The assembled instruction, less any fixups, is stored in BUF. - Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value - still needs to be converted to target byte order, otherwise BUF is an array - of bytes in target byte order. - The result is a pointer to the insn's entry in the opcode table, - or NULL if an error occured (an error message will have already been - printed). - - Note that when processing (non-alias) macro-insns, - this function recurses. - - ??? It's possible to make this cpu-independent. - One would have to deal with a few minor things. - At this point in time doing so would be more of a curiosity than useful - [for example this file isn't _that_ big], but keeping the possibility in - mind helps keep the design clean. */ - -const CGEN_INSN * -openrisc_cgen_assemble_insn (CGEN_CPU_DESC cd, - const char *str, - CGEN_FIELDS *fields, - CGEN_INSN_BYTES_PTR buf, - char **errmsg) -{ - const char *start; - CGEN_INSN_LIST *ilist; - const char *parse_errmsg = NULL; - const char *insert_errmsg = NULL; - int recognized_mnemonic = 0; - - /* Skip leading white space. */ - while (ISSPACE (* str)) - ++ str; - - /* The instructions are stored in hashed lists. - Get the first in the list. */ - ilist = CGEN_ASM_LOOKUP_INSN (cd, str); - - /* Keep looking until we find a match. */ - start = str; - for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) - { - const CGEN_INSN *insn = ilist->insn; - recognized_mnemonic = 1; - -#ifdef CGEN_VALIDATE_INSN_SUPPORTED - /* Not usually needed as unsupported opcodes - shouldn't be in the hash lists. */ - /* Is this insn supported by the selected cpu? */ - if (! openrisc_cgen_insn_supported (cd, insn)) - continue; -#endif - /* If the RELAXED attribute is set, this is an insn that shouldn't be - chosen immediately. Instead, it is used during assembler/linker - relaxation if possible. */ - if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) - continue; - - str = start; - - /* Skip this insn if str doesn't look right lexically. */ - if (CGEN_INSN_RX (insn) != NULL && - regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) - continue; - - /* Allow parse/insert handlers to obtain length of insn. */ - CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); - - parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); - if (parse_errmsg != NULL) - continue; - - /* ??? 0 is passed for `pc'. */ - insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, - (bfd_vma) 0); - if (insert_errmsg != NULL) - continue; - - /* It is up to the caller to actually output the insn and any - queued relocs. */ - return insn; - } - - { - static char errbuf[150]; - const char *tmp_errmsg; -#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS -#define be_verbose 1 -#else -#define be_verbose 0 -#endif - - if (be_verbose) - { - /* If requesting verbose error messages, use insert_errmsg. - Failing that, use parse_errmsg. */ - tmp_errmsg = (insert_errmsg ? insert_errmsg : - parse_errmsg ? parse_errmsg : - recognized_mnemonic ? - _("unrecognized form of instruction") : - _("unrecognized instruction")); - - if (strlen (start) > 50) - /* xgettext:c-format */ - sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); - else - /* xgettext:c-format */ - sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); - } - else - { - if (strlen (start) > 50) - /* xgettext:c-format */ - sprintf (errbuf, _("bad instruction `%.50s...'"), start); - else - /* xgettext:c-format */ - sprintf (errbuf, _("bad instruction `%.50s'"), start); - } - - *errmsg = errbuf; - return NULL; - } -} diff -rNU3 dist.orig/opcodes/openrisc-desc.c dist/opcodes/openrisc-desc.c --- dist.orig/opcodes/openrisc-desc.c 2010-02-12 04:25:49.000000000 +0100 +++ dist/opcodes/openrisc-desc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1018 +0,0 @@ -/* CPU data for openrisc. - -THIS FILE IS MACHINE GENERATED WITH CGEN. - -Copyright 1996-2010 Free Software Foundation, Inc. - -This file is part of the GNU Binutils and/or GDB, the GNU debugger. - - This file 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 "sysdep.h" -#include -#include -#include "ansidecl.h" -#include "bfd.h" -#include "symcat.h" -#include "openrisc-desc.h" -#include "openrisc-opc.h" -#include "opintl.h" -#include "libiberty.h" -#include "xregex.h" - -/* Attributes. */ - -static const CGEN_ATTR_ENTRY bool_attr[] = -{ - { "#f", 0 }, - { "#t", 1 }, - { 0, 0 } -}; - -static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED = -{ - { "base", MACH_BASE }, - { "openrisc", MACH_OPENRISC }, - { "or1300", MACH_OR1300 }, - { "max", MACH_MAX }, - { 0, 0 } -}; - -static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED = -{ - { "or32", ISA_OR32 }, - { "max", ISA_MAX }, - { 0, 0 } -}; - -static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] ATTRIBUTE_UNUSED = -{ - { "DATA_CACHE", HAS_CACHE_DATA_CACHE }, - { "INSN_CACHE", HAS_CACHE_INSN_CACHE }, - { 0, 0 } -}; - -const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] = -{ - { "MACH", & MACH_attr[0], & MACH_attr[0] }, - { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, - { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, - { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, - { "RESERVED", &bool_attr[0], &bool_attr[0] }, - { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, - { "SIGNED", &bool_attr[0], &bool_attr[0] }, - { 0, 0, 0 } -}; - -const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] = -{ - { "MACH", & MACH_attr[0], & MACH_attr[0] }, - { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, - { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, - { "PC", &bool_attr[0], &bool_attr[0] }, - { "PROFILE", &bool_attr[0], &bool_attr[0] }, - { 0, 0, 0 } -}; - -const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] = -{ - { "MACH", & MACH_attr[0], & MACH_attr[0] }, - { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, - { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, - { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, - { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, - { "SIGNED", &bool_attr[0], &bool_attr[0] }, - { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, - { "RELAX", &bool_attr[0], &bool_attr[0] }, - { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, - { 0, 0, 0 } -}; - -const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] = -{ - { "MACH", & MACH_attr[0], & MACH_attr[0] }, - { "ALIAS", &bool_attr[0], &bool_attr[0] }, - { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, - { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, - { "COND-CTI", &bool_attr[0], &bool_attr[0] }, - { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, - { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, - { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, - { "RELAXED", &bool_attr[0], &bool_attr[0] }, - { "NO-DIS", &bool_attr[0], &bool_attr[0] }, - { "PBB", &bool_attr[0], &bool_attr[0] }, - { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, - { 0, 0, 0 } -}; - -/* Instruction set variants. */ - -static const CGEN_ISA openrisc_cgen_isa_table[] = { - { "or32", 32, 32, 32, 32 }, - { 0, 0, 0, 0, 0 } -}; - -/* Machine variants. */ - -static const CGEN_MACH openrisc_cgen_mach_table[] = { - { "openrisc", "openrisc", MACH_OPENRISC, 0 }, - { "or1300", "openrisc:1300", MACH_OR1300, 0 }, - { 0, 0, 0, 0 } -}; - -static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] = -{ - { "r0", 0, {0, {{{0, 0}}}}, 0, 0 }, - { "r1", 1, {0, {{{0, 0}}}}, 0, 0 }, - { "r2", 2, {0, {{{0, 0}}}}, 0, 0 }, - { "r3", 3, {0, {{{0, 0}}}}, 0, 0 }, - { "r4", 4, {0, {{{0, 0}}}}, 0, 0 }, - { "r5", 5, {0, {{{0, 0}}}}, 0, 0 }, - { "r6", 6, {0, {{{0, 0}}}}, 0, 0 }, - { "r7", 7, {0, {{{0, 0}}}}, 0, 0 }, - { "r8", 8, {0, {{{0, 0}}}}, 0, 0 }, - { "r9", 9, {0, {{{0, 0}}}}, 0, 0 }, - { "r10", 10, {0, {{{0, 0}}}}, 0, 0 }, - { "r11", 11, {0, {{{0, 0}}}}, 0, 0 }, - { "r12", 12, {0, {{{0, 0}}}}, 0, 0 }, - { "r13", 13, {0, {{{0, 0}}}}, 0, 0 }, - { "r14", 14, {0, {{{0, 0}}}}, 0, 0 }, - { "r15", 15, {0, {{{0, 0}}}}, 0, 0 }, - { "r16", 16, {0, {{{0, 0}}}}, 0, 0 }, - { "r17", 17, {0, {{{0, 0}}}}, 0, 0 }, - { "r18", 18, {0, {{{0, 0}}}}, 0, 0 }, - { "r19", 19, {0, {{{0, 0}}}}, 0, 0 }, - { "r20", 20, {0, {{{0, 0}}}}, 0, 0 }, - { "r21", 21, {0, {{{0, 0}}}}, 0, 0 }, - { "r22", 22, {0, {{{0, 0}}}}, 0, 0 }, - { "r23", 23, {0, {{{0, 0}}}}, 0, 0 }, - { "r24", 24, {0, {{{0, 0}}}}, 0, 0 }, - { "r25", 25, {0, {{{0, 0}}}}, 0, 0 }, - { "r26", 26, {0, {{{0, 0}}}}, 0, 0 }, - { "r27", 27, {0, {{{0, 0}}}}, 0, 0 }, - { "r28", 28, {0, {{{0, 0}}}}, 0, 0 }, - { "r29", 29, {0, {{{0, 0}}}}, 0, 0 }, - { "r30", 30, {0, {{{0, 0}}}}, 0, 0 }, - { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }, - { "lr", 11, {0, {{{0, 0}}}}, 0, 0 }, - { "sp", 1, {0, {{{0, 0}}}}, 0, 0 }, - { "fp", 2, {0, {{{0, 0}}}}, 0, 0 } -}; - -CGEN_KEYWORD openrisc_cgen_opval_h_gr = -{ - & openrisc_cgen_opval_h_gr_entries[0], - 35, - 0, 0, 0, 0, "" -}; - - -/* The hardware table. */ - -#define A(a) (1 << CGEN_HW_##a) - -const CGEN_HW_ENTRY openrisc_cgen_hw_table[] = -{ - { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<name) - { - if (strcmp (name, table->bfd_name) == 0) - return table; - ++table; - } - abort (); -} - -/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */ - -static void -build_hw_table (CGEN_CPU_TABLE *cd) -{ - int i; - int machs = cd->machs; - const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0]; - /* MAX_HW is only an upper bound on the number of selected entries. - However each entry is indexed by it's enum so there can be holes in - the table. */ - const CGEN_HW_ENTRY **selected = - (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); - - cd->hw_table.init_entries = init; - cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); - memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); - /* ??? For now we just use machs to determine which ones we want. */ - for (i = 0; init[i].name != NULL; ++i) - if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) - & machs) - selected[init[i].type] = &init[i]; - cd->hw_table.entries = selected; - cd->hw_table.num_entries = MAX_HW; -} - -/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */ - -static void -build_ifield_table (CGEN_CPU_TABLE *cd) -{ - cd->ifld_table = & openrisc_cgen_ifld_table[0]; -} - -/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */ - -static void -build_operand_table (CGEN_CPU_TABLE *cd) -{ - int i; - int machs = cd->machs; - const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0]; - /* MAX_OPERANDS is only an upper bound on the number of selected entries. - However each entry is indexed by it's enum so there can be holes in - the table. */ - const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected)); - - cd->operand_table.init_entries = init; - cd->operand_table.entry_size = sizeof (CGEN_OPERAND); - memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); - /* ??? For now we just use mach to determine which ones we want. */ - for (i = 0; init[i].name != NULL; ++i) - if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) - & machs) - selected[init[i].type] = &init[i]; - cd->operand_table.entries = selected; - cd->operand_table.num_entries = MAX_OPERANDS; -} - -/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. - ??? This could leave out insns not supported by the specified mach/isa, - but that would cause errors like "foo only supported by bar" to become - "unknown insn", so for now we include all insns and require the app to - do the checking later. - ??? On the other hand, parsing of such insns may require their hardware or - operand elements to be in the table [which they mightn't be]. */ - -static void -build_insn_table (CGEN_CPU_TABLE *cd) -{ - int i; - const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0]; - CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); - - memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); - for (i = 0; i < MAX_INSNS; ++i) - insns[i].base = &ib[i]; - cd->insn_table.init_entries = insns; - cd->insn_table.entry_size = sizeof (CGEN_IBASE); - cd->insn_table.num_init_entries = MAX_INSNS; -} - -/* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */ - -static void -openrisc_cgen_rebuild_tables (CGEN_CPU_TABLE *cd) -{ - int i; - CGEN_BITSET *isas = cd->isas; - unsigned int machs = cd->machs; - - cd->int_insn_p = CGEN_INT_INSN_P; - - /* Data derived from the isa spec. */ -#define UNSET (CGEN_SIZE_UNKNOWN + 1) - cd->default_insn_bitsize = UNSET; - cd->base_insn_bitsize = UNSET; - cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */ - cd->max_insn_bitsize = 0; - for (i = 0; i < MAX_ISAS; ++i) - if (cgen_bitset_contains (isas, i)) - { - const CGEN_ISA *isa = & openrisc_cgen_isa_table[i]; - - /* Default insn sizes of all selected isas must be - equal or we set the result to 0, meaning "unknown". */ - if (cd->default_insn_bitsize == UNSET) - cd->default_insn_bitsize = isa->default_insn_bitsize; - else if (isa->default_insn_bitsize == cd->default_insn_bitsize) - ; /* This is ok. */ - else - cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; - - /* Base insn sizes of all selected isas must be equal - or we set the result to 0, meaning "unknown". */ - if (cd->base_insn_bitsize == UNSET) - cd->base_insn_bitsize = isa->base_insn_bitsize; - else if (isa->base_insn_bitsize == cd->base_insn_bitsize) - ; /* This is ok. */ - else - cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; - - /* Set min,max insn sizes. */ - if (isa->min_insn_bitsize < cd->min_insn_bitsize) - cd->min_insn_bitsize = isa->min_insn_bitsize; - if (isa->max_insn_bitsize > cd->max_insn_bitsize) - cd->max_insn_bitsize = isa->max_insn_bitsize; - } - - /* Data derived from the mach spec. */ - for (i = 0; i < MAX_MACHS; ++i) - if (((1 << i) & machs) != 0) - { - const CGEN_MACH *mach = & openrisc_cgen_mach_table[i]; - - if (mach->insn_chunk_bitsize != 0) - { - if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) - { - fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n", - cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); - abort (); - } - - cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; - } - } - - /* Determine which hw elements are used by MACH. */ - build_hw_table (cd); - - /* Build the ifield table. */ - build_ifield_table (cd); - - /* Determine which operands are used by MACH/ISA. */ - build_operand_table (cd); - - /* Build the instruction table. */ - build_insn_table (cd); -} - -/* Initialize a cpu table and return a descriptor. - It's much like opening a file, and must be the first function called. - The arguments are a set of (type/value) pairs, terminated with - CGEN_CPU_OPEN_END. - - Currently supported values: - CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr - CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr - CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name - CGEN_CPU_OPEN_ENDIAN: specify endian choice - CGEN_CPU_OPEN_END: terminates arguments - - ??? Simultaneous multiple isas might not make sense, but it's not (yet) - precluded. */ - -CGEN_CPU_DESC -openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) -{ - CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); - static int init_p; - CGEN_BITSET *isas = 0; /* 0 = "unspecified" */ - unsigned int machs = 0; /* 0 = "unspecified" */ - enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; - va_list ap; - - if (! init_p) - { - init_tables (); - init_p = 1; - } - - memset (cd, 0, sizeof (*cd)); - - va_start (ap, arg_type); - while (arg_type != CGEN_CPU_OPEN_END) - { - switch (arg_type) - { - case CGEN_CPU_OPEN_ISAS : - isas = va_arg (ap, CGEN_BITSET *); - break; - case CGEN_CPU_OPEN_MACHS : - machs = va_arg (ap, unsigned int); - break; - case CGEN_CPU_OPEN_BFDMACH : - { - const char *name = va_arg (ap, const char *); - const CGEN_MACH *mach = - lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name); - - machs |= 1 << mach->num; - break; - } - case CGEN_CPU_OPEN_ENDIAN : - endian = va_arg (ap, enum cgen_endian); - break; - default : - fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n", - arg_type); - abort (); /* ??? return NULL? */ - } - arg_type = va_arg (ap, enum cgen_cpu_open_arg); - } - va_end (ap); - - /* Mach unspecified means "all". */ - if (machs == 0) - machs = (1 << MAX_MACHS) - 1; - /* Base mach is always selected. */ - machs |= 1; - if (endian == CGEN_ENDIAN_UNKNOWN) - { - /* ??? If target has only one, could have a default. */ - fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n"); - abort (); - } - - cd->isas = cgen_bitset_copy (isas); - cd->machs = machs; - cd->endian = endian; - /* FIXME: for the sparc case we can determine insn-endianness statically. - The worry here is where both data and insn endian can be independently - chosen, in which case this function will need another argument. - Actually, will want to allow for more arguments in the future anyway. */ - cd->insn_endian = endian; - - /* Table (re)builder. */ - cd->rebuild_tables = openrisc_cgen_rebuild_tables; - openrisc_cgen_rebuild_tables (cd); - - /* Default to not allowing signed overflow. */ - cd->signed_overflow_ok_p = 0; - - return (CGEN_CPU_DESC) cd; -} - -/* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. - MACH_NAME is the bfd name of the mach. */ - -CGEN_CPU_DESC -openrisc_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) -{ - return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, - CGEN_CPU_OPEN_ENDIAN, endian, - CGEN_CPU_OPEN_END); -} - -/* Close a cpu table. - ??? This can live in a machine independent file, but there's currently - no place to put this file (there's no libcgen). libopcodes is the wrong - place as some simulator ports use this but they don't use libopcodes. */ - -void -openrisc_cgen_cpu_close (CGEN_CPU_DESC cd) -{ - unsigned int i; - const CGEN_INSN *insns; - - if (cd->macro_insn_table.init_entries) - { - insns = cd->macro_insn_table.init_entries; - for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) - if (CGEN_INSN_RX ((insns))) - regfree (CGEN_INSN_RX (insns)); - } - - if (cd->insn_table.init_entries) - { - insns = cd->insn_table.init_entries; - for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) - if (CGEN_INSN_RX (insns)) - regfree (CGEN_INSN_RX (insns)); - } - - if (cd->macro_insn_table.init_entries) - free ((CGEN_INSN *) cd->macro_insn_table.init_entries); - - if (cd->insn_table.init_entries) - free ((CGEN_INSN *) cd->insn_table.init_entries); - - if (cd->hw_table.entries) - free ((CGEN_HW_ENTRY *) cd->hw_table.entries); - - if (cd->operand_table.entries) - free ((CGEN_HW_ENTRY *) cd->operand_table.entries); - - free (cd); -} - diff -rNU3 dist.orig/opcodes/openrisc-desc.h dist/opcodes/openrisc-desc.h --- dist.orig/opcodes/openrisc-desc.h 2010-10-09 08:50:23.000000000 +0200 +++ dist/opcodes/openrisc-desc.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,288 +0,0 @@ -/* CPU data header for openrisc. - -THIS FILE IS MACHINE GENERATED WITH CGEN. - -Copyright 1996-2010 Free Software Foundation, Inc. - -This file is part of the GNU Binutils and/or GDB, the GNU debugger. - - This file 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. - -*/ - -#ifndef OPENRISC_CPU_H -#define OPENRISC_CPU_H - -#define CGEN_ARCH openrisc - -/* Given symbol S, return openrisc_cgen_. */ -#define CGEN_SYM(s) openrisc##_cgen_##s - - -/* Selected cpu families. */ -#define HAVE_CPU_OPENRISCBF - -#define CGEN_INSN_LSB0_P 1 - -/* Minimum size of any insn (in bytes). */ -#define CGEN_MIN_INSN_SIZE 4 - -/* Maximum size of any insn (in bytes). */ -#define CGEN_MAX_INSN_SIZE 4 - -#define CGEN_INT_INSN_P 1 - -/* Maximum number of syntax elements in an instruction. */ -#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 14 - -/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands. - e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands - we can't hash on everything up to the space. */ -#define CGEN_MNEMONIC_OPERANDS - -/* Maximum number of fields in an instruction. */ -#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 9 - -/* Enums. */ - -/* Enum declaration for exception vectors. */ -typedef enum e_exception { - E_RESET, E_BUSERR, E_DPF, E_IPF - , E_EXTINT, E_ALIGN, E_ILLEGAL, E_PEINT - , E_DTLBMISS, E_ITLBMISS, E_RRANGE, E_SYSCALL - , E_BREAK, E_RESERVED -} E_EXCEPTION; - -/* Enum declaration for FIXME. */ -typedef enum insn_class { - OP1_0, OP1_1, OP1_2, OP1_3 -} INSN_CLASS; - -/* Enum declaration for FIXME. */ -typedef enum insn_sub { - OP2_0, OP2_1, OP2_2, OP2_3 - , OP2_4, OP2_5, OP2_6, OP2_7 - , OP2_8, OP2_9, OP2_10, OP2_11 - , OP2_12, OP2_13, OP2_14, OP2_15 -} INSN_SUB; - -/* Enum declaration for FIXME. */ -typedef enum insn_op3 { - OP3_0, OP3_1, OP3_2, OP3_3 -} INSN_OP3; - -/* Enum declaration for FIXME. */ -typedef enum insn_op4 { - OP4_0, OP4_1, OP4_2, OP4_3 - , OP4_4, OP4_5, OP4_6, OP4_7 -} INSN_OP4; - -/* Enum declaration for FIXME. */ -typedef enum insn_op5 { - OP5_0, OP5_1, OP5_2, OP5_3 - , OP5_4, OP5_5, OP5_6, OP5_7 - , OP5_8, OP5_9, OP5_10, OP5_11 - , OP5_12, OP5_13, OP5_14, OP5_15 - , OP5_16, OP5_17, OP5_18, OP5_19 - , OP5_20, OP5_21, OP5_22, OP5_23 - , OP5_24, OP5_25, OP5_26, OP5_27 - , OP5_28, OP5_29, OP5_30, OP5_31 -} INSN_OP5; - -/* Enum declaration for FIXME. */ -typedef enum insn_op6 { - OP6_0, OP6_1, OP6_2, OP6_3 - , OP6_4, OP6_5, OP6_6, OP6_7 -} INSN_OP6; - -/* Enum declaration for FIXME. */ -typedef enum insn_op7 { - OP7_0, OP7_1, OP7_2, OP7_3 - , OP7_4, OP7_5, OP7_6, OP7_7 - , OP7_8, OP7_9, OP7_10, OP7_11 - , OP7_12, OP7_13, OP7_14, OP7_15 -} INSN_OP7; - -/* Attributes. */ - -/* Enum declaration for machine type selection. */ -typedef enum mach_attr { - MACH_BASE, MACH_OPENRISC, MACH_OR1300, MACH_MAX -} MACH_ATTR; - -/* Enum declaration for instruction set selection. */ -typedef enum isa_attr { - ISA_OR32, ISA_MAX -} ISA_ATTR; - -/* Enum declaration for if this model has caches. */ -typedef enum has_cache_attr { - HAS_CACHE_DATA_CACHE, HAS_CACHE_INSN_CACHE -} HAS_CACHE_ATTR; - -/* Number of architecture variants. */ -#define MAX_ISAS 1 -#define MAX_MACHS ((int) MACH_MAX) - -/* Ifield support. */ - -/* Ifield attribute indices. */ - -/* Enum declaration for cgen_ifld attrs. */ -typedef enum cgen_ifld_attr { - CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED - , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31 - , CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS -} CGEN_IFLD_ATTR; - -/* Number of non-boolean elements in cgen_ifld_attr. */ -#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1) - -/* cgen_ifld attribute accessor macros. */ -#define CGEN_ATTR_CGEN_IFLD_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_IFLD_MACH-CGEN_IFLD_START_NBOOLS-1].nonbitset) -#define CGEN_ATTR_CGEN_IFLD_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_VIRTUAL)) != 0) -#define CGEN_ATTR_CGEN_IFLD_PCREL_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_PCREL_ADDR)) != 0) -#define CGEN_ATTR_CGEN_IFLD_ABS_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_ABS_ADDR)) != 0) -#define CGEN_ATTR_CGEN_IFLD_RESERVED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_RESERVED)) != 0) -#define CGEN_ATTR_CGEN_IFLD_SIGN_OPT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_SIGN_OPT)) != 0) -#define CGEN_ATTR_CGEN_IFLD_SIGNED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_SIGNED)) != 0) - -/* Enum declaration for openrisc ifield types. */ -typedef enum ifield_type { - OPENRISC_F_NIL, OPENRISC_F_ANYOF, OPENRISC_F_CLASS, OPENRISC_F_SUB - , OPENRISC_F_R1, OPENRISC_F_R2, OPENRISC_F_R3, OPENRISC_F_SIMM16 - , OPENRISC_F_UIMM16, OPENRISC_F_UIMM5, OPENRISC_F_HI16, OPENRISC_F_LO16 - , OPENRISC_F_OP1, OPENRISC_F_OP2, OPENRISC_F_OP3, OPENRISC_F_OP4 - , OPENRISC_F_OP5, OPENRISC_F_OP6, OPENRISC_F_OP7, OPENRISC_F_I16_1 - , OPENRISC_F_I16_2, OPENRISC_F_DISP26, OPENRISC_F_ABS26, OPENRISC_F_I16NC - , OPENRISC_F_F_15_8, OPENRISC_F_F_10_3, OPENRISC_F_F_4_1, OPENRISC_F_F_7_3 - , OPENRISC_F_F_10_7, OPENRISC_F_F_10_11, OPENRISC_F_MAX -} IFIELD_TYPE; - -#define MAX_IFLD ((int) OPENRISC_F_MAX) - -/* Hardware attribute indices. */ - -/* Enum declaration for cgen_hw attrs. */ -typedef enum cgen_hw_attr { - CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE - , CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS -} CGEN_HW_ATTR; - -/* Number of non-boolean elements in cgen_hw_attr. */ -#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1) - -/* cgen_hw attribute accessor macros. */ -#define CGEN_ATTR_CGEN_HW_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_HW_MACH-CGEN_HW_START_NBOOLS-1].nonbitset) -#define CGEN_ATTR_CGEN_HW_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_VIRTUAL)) != 0) -#define CGEN_ATTR_CGEN_HW_CACHE_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_CACHE_ADDR)) != 0) -#define CGEN_ATTR_CGEN_HW_PC_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_PC)) != 0) -#define CGEN_ATTR_CGEN_HW_PROFILE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_PROFILE)) != 0) - -/* Enum declaration for openrisc hardware types. */ -typedef enum cgen_hw_type { - HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR - , HW_H_IADDR, HW_H_PC, HW_H_GR, HW_H_SR - , HW_H_HI16, HW_H_LO16, HW_H_CBIT, HW_H_DELAY_INSN - , HW_MAX -} CGEN_HW_TYPE; - -#define MAX_HW ((int) HW_MAX) - -/* Operand attribute indices. */ - -/* Enum declaration for cgen_operand attrs. */ -typedef enum cgen_operand_attr { - CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT - , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY - , CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH, CGEN_OPERAND_END_NBOOLS -} CGEN_OPERAND_ATTR; - -/* Number of non-boolean elements in cgen_operand_attr. */ -#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1) - -/* cgen_operand attribute accessor macros. */ -#define CGEN_ATTR_CGEN_OPERAND_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_MACH-CGEN_OPERAND_START_NBOOLS-1].nonbitset) -#define CGEN_ATTR_CGEN_OPERAND_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_VIRTUAL)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_PCREL_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_PCREL_ADDR)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_ABS_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_ABS_ADDR)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_SIGN_OPT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SIGN_OPT)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_SIGNED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SIGNED)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_NEGATIVE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_NEGATIVE)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_RELAX_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_RELAX)) != 0) -#define CGEN_ATTR_CGEN_OPERAND_SEM_ONLY_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SEM_ONLY)) != 0) - -/* Enum declaration for openrisc operand types. */ -typedef enum cgen_operand_type { - OPENRISC_OPERAND_PC, OPENRISC_OPERAND_SR, OPENRISC_OPERAND_CBIT, OPENRISC_OPERAND_SIMM_16 - , OPENRISC_OPERAND_UIMM_16, OPENRISC_OPERAND_DISP_26, OPENRISC_OPERAND_ABS_26, OPENRISC_OPERAND_UIMM_5 - , OPENRISC_OPERAND_RD, OPENRISC_OPERAND_RA, OPENRISC_OPERAND_RB, OPENRISC_OPERAND_OP_F_23 - , OPENRISC_OPERAND_OP_F_3, OPENRISC_OPERAND_HI16, OPENRISC_OPERAND_LO16, OPENRISC_OPERAND_UI16NC - , OPENRISC_OPERAND_MAX -} CGEN_OPERAND_TYPE; - -/* Number of operands types. */ -#define MAX_OPERANDS 16 - -/* Maximum number of operands referenced by any insn. */ -#define MAX_OPERAND_INSTANCES 8 - -/* Insn attribute indices. */ - -/* Enum declaration for cgen_insn attrs. */ -typedef enum cgen_insn_attr { - CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI - , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAXED - , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_NOT_IN_DELAY_SLOT, CGEN_INSN_END_BOOLS - , CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_END_NBOOLS -} CGEN_INSN_ATTR; - -/* Number of non-boolean elements in cgen_insn_attr. */ -#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1) - -/* cgen_insn attribute accessor macros. */ -#define CGEN_ATTR_CGEN_INSN_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_MACH-CGEN_INSN_START_NBOOLS-1].nonbitset) -#define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_ALIAS)) != 0) -#define CGEN_ATTR_CGEN_INSN_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_VIRTUAL)) != 0) -#define CGEN_ATTR_CGEN_INSN_UNCOND_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_UNCOND_CTI)) != 0) -#define CGEN_ATTR_CGEN_INSN_COND_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_COND_CTI)) != 0) -#define CGEN_ATTR_CGEN_INSN_SKIP_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_SKIP_CTI)) != 0) -#define CGEN_ATTR_CGEN_INSN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_DELAY_SLOT)) != 0) -#define CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_RELAXABLE)) != 0) -#define CGEN_ATTR_CGEN_INSN_RELAXED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_RELAXED)) != 0) -#define CGEN_ATTR_CGEN_INSN_NO_DIS_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_NO_DIS)) != 0) -#define CGEN_ATTR_CGEN_INSN_PBB_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_PBB)) != 0) -#define CGEN_ATTR_CGEN_INSN_NOT_IN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_NOT_IN_DELAY_SLOT)) != 0) - -/* cgen.h uses things we just defined. */ -#include "opcode/cgen.h" - -extern const struct cgen_ifld openrisc_cgen_ifld_table[]; - -/* Attributes. */ -extern const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[]; -extern const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[]; -extern const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[]; -extern const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[]; - -/* Hardware decls. */ - -extern CGEN_KEYWORD openrisc_cgen_opval_h_gr; - -extern const CGEN_HW_ENTRY openrisc_cgen_hw_table[]; - - - -#endif /* OPENRISC_CPU_H */ diff -rNU3 dist.orig/opcodes/openrisc-dis.c dist/opcodes/openrisc-dis.c --- dist.orig/opcodes/openrisc-dis.c 2010-02-12 05:42:28.000000000 +0100 +++ dist/opcodes/openrisc-dis.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,556 +0,0 @@ -/* Disassembler interface for targets using CGEN. -*- C -*- - CGEN: Cpu tools GENerator - - THIS FILE IS MACHINE GENERATED WITH CGEN. - - the resultant file is machine generated, cgen-dis.in isn't - - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, - 2008, 2010 Free Software Foundation, Inc. - - This file is part of libopcodes. - - 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. */ - -/* ??? Eventually more and more of this stuff can go to cpu-independent files. - Keep that in mind. */ - -#include "sysdep.h" -#include -#include "ansidecl.h" -#include "dis-asm.h" -#include "bfd.h" -#include "symcat.h" -#include "libiberty.h" -#include "openrisc-desc.h" -#include "openrisc-opc.h" -#include "opintl.h" - -/* Default text to print if an instruction isn't recognized. */ -#define UNKNOWN_INSN_MSG _("*unknown*") - -static void print_normal - (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); -static void print_address - (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED; -static void print_keyword - (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED; -static void print_insn_normal - (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int); -static int print_insn - (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned); -static int default_print_insn - (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED; -static int read_insn - (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *, - unsigned long *); - -/* -- disassembler routines inserted here. */ - - -void openrisc_cgen_print_operand - (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int); - -/* Main entry point for printing operands. - XINFO is a `void *' and not a `disassemble_info *' to not put a requirement - of dis-asm.h on cgen.h. - - This function is basically just a big switch statement. Earlier versions - used tables to look up the function to use, but - - if the table contains both assembler and disassembler functions then - the disassembler contains much of the assembler and vice-versa, - - there's a lot of inlining possibilities as things grow, - - using a switch statement avoids the function call overhead. - - This function could be moved into `print_insn_normal', but keeping it - separate makes clear the interface between `print_insn_normal' and each of - the handlers. */ - -void -openrisc_cgen_print_operand (CGEN_CPU_DESC cd, - int opindex, - void * xinfo, - CGEN_FIELDS *fields, - void const *attrs ATTRIBUTE_UNUSED, - bfd_vma pc, - int length) -{ - disassemble_info *info = (disassemble_info *) xinfo; - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - print_address (cd, info, fields->f_abs26, 0|(1<f_disp26, 0|(1<f_simm16, 0|(1<f_lo16, 0|(1<f_op4, 0, pc, length); - break; - case OPENRISC_OPERAND_OP_F_3 : - print_normal (cd, info, fields->f_op5, 0, pc, length); - break; - case OPENRISC_OPERAND_RA : - print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r2, 0); - break; - case OPENRISC_OPERAND_RB : - print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r3, 0); - break; - case OPENRISC_OPERAND_RD : - print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r1, 0); - break; - case OPENRISC_OPERAND_SIMM_16 : - print_normal (cd, info, fields->f_simm16, 0|(1<f_i16nc, 0|(1<f_uimm16, 0, pc, length); - break; - case OPENRISC_OPERAND_UIMM_5 : - print_normal (cd, info, fields->f_uimm5, 0, pc, length); - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while printing insn.\n"), - opindex); - abort (); - } -} - -cgen_print_fn * const openrisc_cgen_print_handlers[] = -{ - print_insn_normal, -}; - - -void -openrisc_cgen_init_dis (CGEN_CPU_DESC cd) -{ - openrisc_cgen_init_opcode_table (cd); - openrisc_cgen_init_ibld_table (cd); - cd->print_handlers = & openrisc_cgen_print_handlers[0]; - cd->print_operand = openrisc_cgen_print_operand; -} - - -/* Default print handler. */ - -static void -print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - void *dis_info, - long value, - unsigned int attrs, - bfd_vma pc ATTRIBUTE_UNUSED, - int length ATTRIBUTE_UNUSED) -{ - disassemble_info *info = (disassemble_info *) dis_info; - - /* Print the operand as directed by the attributes. */ - if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) - ; /* nothing to do */ - else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) - (*info->fprintf_func) (info->stream, "%ld", value); - else - (*info->fprintf_func) (info->stream, "0x%lx", value); -} - -/* Default address handler. */ - -static void -print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - void *dis_info, - bfd_vma value, - unsigned int attrs, - bfd_vma pc ATTRIBUTE_UNUSED, - int length ATTRIBUTE_UNUSED) -{ - disassemble_info *info = (disassemble_info *) dis_info; - - /* Print the operand as directed by the attributes. */ - if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) - ; /* Nothing to do. */ - else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) - (*info->print_address_func) (value, info); - else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) - (*info->print_address_func) (value, info); - else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) - (*info->fprintf_func) (info->stream, "%ld", (long) value); - else - (*info->fprintf_func) (info->stream, "0x%lx", (long) value); -} - -/* Keyword print handler. */ - -static void -print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - void *dis_info, - CGEN_KEYWORD *keyword_table, - long value, - unsigned int attrs ATTRIBUTE_UNUSED) -{ - disassemble_info *info = (disassemble_info *) dis_info; - const CGEN_KEYWORD_ENTRY *ke; - - ke = cgen_keyword_lookup_value (keyword_table, value); - if (ke != NULL) - (*info->fprintf_func) (info->stream, "%s", ke->name); - else - (*info->fprintf_func) (info->stream, "???"); -} - -/* Default insn printer. - - DIS_INFO is defined as `void *' so the disassembler needn't know anything - about disassemble_info. */ - -static void -print_insn_normal (CGEN_CPU_DESC cd, - void *dis_info, - const CGEN_INSN *insn, - CGEN_FIELDS *fields, - bfd_vma pc, - int length) -{ - const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); - disassemble_info *info = (disassemble_info *) dis_info; - const CGEN_SYNTAX_CHAR_TYPE *syn; - - CGEN_INIT_PRINT (cd); - - for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) - { - if (CGEN_SYNTAX_MNEMONIC_P (*syn)) - { - (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn)); - continue; - } - if (CGEN_SYNTAX_CHAR_P (*syn)) - { - (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn)); - continue; - } - - /* We have an operand. */ - openrisc_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info, - fields, CGEN_INSN_ATTRS (insn), pc, length); - } -} - -/* Subroutine of print_insn. Reads an insn into the given buffers and updates - the extract info. - Returns 0 if all is well, non-zero otherwise. */ - -static int -read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - bfd_vma pc, - disassemble_info *info, - bfd_byte *buf, - int buflen, - CGEN_EXTRACT_INFO *ex_info, - unsigned long *insn_value) -{ - int status = (*info->read_memory_func) (pc, buf, buflen, info); - - if (status != 0) - { - (*info->memory_error_func) (status, pc, info); - return -1; - } - - ex_info->dis_info = info; - ex_info->valid = (1 << buflen) - 1; - ex_info->insn_bytes = buf; - - *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG); - return 0; -} - -/* Utility to print an insn. - BUF is the base part of the insn, target byte order, BUFLEN bytes long. - The result is the size of the insn in bytes or zero for an unknown insn - or -1 if an error occurs fetching data (memory_error_func will have - been called). */ - -static int -print_insn (CGEN_CPU_DESC cd, - bfd_vma pc, - disassemble_info *info, - bfd_byte *buf, - unsigned int buflen) -{ - CGEN_INSN_INT insn_value; - const CGEN_INSN_LIST *insn_list; - CGEN_EXTRACT_INFO ex_info; - int basesize; - - /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */ - basesize = cd->base_insn_bitsize < buflen * 8 ? - cd->base_insn_bitsize : buflen * 8; - insn_value = cgen_get_insn_value (cd, buf, basesize); - - - /* Fill in ex_info fields like read_insn would. Don't actually call - read_insn, since the incoming buffer is already read (and possibly - modified a la m32r). */ - ex_info.valid = (1 << buflen) - 1; - ex_info.dis_info = info; - ex_info.insn_bytes = buf; - - /* The instructions are stored in hash lists. - Pick the first one and keep trying until we find the right one. */ - - insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value); - while (insn_list != NULL) - { - const CGEN_INSN *insn = insn_list->insn; - CGEN_FIELDS fields; - int length; - unsigned long insn_value_cropped; - -#ifdef CGEN_VALIDATE_INSN_SUPPORTED - /* Not needed as insn shouldn't be in hash lists if not supported. */ - /* Supported by this cpu? */ - if (! openrisc_cgen_insn_supported (cd, insn)) - { - insn_list = CGEN_DIS_NEXT_INSN (insn_list); - continue; - } -#endif - - /* Basic bit mask must be correct. */ - /* ??? May wish to allow target to defer this check until the extract - handler. */ - - /* Base size may exceed this instruction's size. Extract the - relevant part from the buffer. */ - if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen && - (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) - insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), - info->endian == BFD_ENDIAN_BIG); - else - insn_value_cropped = insn_value; - - if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn)) - == CGEN_INSN_BASE_VALUE (insn)) - { - /* Printing is handled in two passes. The first pass parses the - machine insn and extracts the fields. The second pass prints - them. */ - - /* Make sure the entire insn is loaded into insn_value, if it - can fit. */ - if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) && - (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) - { - unsigned long full_insn_value; - int rc = read_insn (cd, pc, info, buf, - CGEN_INSN_BITSIZE (insn) / 8, - & ex_info, & full_insn_value); - if (rc != 0) - return rc; - length = CGEN_EXTRACT_FN (cd, insn) - (cd, insn, &ex_info, full_insn_value, &fields, pc); - } - else - length = CGEN_EXTRACT_FN (cd, insn) - (cd, insn, &ex_info, insn_value_cropped, &fields, pc); - - /* Length < 0 -> error. */ - if (length < 0) - return length; - if (length > 0) - { - CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length); - /* Length is in bits, result is in bytes. */ - return length / 8; - } - } - - insn_list = CGEN_DIS_NEXT_INSN (insn_list); - } - - return 0; -} - -/* Default value for CGEN_PRINT_INSN. - The result is the size of the insn in bytes or zero for an unknown insn - or -1 if an error occured fetching bytes. */ - -#ifndef CGEN_PRINT_INSN -#define CGEN_PRINT_INSN default_print_insn -#endif - -static int -default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) -{ - bfd_byte buf[CGEN_MAX_INSN_SIZE]; - int buflen; - int status; - - /* Attempt to read the base part of the insn. */ - buflen = cd->base_insn_bitsize / 8; - status = (*info->read_memory_func) (pc, buf, buflen, info); - - /* Try again with the minimum part, if min < base. */ - if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize)) - { - buflen = cd->min_insn_bitsize / 8; - status = (*info->read_memory_func) (pc, buf, buflen, info); - } - - if (status != 0) - { - (*info->memory_error_func) (status, pc, info); - return -1; - } - - return print_insn (cd, pc, info, buf, buflen); -} - -/* Main entry point. - Print one instruction from PC on INFO->STREAM. - Return the size of the instruction (in bytes). */ - -typedef struct cpu_desc_list -{ - struct cpu_desc_list *next; - CGEN_BITSET *isa; - int mach; - int endian; - CGEN_CPU_DESC cd; -} cpu_desc_list; - -int -print_insn_openrisc (bfd_vma pc, disassemble_info *info) -{ - static cpu_desc_list *cd_list = 0; - cpu_desc_list *cl = 0; - static CGEN_CPU_DESC cd = 0; - static CGEN_BITSET *prev_isa; - static int prev_mach; - static int prev_endian; - int length; - CGEN_BITSET *isa; - int mach; - int endian = (info->endian == BFD_ENDIAN_BIG - ? CGEN_ENDIAN_BIG - : CGEN_ENDIAN_LITTLE); - enum bfd_architecture arch; - - /* ??? gdb will set mach but leave the architecture as "unknown" */ -#ifndef CGEN_BFD_ARCH -#define CGEN_BFD_ARCH bfd_arch_openrisc -#endif - arch = info->arch; - if (arch == bfd_arch_unknown) - arch = CGEN_BFD_ARCH; - - /* There's no standard way to compute the machine or isa number - so we leave it to the target. */ -#ifdef CGEN_COMPUTE_MACH - mach = CGEN_COMPUTE_MACH (info); -#else - mach = info->mach; -#endif - -#ifdef CGEN_COMPUTE_ISA - { - static CGEN_BITSET *permanent_isa; - - if (!permanent_isa) - permanent_isa = cgen_bitset_create (MAX_ISAS); - isa = permanent_isa; - cgen_bitset_clear (isa); - cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info)); - } -#else - isa = info->insn_sets; -#endif - - /* If we've switched cpu's, try to find a handle we've used before */ - if (cd - && (cgen_bitset_compare (isa, prev_isa) != 0 - || mach != prev_mach - || endian != prev_endian)) - { - cd = 0; - for (cl = cd_list; cl; cl = cl->next) - { - if (cgen_bitset_compare (cl->isa, isa) == 0 && - cl->mach == mach && - cl->endian == endian) - { - cd = cl->cd; - prev_isa = cd->isas; - break; - } - } - } - - /* If we haven't initialized yet, initialize the opcode table. */ - if (! cd) - { - const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach); - const char *mach_name; - - if (!arch_type) - abort (); - mach_name = arch_type->printable_name; - - prev_isa = cgen_bitset_copy (isa); - prev_mach = mach; - prev_endian = endian; - cd = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa, - CGEN_CPU_OPEN_BFDMACH, mach_name, - CGEN_CPU_OPEN_ENDIAN, prev_endian, - CGEN_CPU_OPEN_END); - if (!cd) - abort (); - - /* Save this away for future reference. */ - cl = xmalloc (sizeof (struct cpu_desc_list)); - cl->cd = cd; - cl->isa = prev_isa; - cl->mach = mach; - cl->endian = endian; - cl->next = cd_list; - cd_list = cl; - - openrisc_cgen_init_dis (cd); - } - - /* We try to have as much common code as possible. - But at this point some targets need to take over. */ - /* ??? Some targets may need a hook elsewhere. Try to avoid this, - but if not possible try to move this hook elsewhere rather than - have two hooks. */ - length = CGEN_PRINT_INSN (cd, pc, info); - if (length > 0) - return length; - if (length < 0) - return -1; - - (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); - return cd->default_insn_bitsize / 8; -} diff -rNU3 dist.orig/opcodes/openrisc-ibld.c dist/opcodes/openrisc-ibld.c --- dist.orig/opcodes/openrisc-ibld.c 2010-01-07 19:05:45.000000000 +0100 +++ dist/opcodes/openrisc-ibld.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1009 +0,0 @@ -/* Instruction building/extraction support for openrisc. -*- C -*- - - THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. - - the resultant file is machine generated, cgen-ibld.in isn't - - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007, - 2008, 2010 Free Software Foundation, Inc. - - This file is part of libopcodes. - - 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. */ - -/* ??? Eventually more and more of this stuff can go to cpu-independent files. - Keep that in mind. */ - -#include "sysdep.h" -#include -#include "ansidecl.h" -#include "dis-asm.h" -#include "bfd.h" -#include "symcat.h" -#include "openrisc-desc.h" -#include "openrisc-opc.h" -#include "cgen/basic-modes.h" -#include "opintl.h" -#include "safe-ctype.h" - -#undef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#undef max -#define max(a,b) ((a) > (b) ? (a) : (b)) - -/* Used by the ifield rtx function. */ -#define FLD(f) (fields->f) - -static const char * insert_normal - (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR); -static const char * insert_insn_normal - (CGEN_CPU_DESC, const CGEN_INSN *, - CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); -static int extract_normal - (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, - unsigned int, unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, bfd_vma, long *); -static int extract_insn_normal - (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, - CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); -#if CGEN_INT_INSN_P -static void put_insn_int_value - (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT); -#endif -#if ! CGEN_INT_INSN_P -static CGEN_INLINE void insert_1 - (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *); -static CGEN_INLINE int fill_cache - (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma); -static CGEN_INLINE long extract_1 - (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma); -#endif - -/* Operand insertion. */ - -#if ! CGEN_INT_INSN_P - -/* Subroutine of insert_normal. */ - -static CGEN_INLINE void -insert_1 (CGEN_CPU_DESC cd, - unsigned long value, - int start, - int length, - int word_length, - unsigned char *bufp) -{ - unsigned long x,mask; - int shift; - - x = cgen_get_insn_value (cd, bufp, word_length); - - /* Written this way to avoid undefined behaviour. */ - mask = (((1L << (length - 1)) - 1) << 1) | 1; - if (CGEN_INSN_LSB0_P) - shift = (start + 1) - length; - else - shift = (word_length - (start + length)); - x = (x & ~(mask << shift)) | ((value & mask) << shift); - - cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x); -} - -#endif /* ! CGEN_INT_INSN_P */ - -/* Default insertion routine. - - ATTRS is a mask of the boolean attributes. - WORD_OFFSET is the offset in bits from the start of the insn of the value. - WORD_LENGTH is the length of the word in bits in which the value resides. - START is the starting bit number in the word, architecture origin. - LENGTH is the length of VALUE in bits. - TOTAL_LENGTH is the total length of the insn in bits. - - The result is an error message or NULL if success. */ - -/* ??? This duplicates functionality with bfd's howto table and - bfd_install_relocation. */ -/* ??? This doesn't handle bfd_vma's. Create another function when - necessary. */ - -static const char * -insert_normal (CGEN_CPU_DESC cd, - long value, - unsigned int attrs, - unsigned int word_offset, - unsigned int start, - unsigned int length, - unsigned int word_length, - unsigned int total_length, - CGEN_INSN_BYTES_PTR buffer) -{ - static char errbuf[100]; - /* Written this way to avoid undefined behaviour. */ - unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1; - - /* If LENGTH is zero, this operand doesn't contribute to the value. */ - if (length == 0) - return NULL; - - if (word_length > 8 * sizeof (CGEN_INSN_INT)) - abort (); - - /* For architectures with insns smaller than the base-insn-bitsize, - word_length may be too big. */ - if (cd->min_insn_bitsize < cd->base_insn_bitsize) - { - if (word_offset == 0 - && word_length > total_length) - word_length = total_length; - } - - /* Ensure VALUE will fit. */ - if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) - { - long minval = - (1L << (length - 1)); - unsigned long maxval = mask; - - if ((value > 0 && (unsigned long) value > maxval) - || value < minval) - { - /* xgettext:c-format */ - sprintf (errbuf, - _("operand out of range (%ld not between %ld and %lu)"), - value, minval, maxval); - return errbuf; - } - } - else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) - { - unsigned long maxval = mask; - unsigned long val = (unsigned long) value; - - /* For hosts with a word size > 32 check to see if value has been sign - extended beyond 32 bits. If so then ignore these higher sign bits - as the user is attempting to store a 32-bit signed value into an - unsigned 32-bit field which is allowed. */ - if (sizeof (unsigned long) > 4 && ((value >> 32) == -1)) - val &= 0xFFFFFFFF; - - if (val > maxval) - { - /* xgettext:c-format */ - sprintf (errbuf, - _("operand out of range (0x%lx not between 0 and 0x%lx)"), - val, maxval); - return errbuf; - } - } - else - { - if (! cgen_signed_overflow_ok_p (cd)) - { - long minval = - (1L << (length - 1)); - long maxval = (1L << (length - 1)) - 1; - - if (value < minval || value > maxval) - { - sprintf - /* xgettext:c-format */ - (errbuf, _("operand out of range (%ld not between %ld and %ld)"), - value, minval, maxval); - return errbuf; - } - } - } - -#if CGEN_INT_INSN_P - - { - int shift; - - if (CGEN_INSN_LSB0_P) - shift = (word_offset + start + 1) - length; - else - shift = total_length - (word_offset + start + length); - *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); - } - -#else /* ! CGEN_INT_INSN_P */ - - { - unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; - - insert_1 (cd, value, start, length, word_length, bufp); - } - -#endif /* ! CGEN_INT_INSN_P */ - - return NULL; -} - -/* Default insn builder (insert handler). - The instruction is recorded in CGEN_INT_INSN_P byte order (meaning - that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is - recorded in host byte order, otherwise BUFFER is an array of bytes - and the value is recorded in target byte order). - The result is an error message or NULL if success. */ - -static const char * -insert_insn_normal (CGEN_CPU_DESC cd, - const CGEN_INSN * insn, - CGEN_FIELDS * fields, - CGEN_INSN_BYTES_PTR buffer, - bfd_vma pc) -{ - const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); - unsigned long value; - const CGEN_SYNTAX_CHAR_TYPE * syn; - - CGEN_INIT_INSERT (cd); - value = CGEN_INSN_BASE_VALUE (insn); - - /* If we're recording insns as numbers (rather than a string of bytes), - target byte order handling is deferred until later. */ - -#if CGEN_INT_INSN_P - - put_insn_int_value (cd, buffer, cd->base_insn_bitsize, - CGEN_FIELDS_BITSIZE (fields), value); - -#else - - cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, - (unsigned) CGEN_FIELDS_BITSIZE (fields)), - value); - -#endif /* ! CGEN_INT_INSN_P */ - - /* ??? It would be better to scan the format's fields. - Still need to be able to insert a value based on the operand though; - e.g. storing a branch displacement that got resolved later. - Needs more thought first. */ - - for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) - { - const char *errmsg; - - if (CGEN_SYNTAX_CHAR_P (* syn)) - continue; - - errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), - fields, buffer, pc); - if (errmsg) - return errmsg; - } - - return NULL; -} - -#if CGEN_INT_INSN_P -/* Cover function to store an insn value into an integral insn. Must go here - because it needs -desc.h for CGEN_INT_INSN_P. */ - -static void -put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - CGEN_INSN_BYTES_PTR buf, - int length, - int insn_length, - CGEN_INSN_INT value) -{ - /* For architectures with insns smaller than the base-insn-bitsize, - length may be too big. */ - if (length > insn_length) - *buf = value; - else - { - int shift = insn_length - length; - /* Written this way to avoid undefined behaviour. */ - CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; - - *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); - } -} -#endif - -/* Operand extraction. */ - -#if ! CGEN_INT_INSN_P - -/* Subroutine of extract_normal. - Ensure sufficient bytes are cached in EX_INFO. - OFFSET is the offset in bytes from the start of the insn of the value. - BYTES is the length of the needed value. - Returns 1 for success, 0 for failure. */ - -static CGEN_INLINE int -fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - CGEN_EXTRACT_INFO *ex_info, - int offset, - int bytes, - bfd_vma pc) -{ - /* It's doubtful that the middle part has already been fetched so - we don't optimize that case. kiss. */ - unsigned int mask; - disassemble_info *info = (disassemble_info *) ex_info->dis_info; - - /* First do a quick check. */ - mask = (1 << bytes) - 1; - if (((ex_info->valid >> offset) & mask) == mask) - return 1; - - /* Search for the first byte we need to read. */ - for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) - if (! (mask & ex_info->valid)) - break; - - if (bytes) - { - int status; - - pc += offset; - status = (*info->read_memory_func) - (pc, ex_info->insn_bytes + offset, bytes, info); - - if (status != 0) - { - (*info->memory_error_func) (status, pc, info); - return 0; - } - - ex_info->valid |= ((1 << bytes) - 1) << offset; - } - - return 1; -} - -/* Subroutine of extract_normal. */ - -static CGEN_INLINE long -extract_1 (CGEN_CPU_DESC cd, - CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, - int start, - int length, - int word_length, - unsigned char *bufp, - bfd_vma pc ATTRIBUTE_UNUSED) -{ - unsigned long x; - int shift; - - x = cgen_get_insn_value (cd, bufp, word_length); - - if (CGEN_INSN_LSB0_P) - shift = (start + 1) - length; - else - shift = (word_length - (start + length)); - return x >> shift; -} - -#endif /* ! CGEN_INT_INSN_P */ - -/* Default extraction routine. - - INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, - or sometimes less for cases like the m32r where the base insn size is 32 - but some insns are 16 bits. - ATTRS is a mask of the boolean attributes. We only need `SIGNED', - but for generality we take a bitmask of all of them. - WORD_OFFSET is the offset in bits from the start of the insn of the value. - WORD_LENGTH is the length of the word in bits in which the value resides. - START is the starting bit number in the word, architecture origin. - LENGTH is the length of VALUE in bits. - TOTAL_LENGTH is the total length of the insn in bits. - - Returns 1 for success, 0 for failure. */ - -/* ??? The return code isn't properly used. wip. */ - -/* ??? This doesn't handle bfd_vma's. Create another function when - necessary. */ - -static int -extract_normal (CGEN_CPU_DESC cd, -#if ! CGEN_INT_INSN_P - CGEN_EXTRACT_INFO *ex_info, -#else - CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, -#endif - CGEN_INSN_INT insn_value, - unsigned int attrs, - unsigned int word_offset, - unsigned int start, - unsigned int length, - unsigned int word_length, - unsigned int total_length, -#if ! CGEN_INT_INSN_P - bfd_vma pc, -#else - bfd_vma pc ATTRIBUTE_UNUSED, -#endif - long *valuep) -{ - long value, mask; - - /* If LENGTH is zero, this operand doesn't contribute to the value - so give it a standard value of zero. */ - if (length == 0) - { - *valuep = 0; - return 1; - } - - if (word_length > 8 * sizeof (CGEN_INSN_INT)) - abort (); - - /* For architectures with insns smaller than the insn-base-bitsize, - word_length may be too big. */ - if (cd->min_insn_bitsize < cd->base_insn_bitsize) - { - if (word_offset + word_length > total_length) - word_length = total_length - word_offset; - } - - /* Does the value reside in INSN_VALUE, and at the right alignment? */ - - if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) - { - if (CGEN_INSN_LSB0_P) - value = insn_value >> ((word_offset + start + 1) - length); - else - value = insn_value >> (total_length - ( word_offset + start + length)); - } - -#if ! CGEN_INT_INSN_P - - else - { - unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; - - if (word_length > 8 * sizeof (CGEN_INSN_INT)) - abort (); - - if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) - return 0; - - value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); - } - -#endif /* ! CGEN_INT_INSN_P */ - - /* Written this way to avoid undefined behaviour. */ - mask = (((1L << (length - 1)) - 1) << 1) | 1; - - value &= mask; - /* sign extend? */ - if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) - && (value & (1L << (length - 1)))) - value |= ~mask; - - *valuep = value; - - return 1; -} - -/* Default insn extractor. - - INSN_VALUE is the first base_insn_bitsize bits, translated to host order. - The extracted fields are stored in FIELDS. - EX_INFO is used to handle reading variable length insns. - Return the length of the insn in bits, or 0 if no match, - or -1 if an error occurs fetching data (memory_error_func will have - been called). */ - -static int -extract_insn_normal (CGEN_CPU_DESC cd, - const CGEN_INSN *insn, - CGEN_EXTRACT_INFO *ex_info, - CGEN_INSN_INT insn_value, - CGEN_FIELDS *fields, - bfd_vma pc) -{ - const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); - const CGEN_SYNTAX_CHAR_TYPE *syn; - - CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); - - CGEN_INIT_EXTRACT (cd); - - for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) - { - int length; - - if (CGEN_SYNTAX_CHAR_P (*syn)) - continue; - - length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), - ex_info, insn_value, fields, pc); - if (length <= 0) - return length; - } - - /* We recognized and successfully extracted this insn. */ - return CGEN_INSN_BITSIZE (insn); -} - -/* Machine generated code added here. */ - -const char * openrisc_cgen_insert_operand - (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); - -/* Main entry point for operand insertion. - - This function is basically just a big switch statement. Earlier versions - used tables to look up the function to use, but - - if the table contains both assembler and disassembler functions then - the disassembler contains much of the assembler and vice-versa, - - there's a lot of inlining possibilities as things grow, - - using a switch statement avoids the function call overhead. - - This function could be moved into `parse_insn_normal', but keeping it - separate makes clear the interface between `parse_insn_normal' and each of - the handlers. It's also needed by GAS to insert operands that couldn't be - resolved during parsing. */ - -const char * -openrisc_cgen_insert_operand (CGEN_CPU_DESC cd, - int opindex, - CGEN_FIELDS * fields, - CGEN_INSN_BYTES_PTR buffer, - bfd_vma pc ATTRIBUTE_UNUSED) -{ - const char * errmsg = NULL; - unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - { - long value = fields->f_abs26; - value = ((SI) (pc) >> (2)); - errmsg = insert_normal (cd, value, 0|(1<f_disp26; - value = ((SI) (((value) - (pc))) >> (2)); - errmsg = insert_normal (cd, value, 0|(1<f_simm16, 0|(1<f_lo16, 0|(1<f_op4, 0, 0, 23, 3, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_OP_F_3 : - errmsg = insert_normal (cd, fields->f_op5, 0, 0, 25, 5, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_RA : - errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_RB : - errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_RD : - errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_SIMM_16 : - errmsg = insert_normal (cd, fields->f_simm16, 0|(1<> (11))) & (31)); - FLD (f_i16_1) = ((FLD (f_i16nc)) & (2047)); -} - errmsg = insert_normal (cd, fields->f_i16_1, 0, 0, 10, 11, 32, total_length, buffer); - if (errmsg) - break; - errmsg = insert_normal (cd, fields->f_i16_2, 0, 0, 25, 5, 32, total_length, buffer); - if (errmsg) - break; - } - break; - case OPENRISC_OPERAND_UIMM_16 : - errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 15, 16, 32, total_length, buffer); - break; - case OPENRISC_OPERAND_UIMM_5 : - errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 4, 5, 32, total_length, buffer); - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while building insn.\n"), - opindex); - abort (); - } - - return errmsg; -} - -int openrisc_cgen_extract_operand - (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); - -/* Main entry point for operand extraction. - The result is <= 0 for error, >0 for success. - ??? Actual values aren't well defined right now. - - This function is basically just a big switch statement. Earlier versions - used tables to look up the function to use, but - - if the table contains both assembler and disassembler functions then - the disassembler contains much of the assembler and vice-versa, - - there's a lot of inlining possibilities as things grow, - - using a switch statement avoids the function call overhead. - - This function could be moved into `print_insn_normal', but keeping it - separate makes clear the interface between `print_insn_normal' and each of - the handlers. */ - -int -openrisc_cgen_extract_operand (CGEN_CPU_DESC cd, - int opindex, - CGEN_EXTRACT_INFO *ex_info, - CGEN_INSN_INT insn_value, - CGEN_FIELDS * fields, - bfd_vma pc) -{ - /* Assume success (for those operands that are nops). */ - int length = 1; - unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - { - long value; - length = extract_normal (cd, ex_info, insn_value, 0|(1<f_abs26 = value; - } - break; - case OPENRISC_OPERAND_DISP_26 : - { - long value; - length = extract_normal (cd, ex_info, insn_value, 0|(1<f_disp26 = value; - } - break; - case OPENRISC_OPERAND_HI16 : - length = extract_normal (cd, ex_info, insn_value, 0|(1<f_simm16); - break; - case OPENRISC_OPERAND_LO16 : - length = extract_normal (cd, ex_info, insn_value, 0|(1<f_lo16); - break; - case OPENRISC_OPERAND_OP_F_23 : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 3, 32, total_length, pc, & fields->f_op4); - break; - case OPENRISC_OPERAND_OP_F_3 : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_op5); - break; - case OPENRISC_OPERAND_RA : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2); - break; - case OPENRISC_OPERAND_RB : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3); - break; - case OPENRISC_OPERAND_RD : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); - break; - case OPENRISC_OPERAND_SIMM_16 : - length = extract_normal (cd, ex_info, insn_value, 0|(1<f_simm16); - break; - case OPENRISC_OPERAND_UI16NC : - { - length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_i16_1); - if (length <= 0) break; - length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_i16_2); - if (length <= 0) break; -{ - FLD (f_i16nc) = openrisc_sign_extend_16bit (((((FLD (f_i16_2)) << (11))) | (FLD (f_i16_1)))); -} - } - break; - case OPENRISC_OPERAND_UIMM_16 : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm16); - break; - case OPENRISC_OPERAND_UIMM_5 : - length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_uimm5); - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"), - opindex); - abort (); - } - - return length; -} - -cgen_insert_fn * const openrisc_cgen_insert_handlers[] = -{ - insert_insn_normal, -}; - -cgen_extract_fn * const openrisc_cgen_extract_handlers[] = -{ - extract_insn_normal, -}; - -int openrisc_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); -bfd_vma openrisc_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); - -/* Getting values from cgen_fields is handled by a collection of functions. - They are distinguished by the type of the VALUE argument they return. - TODO: floating point, inlining support, remove cases where result type - not appropriate. */ - -int -openrisc_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - int opindex, - const CGEN_FIELDS * fields) -{ - int value; - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - value = fields->f_abs26; - break; - case OPENRISC_OPERAND_DISP_26 : - value = fields->f_disp26; - break; - case OPENRISC_OPERAND_HI16 : - value = fields->f_simm16; - break; - case OPENRISC_OPERAND_LO16 : - value = fields->f_lo16; - break; - case OPENRISC_OPERAND_OP_F_23 : - value = fields->f_op4; - break; - case OPENRISC_OPERAND_OP_F_3 : - value = fields->f_op5; - break; - case OPENRISC_OPERAND_RA : - value = fields->f_r2; - break; - case OPENRISC_OPERAND_RB : - value = fields->f_r3; - break; - case OPENRISC_OPERAND_RD : - value = fields->f_r1; - break; - case OPENRISC_OPERAND_SIMM_16 : - value = fields->f_simm16; - break; - case OPENRISC_OPERAND_UI16NC : - value = fields->f_i16nc; - break; - case OPENRISC_OPERAND_UIMM_16 : - value = fields->f_uimm16; - break; - case OPENRISC_OPERAND_UIMM_5 : - value = fields->f_uimm5; - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"), - opindex); - abort (); - } - - return value; -} - -bfd_vma -openrisc_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - int opindex, - const CGEN_FIELDS * fields) -{ - bfd_vma value; - - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - value = fields->f_abs26; - break; - case OPENRISC_OPERAND_DISP_26 : - value = fields->f_disp26; - break; - case OPENRISC_OPERAND_HI16 : - value = fields->f_simm16; - break; - case OPENRISC_OPERAND_LO16 : - value = fields->f_lo16; - break; - case OPENRISC_OPERAND_OP_F_23 : - value = fields->f_op4; - break; - case OPENRISC_OPERAND_OP_F_3 : - value = fields->f_op5; - break; - case OPENRISC_OPERAND_RA : - value = fields->f_r2; - break; - case OPENRISC_OPERAND_RB : - value = fields->f_r3; - break; - case OPENRISC_OPERAND_RD : - value = fields->f_r1; - break; - case OPENRISC_OPERAND_SIMM_16 : - value = fields->f_simm16; - break; - case OPENRISC_OPERAND_UI16NC : - value = fields->f_i16nc; - break; - case OPENRISC_OPERAND_UIMM_16 : - value = fields->f_uimm16; - break; - case OPENRISC_OPERAND_UIMM_5 : - value = fields->f_uimm5; - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"), - opindex); - abort (); - } - - return value; -} - -void openrisc_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int); -void openrisc_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma); - -/* Stuffing values in cgen_fields is handled by a collection of functions. - They are distinguished by the type of the VALUE argument they accept. - TODO: floating point, inlining support, remove cases where argument type - not appropriate. */ - -void -openrisc_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - int opindex, - CGEN_FIELDS * fields, - int value) -{ - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - fields->f_abs26 = value; - break; - case OPENRISC_OPERAND_DISP_26 : - fields->f_disp26 = value; - break; - case OPENRISC_OPERAND_HI16 : - fields->f_simm16 = value; - break; - case OPENRISC_OPERAND_LO16 : - fields->f_lo16 = value; - break; - case OPENRISC_OPERAND_OP_F_23 : - fields->f_op4 = value; - break; - case OPENRISC_OPERAND_OP_F_3 : - fields->f_op5 = value; - break; - case OPENRISC_OPERAND_RA : - fields->f_r2 = value; - break; - case OPENRISC_OPERAND_RB : - fields->f_r3 = value; - break; - case OPENRISC_OPERAND_RD : - fields->f_r1 = value; - break; - case OPENRISC_OPERAND_SIMM_16 : - fields->f_simm16 = value; - break; - case OPENRISC_OPERAND_UI16NC : - fields->f_i16nc = value; - break; - case OPENRISC_OPERAND_UIMM_16 : - fields->f_uimm16 = value; - break; - case OPENRISC_OPERAND_UIMM_5 : - fields->f_uimm5 = value; - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"), - opindex); - abort (); - } -} - -void -openrisc_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, - int opindex, - CGEN_FIELDS * fields, - bfd_vma value) -{ - switch (opindex) - { - case OPENRISC_OPERAND_ABS_26 : - fields->f_abs26 = value; - break; - case OPENRISC_OPERAND_DISP_26 : - fields->f_disp26 = value; - break; - case OPENRISC_OPERAND_HI16 : - fields->f_simm16 = value; - break; - case OPENRISC_OPERAND_LO16 : - fields->f_lo16 = value; - break; - case OPENRISC_OPERAND_OP_F_23 : - fields->f_op4 = value; - break; - case OPENRISC_OPERAND_OP_F_3 : - fields->f_op5 = value; - break; - case OPENRISC_OPERAND_RA : - fields->f_r2 = value; - break; - case OPENRISC_OPERAND_RB : - fields->f_r3 = value; - break; - case OPENRISC_OPERAND_RD : - fields->f_r1 = value; - break; - case OPENRISC_OPERAND_SIMM_16 : - fields->f_simm16 = value; - break; - case OPENRISC_OPERAND_UI16NC : - fields->f_i16nc = value; - break; - case OPENRISC_OPERAND_UIMM_16 : - fields->f_uimm16 = value; - break; - case OPENRISC_OPERAND_UIMM_5 : - fields->f_uimm5 = value; - break; - - default : - /* xgettext:c-format */ - fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"), - opindex); - abort (); - } -} - -/* Function to call before using the instruction builder tables. */ - -void -openrisc_cgen_init_ibld_table (CGEN_CPU_DESC cd) -{ - cd->insert_handlers = & openrisc_cgen_insert_handlers[0]; - cd->extract_handlers = & openrisc_cgen_extract_handlers[0]; - - cd->insert_operand = openrisc_cgen_insert_operand; - cd->extract_operand = openrisc_cgen_extract_operand; - - cd->get_int_operand = openrisc_cgen_get_int_operand; - cd->set_int_operand = openrisc_cgen_set_int_operand; - cd->get_vma_operand = openrisc_cgen_get_vma_operand; - cd->set_vma_operand = openrisc_cgen_set_vma_operand; -} diff -rNU3 dist.orig/opcodes/openrisc-opc.c dist/opcodes/openrisc-opc.c --- dist.orig/opcodes/openrisc-opc.c 2010-02-12 04:25:49.000000000 +0100 +++ dist/opcodes/openrisc-opc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,682 +0,0 @@ -/* Instruction opcode table for openrisc. - -THIS FILE IS MACHINE GENERATED WITH CGEN. - -Copyright 1996-2010 Free Software Foundation, Inc. - -This file is part of the GNU Binutils and/or GDB, the GNU debugger. - - This file 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 "sysdep.h" -#include "ansidecl.h" -#include "bfd.h" -#include "symcat.h" -#include "openrisc-desc.h" -#include "openrisc-opc.h" -#include "libiberty.h" - -/* -- opc.c */ -/* -- */ -/* The hash functions are recorded here to help keep assembler code out of - the disassembler and vice versa. */ - -static int asm_hash_insn_p (const CGEN_INSN *); -static unsigned int asm_hash_insn (const char *); -static int dis_hash_insn_p (const CGEN_INSN *); -static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT); - -/* Instruction formats. */ - -#define F(f) & openrisc_cgen_ifld_table[OPENRISC_##f] -static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = { - 0, 0, 0x0, { { 0 } } -}; - -static const CGEN_IFMT ifmt_l_j ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_ABS26) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_jr ATTRIBUTE_UNUSED = { - 32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP3) }, { F (F_OP4) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_bal ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_DISP26) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_movhi ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_mfsr ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_mtsr ATTRIBUTE_UNUSED = { - 32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_I16_1) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_lw ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_sw ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R3) }, { F (F_I16NC) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_sll ATTRIBUTE_UNUSED = { - 32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_3) }, { F (F_OP6) }, { F (F_F_4_1) }, { F (F_OP7) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_slli ATTRIBUTE_UNUSED = { - 32, 32, 0xfc00ffe0, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_F_15_8) }, { F (F_OP6) }, { F (F_UIMM5) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_add ATTRIBUTE_UNUSED = { - 32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_7) }, { F (F_OP7) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_addi ATTRIBUTE_UNUSED = { - 32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_LO16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_sfgts ATTRIBUTE_UNUSED = { - 32, 32, 0xffe007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_11) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_sfgtsi ATTRIBUTE_UNUSED = { - 32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } -}; - -static const CGEN_IFMT ifmt_l_sfgtui ATTRIBUTE_UNUSED = { - 32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } } -}; - -#undef F - -#define A(a) (1 << CGEN_INSN_##a) -#define OPERAND(op) OPENRISC_OPERAND_##op -#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ -#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) - -/* The instruction table. */ - -static const CGEN_OPCODE openrisc_cgen_insn_opcode_table[MAX_INSNS] = -{ - /* Special null first entry. - A `num' value of zero is thus invalid. - Also, the special `invalid' insn resides here. */ - { { 0, 0, 0, 0 }, {{0}}, 0, {0}}, -/* l.j ${abs-26} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (ABS_26), 0 } }, - & ifmt_l_j, { 0x0 } - }, -/* l.jal ${abs-26} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (ABS_26), 0 } }, - & ifmt_l_j, { 0x4000000 } - }, -/* l.jr $rA */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), 0 } }, - & ifmt_l_jr, { 0x14000000 } - }, -/* l.jalr $rA */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), 0 } }, - & ifmt_l_jr, { 0x14200000 } - }, -/* l.bal ${disp-26} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (DISP_26), 0 } }, - & ifmt_l_bal, { 0x8000000 } - }, -/* l.bnf ${disp-26} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (DISP_26), 0 } }, - & ifmt_l_bal, { 0xc000000 } - }, -/* l.bf ${disp-26} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (DISP_26), 0 } }, - & ifmt_l_bal, { 0x10000000 } - }, -/* l.brk ${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (UIMM_16), 0 } }, - & ifmt_l_jr, { 0x17000000 } - }, -/* l.rfe $rA */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), 0 } }, - & ifmt_l_jr, { 0x14400000 } - }, -/* l.sys ${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (UIMM_16), 0 } }, - & ifmt_l_jr, { 0x16000000 } - }, -/* l.nop */ - { - { 0, 0, 0, 0 }, - { { MNEM, 0 } }, - & ifmt_l_jr, { 0x15000000 } - }, -/* l.movhi $rD,$hi16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (HI16), 0 } }, - & ifmt_l_movhi, { 0x18000000 } - }, -/* l.mfsr $rD,$rA */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, - & ifmt_l_mfsr, { 0x1c000000 } - }, -/* l.mtsr $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_mtsr, { 0x40000000 } - }, -/* l.lw $rD,${simm-16}($rA) */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } }, - & ifmt_l_lw, { 0x80000000 } - }, -/* l.lbz $rD,${simm-16}($rA) */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } }, - & ifmt_l_lw, { 0x84000000 } - }, -/* l.lbs $rD,${simm-16}($rA) */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } }, - & ifmt_l_lw, { 0x88000000 } - }, -/* l.lhz $rD,${simm-16}($rA) */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } }, - & ifmt_l_lw, { 0x8c000000 } - }, -/* l.lhs $rD,${simm-16}($rA) */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } }, - & ifmt_l_lw, { 0x90000000 } - }, -/* l.sw ${ui16nc}($rA),$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } }, - & ifmt_l_sw, { 0xd4000000 } - }, -/* l.sb ${ui16nc}($rA),$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } }, - & ifmt_l_sw, { 0xd8000000 } - }, -/* l.sh ${ui16nc}($rA),$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } }, - & ifmt_l_sw, { 0xdc000000 } - }, -/* l.sll $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sll, { 0xe0000008 } - }, -/* l.slli $rD,$rA,${uimm-5} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } }, - & ifmt_l_slli, { 0xb4000000 } - }, -/* l.srl $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sll, { 0xe0000028 } - }, -/* l.srli $rD,$rA,${uimm-5} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } }, - & ifmt_l_slli, { 0xb4000020 } - }, -/* l.sra $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sll, { 0xe0000048 } - }, -/* l.srai $rD,$rA,${uimm-5} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } }, - & ifmt_l_slli, { 0xb4000040 } - }, -/* l.ror $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sll, { 0xe0000088 } - }, -/* l.rori $rD,$rA,${uimm-5} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } }, - & ifmt_l_slli, { 0xb4000080 } - }, -/* l.add $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000000 } - }, -/* l.addi $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0x94000000 } - }, -/* l.sub $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000002 } - }, -/* l.subi $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0x9c000000 } - }, -/* l.and $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000003 } - }, -/* l.andi $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0xa0000000 } - }, -/* l.or $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000004 } - }, -/* l.ori $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0xa4000000 } - }, -/* l.xor $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000005 } - }, -/* l.xori $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0xa8000000 } - }, -/* l.mul $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000006 } - }, -/* l.muli $rD,$rA,$lo16 */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } }, - & ifmt_l_addi, { 0xac000000 } - }, -/* l.div $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe0000009 } - }, -/* l.divu $rD,$rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_add, { 0xe000000a } - }, -/* l.sfgts $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4c00000 } - }, -/* l.sfgtu $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4400000 } - }, -/* l.sfges $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4e00000 } - }, -/* l.sfgeu $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4600000 } - }, -/* l.sflts $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe5000000 } - }, -/* l.sfltu $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4800000 } - }, -/* l.sfles $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe5200000 } - }, -/* l.sfleu $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4a00000 } - }, -/* l.sfgtsi $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb8c00000 } - }, -/* l.sfgtui $rA,${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } }, - & ifmt_l_sfgtui, { 0xb8400000 } - }, -/* l.sfgesi $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb8e00000 } - }, -/* l.sfgeui $rA,${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } }, - & ifmt_l_sfgtui, { 0xb8600000 } - }, -/* l.sfltsi $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb9000000 } - }, -/* l.sfltui $rA,${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } }, - & ifmt_l_sfgtui, { 0xb8800000 } - }, -/* l.sflesi $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb9200000 } - }, -/* l.sfleui $rA,${uimm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } }, - & ifmt_l_sfgtui, { 0xb8a00000 } - }, -/* l.sfeq $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4000000 } - }, -/* l.sfeqi $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb8000000 } - }, -/* l.sfne $rA,$rB */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, - & ifmt_l_sfgts, { 0xe4200000 } - }, -/* l.sfnei $rA,${simm-16} */ - { - { 0, 0, 0, 0 }, - { { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } }, - & ifmt_l_sfgtsi, { 0xb8200000 } - }, -}; - -#undef A -#undef OPERAND -#undef MNEM -#undef OP - -/* Formats for ALIAS macro-insns. */ - -#define F(f) & openrisc_cgen_ifld_table[OPENRISC_##f] -static const CGEN_IFMT ifmt_l_ret ATTRIBUTE_UNUSED = { - 32, 32, 0xffffffff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP3) }, { F (F_OP4) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } } -}; - -#undef F - -/* Each non-simple macro entry points to an array of expansion possibilities. */ - -#define A(a) (1 << CGEN_INSN_##a) -#define OPERAND(op) OPENRISC_OPERAND_##op -#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ -#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) - -/* The macro instruction table. */ - -static const CGEN_IBASE openrisc_cgen_macro_insn_table[] = -{ -/* l.ret */ - { - -1, "l-ret", "l.ret", 32, - { 0|A(ALIAS), { { { (1<= 1) - memset (insns, 0, num_macros * sizeof (CGEN_INSN)); - for (i = 0; i < num_macros; ++i) - { - insns[i].base = &ib[i]; - insns[i].opcode = &oc[i]; - openrisc_cgen_build_insn_regex (& insns[i]); - } - cd->macro_insn_table.init_entries = insns; - cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); - cd->macro_insn_table.num_init_entries = num_macros; - - oc = & openrisc_cgen_insn_opcode_table[0]; - insns = (CGEN_INSN *) cd->insn_table.init_entries; - for (i = 0; i < MAX_INSNS; ++i) - { - insns[i].opcode = &oc[i]; - openrisc_cgen_build_insn_regex (& insns[i]); - } - - cd->sizeof_fields = sizeof (CGEN_FIELDS); - cd->set_fields_bitsize = set_fields_bitsize; - - cd->asm_hash_p = asm_hash_insn_p; - cd->asm_hash = asm_hash_insn; - cd->asm_hash_size = CGEN_ASM_HASH_SIZE; - - cd->dis_hash_p = dis_hash_insn_p; - cd->dis_hash = dis_hash_insn; - cd->dis_hash_size = CGEN_DIS_HASH_SIZE; -} diff -rNU3 dist.orig/opcodes/openrisc-opc.h dist/opcodes/openrisc-opc.h --- dist.orig/opcodes/openrisc-opc.h 2010-01-02 19:50:59.000000000 +0100 +++ dist/opcodes/openrisc-opc.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,113 +0,0 @@ -/* Instruction opcode header for openrisc. - -THIS FILE IS MACHINE GENERATED WITH CGEN. - -Copyright 1996-2010 Free Software Foundation, Inc. - -This file is part of the GNU Binutils and/or GDB, the GNU debugger. - - This file 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. - -*/ - -#ifndef OPENRISC_OPC_H -#define OPENRISC_OPC_H - -/* -- opc.h */ -#undef CGEN_DIS_HASH_SIZE -#define CGEN_DIS_HASH_SIZE 64 -#undef CGEN_DIS_HASH -#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) - -extern long openrisc_sign_extend_16bit (long); -/* -- */ -/* Enum declaration for openrisc instruction types. */ -typedef enum cgen_insn_type { - OPENRISC_INSN_INVALID, OPENRISC_INSN_L_J, OPENRISC_INSN_L_JAL, OPENRISC_INSN_L_JR - , OPENRISC_INSN_L_JALR, OPENRISC_INSN_L_BAL, OPENRISC_INSN_L_BNF, OPENRISC_INSN_L_BF - , OPENRISC_INSN_L_BRK, OPENRISC_INSN_L_RFE, OPENRISC_INSN_L_SYS, OPENRISC_INSN_L_NOP - , OPENRISC_INSN_L_MOVHI, OPENRISC_INSN_L_MFSR, OPENRISC_INSN_L_MTSR, OPENRISC_INSN_L_LW - , OPENRISC_INSN_L_LBZ, OPENRISC_INSN_L_LBS, OPENRISC_INSN_L_LHZ, OPENRISC_INSN_L_LHS - , OPENRISC_INSN_L_SW, OPENRISC_INSN_L_SB, OPENRISC_INSN_L_SH, OPENRISC_INSN_L_SLL - , OPENRISC_INSN_L_SLLI, OPENRISC_INSN_L_SRL, OPENRISC_INSN_L_SRLI, OPENRISC_INSN_L_SRA - , OPENRISC_INSN_L_SRAI, OPENRISC_INSN_L_ROR, OPENRISC_INSN_L_RORI, OPENRISC_INSN_L_ADD - , OPENRISC_INSN_L_ADDI, OPENRISC_INSN_L_SUB, OPENRISC_INSN_L_SUBI, OPENRISC_INSN_L_AND - , OPENRISC_INSN_L_ANDI, OPENRISC_INSN_L_OR, OPENRISC_INSN_L_ORI, OPENRISC_INSN_L_XOR - , OPENRISC_INSN_L_XORI, OPENRISC_INSN_L_MUL, OPENRISC_INSN_L_MULI, OPENRISC_INSN_L_DIV - , OPENRISC_INSN_L_DIVU, OPENRISC_INSN_L_SFGTS, OPENRISC_INSN_L_SFGTU, OPENRISC_INSN_L_SFGES - , OPENRISC_INSN_L_SFGEU, OPENRISC_INSN_L_SFLTS, OPENRISC_INSN_L_SFLTU, OPENRISC_INSN_L_SFLES - , OPENRISC_INSN_L_SFLEU, OPENRISC_INSN_L_SFGTSI, OPENRISC_INSN_L_SFGTUI, OPENRISC_INSN_L_SFGESI - , OPENRISC_INSN_L_SFGEUI, OPENRISC_INSN_L_SFLTSI, OPENRISC_INSN_L_SFLTUI, OPENRISC_INSN_L_SFLESI - , OPENRISC_INSN_L_SFLEUI, OPENRISC_INSN_L_SFEQ, OPENRISC_INSN_L_SFEQI, OPENRISC_INSN_L_SFNE - , OPENRISC_INSN_L_SFNEI -} CGEN_INSN_TYPE; - -/* Index of `invalid' insn place holder. */ -#define CGEN_INSN_INVALID OPENRISC_INSN_INVALID - -/* Total number of insns in table. */ -#define MAX_INSNS ((int) OPENRISC_INSN_L_SFNEI + 1) - -/* This struct records data prior to insertion or after extraction. */ -struct cgen_fields -{ - int length; - long f_nil; - long f_anyof; - long f_class; - long f_sub; - long f_r1; - long f_r2; - long f_r3; - long f_simm16; - long f_uimm16; - long f_uimm5; - long f_hi16; - long f_lo16; - long f_op1; - long f_op2; - long f_op3; - long f_op4; - long f_op5; - long f_op6; - long f_op7; - long f_i16_1; - long f_i16_2; - long f_disp26; - long f_abs26; - long f_i16nc; - long f_f_15_8; - long f_f_10_3; - long f_f_4_1; - long f_f_7_3; - long f_f_10_7; - long f_f_10_11; -}; - -#define CGEN_INIT_PARSE(od) \ -{\ -} -#define CGEN_INIT_INSERT(od) \ -{\ -} -#define CGEN_INIT_EXTRACT(od) \ -{\ -} -#define CGEN_INIT_PRINT(od) \ -{\ -} - - -#endif /* OPENRISC_OPC_H */ diff -rNU3 dist.orig/opcodes/or1k-asm.c dist/opcodes/or1k-asm.c --- dist.orig/opcodes/or1k-asm.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-asm.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,910 @@ +/* Assembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + + THIS FILE IS MACHINE GENERATED WITH CGEN. + - the resultant file is machine generated, cgen-asm.in isn't + + Copyright (C) 1996-2014 Free Software Foundation, Inc. + + This file is part of libopcodes. + + 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. */ + + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "or1k-desc.h" +#include "or1k-opc.h" +#include "opintl.h" +#include "xregex.h" +#include "libiberty.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +static const char * parse_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); + +/* -- assembler routines inserted here. */ + +/* -- asm.c */ + +static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); + +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +static const char * +parse_disp26 (CGEN_CPU_DESC cd, + const char ** strp, + int opindex, + int opinfo, + enum cgen_parse_operand_result * resultp, + bfd_vma * valuep) +{ + const char *errmsg = NULL; + enum cgen_parse_operand_result result_type; + + if (strncasecmp (*strp, "plt(", 4) == 0) + { + bfd_vma value; + + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 2) & 0xffff; + *valuep = value; + return errmsg; + } + return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); +} + +static const char * +parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + long ret; + + if (**strp == '#') + ++*strp; + + if (strncasecmp (*strp, "hi(", 3) == 0) + { + bfd_vma value; + + *strp += 3; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, + & result_type, & value); + if (**strp != ')') + errmsg = MISSING_CLOSING_PARENTHESIS; + ++*strp; + + ret = value; + + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + ret >>= 16; + ret &= 0xffff; + ret = (ret ^ 0x8000) - 0x8000; + } + } + else if (strncasecmp (*strp, "lo(", 3) == 0) + { + bfd_vma value; + + *strp += 3; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + + ret = value; + + if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + ret &= 0xffff; + ret = (ret ^ 0x8000) - 0x8000; + } + } + else if (strncasecmp (*strp, "got(", 4) == 0) + { + bfd_vma value; + + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotpchi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTPC_HI16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotpclo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTPC_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotoffhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTOFF_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gotofflo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_GOTOFF_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_GD_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_GD_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDM_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDM_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDO_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "dtpofflo(", 9) == 0) + { + bfd_vma value; + + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LDO_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0) + { + bfd_vma value; + + *strp += 11; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_IE_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "gottpofflo(", 11) == 0) + { + bfd_vma value; + + *strp += 11; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_IE_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tpoffhi(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LE_HI16, + & result_type, & value); + + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value >> 16) & 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "tpofflo(", 8) == 0) + { + bfd_vma value; + + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, + BFD_RELOC_OR1K_TLS_LE_LO16, + &result_type, &value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else + { + long value; + errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); + ret = value; + } + + if (errmsg == NULL) + *valuep = ret; + + return errmsg; +} + +static const char * +parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep) +{ + const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep); + + if (errmsg == NULL) + *valuep &= 0xffff; + return errmsg; +} + +/* -- */ + +const char * or1k_cgen_parse_operand + (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); + +/* Main entry point for operand parsing. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. */ + +const char * +or1k_cgen_parse_operand (CGEN_CPU_DESC cd, + int opindex, + const char ** strp, + CGEN_FIELDS * fields) +{ + const char * errmsg = NULL; + /* Used by scalar operands that still need to be parsed. */ + long junk ATTRIBUTE_UNUSED; + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + { + bfd_vma value = 0; + errmsg = parse_disp26 (cd, strp, OR1K_OPERAND_DISP26, 0, NULL, & value); + fields->f_disp26 = value; + } + break; + case OR1K_OPERAND_RA : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r2); + break; + case OR1K_OPERAND_RADF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1); + break; + case OR1K_OPERAND_RASF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r2); + break; + case OR1K_OPERAND_RB : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r3); + break; + case OR1K_OPERAND_RBDF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1); + break; + case OR1K_OPERAND_RBSF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r3); + break; + case OR1K_OPERAND_RD : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r1); + break; + case OR1K_OPERAND_RDDF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1); + break; + case OR1K_OPERAND_RDSF : + errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r1); + break; + case OR1K_OPERAND_SIMM16 : + errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16, (long *) (& fields->f_simm16)); + break; + case OR1K_OPERAND_SIMM16_SPLIT : + errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16_SPLIT, (long *) (& fields->f_simm16_split)); + break; + case OR1K_OPERAND_UIMM16 : + errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16)); + break; + case OR1K_OPERAND_UIMM16_SPLIT : + errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16_SPLIT, (unsigned long *) (& fields->f_uimm16_split)); + break; + case OR1K_OPERAND_UIMM6 : + errmsg = cgen_parse_unsigned_integer (cd, strp, OR1K_OPERAND_UIMM6, (unsigned long *) (& fields->f_uimm6)); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); + abort (); + } + + return errmsg; +} + +cgen_parse_fn * const or1k_cgen_parse_handlers[] = +{ + parse_insn_normal, +}; + +void +or1k_cgen_init_asm (CGEN_CPU_DESC cd) +{ + or1k_cgen_init_opcode_table (cd); + or1k_cgen_init_ibld_table (cd); + cd->parse_handlers = & or1k_cgen_parse_handlers[0]; + cd->parse_operand = or1k_cgen_parse_operand; +#ifdef CGEN_ASM_INIT_HOOK +CGEN_ASM_INIT_HOOK +#endif +} + + + +/* Regex construction routine. + + This translates an opcode syntax string into a regex string, + by replacing any non-character syntax element (such as an + opcode) with the pattern '.*' + + It then compiles the regex and stores it in the opcode, for + later use by or1k_cgen_assemble_insn + + Returns NULL for success, an error message for failure. */ + +char * +or1k_cgen_build_insn_regex (CGEN_INSN *insn) +{ + CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); + const char *mnem = CGEN_INSN_MNEMONIC (insn); + char rxbuf[CGEN_MAX_RX_ELEMENTS]; + char *rx = rxbuf; + const CGEN_SYNTAX_CHAR_TYPE *syn; + int reg_err; + + syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); + + /* Mnemonics come first in the syntax string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + return _("missing mnemonic in syntax string"); + ++syn; + + /* Generate a case sensitive regular expression that emulates case + insensitive matching in the "C" locale. We cannot generate a case + insensitive regular expression because in Turkish locales, 'i' and 'I' + are not equal modulo case conversion. */ + + /* Copy the literal mnemonic out of the insn. */ + for (; *mnem; mnem++) + { + char c = *mnem; + + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + } + + /* Copy any remaining literals from the syntax string into the rx. */ + for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) + { + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + char c = CGEN_SYNTAX_CHAR (* syn); + + switch (c) + { + /* Escape any regex metacharacters in the syntax. */ + case '.': case '[': case '\\': + case '*': case '^': case '$': + +#ifdef CGEN_ESCAPE_EXTENDED_REGEX + case '?': case '{': case '}': + case '(': case ')': case '*': + case '|': case '+': case ']': +#endif + *rx++ = '\\'; + *rx++ = c; + break; + + default: + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + break; + } + } + else + { + /* Replace non-syntax fields with globs. */ + *rx++ = '.'; + *rx++ = '*'; + } + } + + /* Trailing whitespace ok. */ + * rx++ = '['; + * rx++ = ' '; + * rx++ = '\t'; + * rx++ = ']'; + * rx++ = '*'; + + /* But anchor it after that. */ + * rx++ = '$'; + * rx = '\0'; + + CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); + reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); + + if (reg_err == 0) + return NULL; + else + { + static char msg[80]; + + regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); + regfree ((regex_t *) CGEN_INSN_RX (insn)); + free (CGEN_INSN_RX (insn)); + (CGEN_INSN_RX (insn)) = NULL; + return msg; + } +} + + +/* Default insn parser. + + The syntax string is scanned and operands are parsed and stored in FIELDS. + Relocs are queued as we go via other callbacks. + + ??? Note that this is currently an all-or-nothing parser. If we fail to + parse the instruction, we return 0 and the caller will start over from + the beginning. Backtracking will be necessary in parsing subexpressions, + but that can be handled there. Not handling backtracking here may get + expensive in the case of the m68k. Deal with later. + + Returns NULL for success, an error message for failure. */ + +static const char * +parse_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN *insn, + const char **strp, + CGEN_FIELDS *fields) +{ + /* ??? Runtime added insns not handled yet. */ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const char *str = *strp; + const char *errmsg; + const char *p; + const CGEN_SYNTAX_CHAR_TYPE * syn; +#ifdef CGEN_MNEMONIC_OPERANDS + /* FIXME: wip */ + int past_opcode_p; +#endif + + /* For now we assume the mnemonic is first (there are no leading operands). + We can parse it without needing to set up operand parsing. + GAS's input scrubber will ensure mnemonics are lowercase, but we may + not be called from GAS. */ + p = CGEN_INSN_MNEMONIC (insn); + while (*p && TOLOWER (*p) == TOLOWER (*str)) + ++p, ++str; + + if (* p) + return _("unrecognized instruction"); + +#ifndef CGEN_MNEMONIC_OPERANDS + if (* str && ! ISSPACE (* str)) + return _("unrecognized instruction"); +#endif + + CGEN_INIT_PARSE (cd); + cgen_init_parse_operand (cd); +#ifdef CGEN_MNEMONIC_OPERANDS + past_opcode_p = 0; +#endif + + /* We don't check for (*str != '\0') here because we want to parse + any trailing fake arguments in the syntax string. */ + syn = CGEN_SYNTAX_STRING (syntax); + + /* Mnemonics come first for now, ensure valid string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + abort (); + + ++syn; + + while (* syn != 0) + { + /* Non operand chars must match exactly. */ + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + /* FIXME: While we allow for non-GAS callers above, we assume the + first char after the mnemonic part is a space. */ + /* FIXME: We also take inappropriate advantage of the fact that + GAS's input scrubber will remove extraneous blanks. */ + if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) + { +#ifdef CGEN_MNEMONIC_OPERANDS + if (CGEN_SYNTAX_CHAR(* syn) == ' ') + past_opcode_p = 1; +#endif + ++ syn; + ++ str; + } + else if (*str) + { + /* Syntax char didn't match. Can't be this insn. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found `%c')"), + CGEN_SYNTAX_CHAR(*syn), *str); + return msg; + } + else + { + /* Ran out of input. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), + CGEN_SYNTAX_CHAR(*syn)); + return msg; + } + continue; + } + +#ifdef CGEN_MNEMONIC_OPERANDS + (void) past_opcode_p; +#endif + /* We have an operand of some sort. */ + errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); + if (errmsg) + return errmsg; + + /* Done with this operand, continue with next one. */ + ++ syn; + } + + /* If we're at the end of the syntax string, we're done. */ + if (* syn == 0) + { + /* FIXME: For the moment we assume a valid `str' can only contain + blanks now. IE: We needn't try again with a longer version of + the insn and it is assumed that longer versions of insns appear + before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ + while (ISSPACE (* str)) + ++ str; + + if (* str != '\0') + return _("junk at end of line"); /* FIXME: would like to include `str' */ + + return NULL; + } + + /* We couldn't parse it. */ + return _("unrecognized instruction"); +} + +/* Main entry point. + This routine is called for each instruction to be assembled. + STR points to the insn to be assembled. + We assume all necessary tables have been initialized. + The assembled instruction, less any fixups, is stored in BUF. + Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value + still needs to be converted to target byte order, otherwise BUF is an array + of bytes in target byte order. + The result is a pointer to the insn's entry in the opcode table, + or NULL if an error occured (an error message will have already been + printed). + + Note that when processing (non-alias) macro-insns, + this function recurses. + + ??? It's possible to make this cpu-independent. + One would have to deal with a few minor things. + At this point in time doing so would be more of a curiosity than useful + [for example this file isn't _that_ big], but keeping the possibility in + mind helps keep the design clean. */ + +const CGEN_INSN * +or1k_cgen_assemble_insn (CGEN_CPU_DESC cd, + const char *str, + CGEN_FIELDS *fields, + CGEN_INSN_BYTES_PTR buf, + char **errmsg) +{ + const char *start; + CGEN_INSN_LIST *ilist; + const char *parse_errmsg = NULL; + const char *insert_errmsg = NULL; + int recognized_mnemonic = 0; + + /* Skip leading white space. */ + while (ISSPACE (* str)) + ++ str; + + /* The instructions are stored in hashed lists. + Get the first in the list. */ + ilist = CGEN_ASM_LOOKUP_INSN (cd, str); + + /* Keep looking until we find a match. */ + start = str; + for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) + { + const CGEN_INSN *insn = ilist->insn; + recognized_mnemonic = 1; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not usually needed as unsupported opcodes + shouldn't be in the hash lists. */ + /* Is this insn supported by the selected cpu? */ + if (! or1k_cgen_insn_supported (cd, insn)) + continue; +#endif + /* If the RELAXED attribute is set, this is an insn that shouldn't be + chosen immediately. Instead, it is used during assembler/linker + relaxation if possible. */ + if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) + continue; + + str = start; + + /* Skip this insn if str doesn't look right lexically. */ + if (CGEN_INSN_RX (insn) != NULL && + regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) + continue; + + /* Allow parse/insert handlers to obtain length of insn. */ + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); + if (parse_errmsg != NULL) + continue; + + /* ??? 0 is passed for `pc'. */ + insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, + (bfd_vma) 0); + if (insert_errmsg != NULL) + continue; + + /* It is up to the caller to actually output the insn and any + queued relocs. */ + return insn; + } + + { + static char errbuf[150]; + const char *tmp_errmsg; +#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS +#define be_verbose 1 +#else +#define be_verbose 0 +#endif + + if (be_verbose) + { + /* If requesting verbose error messages, use insert_errmsg. + Failing that, use parse_errmsg. */ + tmp_errmsg = (insert_errmsg ? insert_errmsg : + parse_errmsg ? parse_errmsg : + recognized_mnemonic ? + _("unrecognized form of instruction") : + _("unrecognized instruction")); + + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); + else + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); + } + else + { + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s...'"), start); + else + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s'"), start); + } + + *errmsg = errbuf; + return NULL; + } +} diff -rNU3 dist.orig/opcodes/or1k-desc.c dist/opcodes/or1k-desc.c --- dist.orig/opcodes/or1k-desc.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-desc.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,2110 @@ +/* CPU data for or1k. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright (C) 1996-2014 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + + This file 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 "sysdep.h" +#include +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "or1k-desc.h" +#include "or1k-opc.h" +#include "opintl.h" +#include "libiberty.h" +#include "xregex.h" + +/* Attributes. */ + +static const CGEN_ATTR_ENTRY bool_attr[] = +{ + { "#f", 0 }, + { "#t", 1 }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED = +{ + { "base", MACH_BASE }, + { "or32", MACH_OR32 }, + { "or32nd", MACH_OR32ND }, + { "or64", MACH_OR64 }, + { "or64nd", MACH_OR64ND }, + { "max", MACH_MAX }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED = +{ + { "openrisc", ISA_OPENRISC }, + { "max", ISA_MAX }, + { 0, 0 } +}; + +const CGEN_ATTR_TABLE or1k_cgen_ifield_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "RESERVED", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE or1k_cgen_hardware_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, + { "PC", &bool_attr[0], &bool_attr[0] }, + { "PROFILE", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE or1k_cgen_operand_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, + { "RELAX", &bool_attr[0], &bool_attr[0] }, + { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE or1k_cgen_insn_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "ALIAS", &bool_attr[0], &bool_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, + { "COND-CTI", &bool_attr[0], &bool_attr[0] }, + { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, + { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, + { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, + { "RELAXED", &bool_attr[0], &bool_attr[0] }, + { "NO-DIS", &bool_attr[0], &bool_attr[0] }, + { "PBB", &bool_attr[0], &bool_attr[0] }, + { "DELAYED-CTI", &bool_attr[0], &bool_attr[0] }, + { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, + { "FORCED-CTI", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +/* Instruction set variants. */ + +static const CGEN_ISA or1k_cgen_isa_table[] = { + { "openrisc", 32, 32, 32, 32 }, + { 0, 0, 0, 0, 0 } +}; + +/* Machine variants. */ + +static const CGEN_MACH or1k_cgen_mach_table[] = { + { "or32", "or1k", MACH_OR32, 0 }, + { "or32nd", "or1knd", MACH_OR32ND, 0 }, + { "or64", "or1k64", MACH_OR64, 0 }, + { "or64nd", "or1k64nd", MACH_OR64ND, 0 }, + { 0, 0, 0, 0 } +}; + +static CGEN_KEYWORD_ENTRY or1k_cgen_opval_h_fsr_entries[] = +{ + { "r0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "r1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "r2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "r3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "r4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "r5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "r6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "r7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "r8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "r9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "r10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "r11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "r12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "r13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "r14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "r15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "r16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "r17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "r18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "r19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "r20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "r21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "r22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "r23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "r24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "r25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "r26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "r27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "r28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "r29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "r30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }, + { "lr", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "sp", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "fp", 2, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD or1k_cgen_opval_h_fsr = +{ + & or1k_cgen_opval_h_fsr_entries[0], + 35, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY or1k_cgen_opval_h_fdr_entries[] = +{ + { "r0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "r1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "r2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "r3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "r4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "r5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "r6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "r7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "r8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "r9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "r10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "r11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "r12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "r13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "r14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "r15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "r16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "r17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "r18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "r19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "r20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "r21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "r22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "r23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "r24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "r25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "r26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "r27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "r28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "r29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "r30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }, + { "lr", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "sp", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "fp", 2, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD or1k_cgen_opval_h_fdr = +{ + & or1k_cgen_opval_h_fdr_entries[0], + 35, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY or1k_cgen_opval_h_gpr_entries[] = +{ + { "r0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "r1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "r2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "r3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "r4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "r5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "r6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "r7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "r8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "r9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "r10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "r11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "r12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "r13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "r14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "r15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "r16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "r17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "r18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "r19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "r20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "r21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "r22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "r23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "r24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "r25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "r26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "r27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "r28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "r29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "r30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }, + { "lr", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "sp", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "fp", 2, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD or1k_cgen_opval_h_gpr = +{ + & or1k_cgen_opval_h_gpr_entries[0], + 35, + 0, 0, 0, 0, "" +}; + + +/* The hardware table. */ + +#define A(a) (1 << CGEN_HW_##a) + +const CGEN_HW_ENTRY or1k_cgen_hw_table[] = +{ + { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<name) + { + if (strcmp (name, table->bfd_name) == 0) + return table; + ++table; + } + abort (); +} + +/* Subroutine of or1k_cgen_cpu_open to build the hardware table. */ + +static void +build_hw_table (CGEN_CPU_TABLE *cd) +{ + int i; + int machs = cd->machs; + const CGEN_HW_ENTRY *init = & or1k_cgen_hw_table[0]; + /* MAX_HW is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_HW_ENTRY **selected = + (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); + + cd->hw_table.init_entries = init; + cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); + memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); + /* ??? For now we just use machs to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->hw_table.entries = selected; + cd->hw_table.num_entries = MAX_HW; +} + +/* Subroutine of or1k_cgen_cpu_open to build the hardware table. */ + +static void +build_ifield_table (CGEN_CPU_TABLE *cd) +{ + cd->ifld_table = & or1k_cgen_ifld_table[0]; +} + +/* Subroutine of or1k_cgen_cpu_open to build the hardware table. */ + +static void +build_operand_table (CGEN_CPU_TABLE *cd) +{ + int i; + int machs = cd->machs; + const CGEN_OPERAND *init = & or1k_cgen_operand_table[0]; + /* MAX_OPERANDS is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected)); + + cd->operand_table.init_entries = init; + cd->operand_table.entry_size = sizeof (CGEN_OPERAND); + memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); + /* ??? For now we just use mach to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->operand_table.entries = selected; + cd->operand_table.num_entries = MAX_OPERANDS; +} + +/* Subroutine of or1k_cgen_cpu_open to build the hardware table. + ??? This could leave out insns not supported by the specified mach/isa, + but that would cause errors like "foo only supported by bar" to become + "unknown insn", so for now we include all insns and require the app to + do the checking later. + ??? On the other hand, parsing of such insns may require their hardware or + operand elements to be in the table [which they mightn't be]. */ + +static void +build_insn_table (CGEN_CPU_TABLE *cd) +{ + int i; + const CGEN_IBASE *ib = & or1k_cgen_insn_table[0]; + CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); + + memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); + for (i = 0; i < MAX_INSNS; ++i) + insns[i].base = &ib[i]; + cd->insn_table.init_entries = insns; + cd->insn_table.entry_size = sizeof (CGEN_IBASE); + cd->insn_table.num_init_entries = MAX_INSNS; +} + +/* Subroutine of or1k_cgen_cpu_open to rebuild the tables. */ + +static void +or1k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd) +{ + int i; + CGEN_BITSET *isas = cd->isas; + unsigned int machs = cd->machs; + + cd->int_insn_p = CGEN_INT_INSN_P; + + /* Data derived from the isa spec. */ +#define UNSET (CGEN_SIZE_UNKNOWN + 1) + cd->default_insn_bitsize = UNSET; + cd->base_insn_bitsize = UNSET; + cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */ + cd->max_insn_bitsize = 0; + for (i = 0; i < MAX_ISAS; ++i) + if (cgen_bitset_contains (isas, i)) + { + const CGEN_ISA *isa = & or1k_cgen_isa_table[i]; + + /* Default insn sizes of all selected isas must be + equal or we set the result to 0, meaning "unknown". */ + if (cd->default_insn_bitsize == UNSET) + cd->default_insn_bitsize = isa->default_insn_bitsize; + else if (isa->default_insn_bitsize == cd->default_insn_bitsize) + ; /* This is ok. */ + else + cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Base insn sizes of all selected isas must be equal + or we set the result to 0, meaning "unknown". */ + if (cd->base_insn_bitsize == UNSET) + cd->base_insn_bitsize = isa->base_insn_bitsize; + else if (isa->base_insn_bitsize == cd->base_insn_bitsize) + ; /* This is ok. */ + else + cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Set min,max insn sizes. */ + if (isa->min_insn_bitsize < cd->min_insn_bitsize) + cd->min_insn_bitsize = isa->min_insn_bitsize; + if (isa->max_insn_bitsize > cd->max_insn_bitsize) + cd->max_insn_bitsize = isa->max_insn_bitsize; + } + + /* Data derived from the mach spec. */ + for (i = 0; i < MAX_MACHS; ++i) + if (((1 << i) & machs) != 0) + { + const CGEN_MACH *mach = & or1k_cgen_mach_table[i]; + + if (mach->insn_chunk_bitsize != 0) + { + if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) + { + fprintf (stderr, "or1k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n", + cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); + abort (); + } + + cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; + } + } + + /* Determine which hw elements are used by MACH. */ + build_hw_table (cd); + + /* Build the ifield table. */ + build_ifield_table (cd); + + /* Determine which operands are used by MACH/ISA. */ + build_operand_table (cd); + + /* Build the instruction table. */ + build_insn_table (cd); +} + +/* Initialize a cpu table and return a descriptor. + It's much like opening a file, and must be the first function called. + The arguments are a set of (type/value) pairs, terminated with + CGEN_CPU_OPEN_END. + + Currently supported values: + CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr + CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr + CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name + CGEN_CPU_OPEN_ENDIAN: specify endian choice + CGEN_CPU_OPEN_END: terminates arguments + + ??? Simultaneous multiple isas might not make sense, but it's not (yet) + precluded. */ + +CGEN_CPU_DESC +or1k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) +{ + CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); + static int init_p; + CGEN_BITSET *isas = 0; /* 0 = "unspecified" */ + unsigned int machs = 0; /* 0 = "unspecified" */ + enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; + va_list ap; + + if (! init_p) + { + init_tables (); + init_p = 1; + } + + memset (cd, 0, sizeof (*cd)); + + va_start (ap, arg_type); + while (arg_type != CGEN_CPU_OPEN_END) + { + switch (arg_type) + { + case CGEN_CPU_OPEN_ISAS : + isas = va_arg (ap, CGEN_BITSET *); + break; + case CGEN_CPU_OPEN_MACHS : + machs = va_arg (ap, unsigned int); + break; + case CGEN_CPU_OPEN_BFDMACH : + { + const char *name = va_arg (ap, const char *); + const CGEN_MACH *mach = + lookup_mach_via_bfd_name (or1k_cgen_mach_table, name); + + machs |= 1 << mach->num; + break; + } + case CGEN_CPU_OPEN_ENDIAN : + endian = va_arg (ap, enum cgen_endian); + break; + default : + fprintf (stderr, "or1k_cgen_cpu_open: unsupported argument `%d'\n", + arg_type); + abort (); /* ??? return NULL? */ + } + arg_type = va_arg (ap, enum cgen_cpu_open_arg); + } + va_end (ap); + + /* Mach unspecified means "all". */ + if (machs == 0) + machs = (1 << MAX_MACHS) - 1; + /* Base mach is always selected. */ + machs |= 1; + if (endian == CGEN_ENDIAN_UNKNOWN) + { + /* ??? If target has only one, could have a default. */ + fprintf (stderr, "or1k_cgen_cpu_open: no endianness specified\n"); + abort (); + } + + cd->isas = cgen_bitset_copy (isas); + cd->machs = machs; + cd->endian = endian; + /* FIXME: for the sparc case we can determine insn-endianness statically. + The worry here is where both data and insn endian can be independently + chosen, in which case this function will need another argument. + Actually, will want to allow for more arguments in the future anyway. */ + cd->insn_endian = endian; + + /* Table (re)builder. */ + cd->rebuild_tables = or1k_cgen_rebuild_tables; + or1k_cgen_rebuild_tables (cd); + + /* Default to not allowing signed overflow. */ + cd->signed_overflow_ok_p = 0; + + return (CGEN_CPU_DESC) cd; +} + +/* Cover fn to or1k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. + MACH_NAME is the bfd name of the mach. */ + +CGEN_CPU_DESC +or1k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) +{ + return or1k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, endian, + CGEN_CPU_OPEN_END); +} + +/* Close a cpu table. + ??? This can live in a machine independent file, but there's currently + no place to put this file (there's no libcgen). libopcodes is the wrong + place as some simulator ports use this but they don't use libopcodes. */ + +void +or1k_cgen_cpu_close (CGEN_CPU_DESC cd) +{ + unsigned int i; + const CGEN_INSN *insns; + + if (cd->macro_insn_table.init_entries) + { + insns = cd->macro_insn_table.init_entries; + for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) + if (CGEN_INSN_RX ((insns))) + regfree (CGEN_INSN_RX (insns)); + } + + if (cd->insn_table.init_entries) + { + insns = cd->insn_table.init_entries; + for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) + if (CGEN_INSN_RX (insns)) + regfree (CGEN_INSN_RX (insns)); + } + + if (cd->macro_insn_table.init_entries) + free ((CGEN_INSN *) cd->macro_insn_table.init_entries); + + if (cd->insn_table.init_entries) + free ((CGEN_INSN *) cd->insn_table.init_entries); + + if (cd->hw_table.entries) + free ((CGEN_HW_ENTRY *) cd->hw_table.entries); + + if (cd->operand_table.entries) + free ((CGEN_HW_ENTRY *) cd->operand_table.entries); + + free (cd); +} + diff -rNU3 dist.orig/opcodes/or1k-desc.h dist/opcodes/or1k-desc.h --- dist.orig/opcodes/or1k-desc.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-desc.h 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,682 @@ +/* CPU data header for or1k. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright (C) 1996-2014 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + + This file 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. + +*/ + +#ifndef OR1K_CPU_H +#define OR1K_CPU_H + +#define CGEN_ARCH or1k + +/* Given symbol S, return or1k_cgen_. */ +#define CGEN_SYM(s) or1k##_cgen_##s + + +/* Selected cpu families. */ +#define HAVE_CPU_OR1K32BF +#define HAVE_CPU_OR1K64BF + +#define CGEN_INSN_LSB0_P 1 + +/* Minimum size of any insn (in bytes). */ +#define CGEN_MIN_INSN_SIZE 4 + +/* Maximum size of any insn (in bytes). */ +#define CGEN_MAX_INSN_SIZE 4 + +#define CGEN_INT_INSN_P 1 + +/* Maximum number of syntax elements in an instruction. */ +#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 17 + +/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands. + e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands + we can't hash on everything up to the space. */ +#define CGEN_MNEMONIC_OPERANDS + +/* Maximum number of fields in an instruction. */ +#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 8 + +/* Enums. */ + +/* Enum declaration for Exception numbers. */ +typedef enum except_number { + EXCEPT_NONE, EXCEPT_RESET, EXCEPT_BUSERR, EXCEPT_DPF + , EXCEPT_IPF, EXCEPT_TICK, EXCEPT_ALIGN, EXCEPT_ILLEGAL + , EXCEPT_INT, EXCEPT_DTLBMISS, EXCEPT_ITLBMISS, EXCEPT_RANGE + , EXCEPT_SYSCALL, EXCEPT_FPE, EXCEPT_TRAP +} EXCEPT_NUMBER; + +/* Enum declaration for special purpose register groups. */ +typedef enum spr_groups { + SPR_GROUP_SYS, SPR_GROUP_DMMU, SPR_GROUP_IMMU, SPR_GROUP_DCACHE + , SPR_GROUP_ICACHE, SPR_GROUP_MAC, SPR_GROUP_DEBUG, SPR_GROUP_PERF + , SPR_GROUP_POWER, SPR_GROUP_PIC, SPR_GROUP_TICK, SPR_GROUP_FPU +} SPR_GROUPS; + +/* Enum declaration for special purpose register indicies. */ +typedef enum spr_reg_indices { + SPR_INDEX_SYS_VR = 0, SPR_INDEX_SYS_UPR = 1, SPR_INDEX_SYS_CPUCFGR = 2, SPR_INDEX_SYS_DMMUCFGR = 3 + , SPR_INDEX_SYS_IMMUCFGR = 4, SPR_INDEX_SYS_DCCFGR = 5, SPR_INDEX_SYS_ICCFGR = 6, SPR_INDEX_SYS_DCFGR = 7 + , SPR_INDEX_SYS_PCCFGR = 8, SPR_INDEX_SYS_NPC = 16, SPR_INDEX_SYS_SR = 17, SPR_INDEX_SYS_PPC = 18 + , SPR_INDEX_SYS_FPCSR = 20, SPR_INDEX_SYS_EPCR0 = 32, SPR_INDEX_SYS_EPCR1 = 33, SPR_INDEX_SYS_EPCR2 = 34 + , SPR_INDEX_SYS_EPCR3 = 35, SPR_INDEX_SYS_EPCR4 = 36, SPR_INDEX_SYS_EPCR5 = 37, SPR_INDEX_SYS_EPCR6 = 38 + , SPR_INDEX_SYS_EPCR7 = 39, SPR_INDEX_SYS_EPCR8 = 40, SPR_INDEX_SYS_EPCR9 = 41, SPR_INDEX_SYS_EPCR10 = 42 + , SPR_INDEX_SYS_EPCR11 = 43, SPR_INDEX_SYS_EPCR12 = 44, SPR_INDEX_SYS_EPCR13 = 45, SPR_INDEX_SYS_EPCR14 = 46 + , SPR_INDEX_SYS_EPCR15 = 47, SPR_INDEX_SYS_EEAR0 = 48, SPR_INDEX_SYS_EEAR1 = 49, SPR_INDEX_SYS_EEAR2 = 50 + , SPR_INDEX_SYS_EEAR3 = 51, SPR_INDEX_SYS_EEAR4 = 52, SPR_INDEX_SYS_EEAR5 = 53, SPR_INDEX_SYS_EEAR6 = 54 + , SPR_INDEX_SYS_EEAR7 = 55, SPR_INDEX_SYS_EEAR8 = 56, SPR_INDEX_SYS_EEAR9 = 57, SPR_INDEX_SYS_EEAR10 = 58 + , SPR_INDEX_SYS_EEAR11 = 59, SPR_INDEX_SYS_EEAR12 = 60, SPR_INDEX_SYS_EEAR13 = 61, SPR_INDEX_SYS_EEAR14 = 62 + , SPR_INDEX_SYS_EEAR15 = 63, SPR_INDEX_SYS_ESR0 = 64, SPR_INDEX_SYS_ESR1 = 65, SPR_INDEX_SYS_ESR2 = 66 + , SPR_INDEX_SYS_ESR3 = 67, SPR_INDEX_SYS_ESR4 = 68, SPR_INDEX_SYS_ESR5 = 69, SPR_INDEX_SYS_ESR6 = 70 + , SPR_INDEX_SYS_ESR7 = 71, SPR_INDEX_SYS_ESR8 = 72, SPR_INDEX_SYS_ESR9 = 73, SPR_INDEX_SYS_ESR10 = 74 + , SPR_INDEX_SYS_ESR11 = 75, SPR_INDEX_SYS_ESR12 = 76, SPR_INDEX_SYS_ESR13 = 77, SPR_INDEX_SYS_ESR14 = 78 + , SPR_INDEX_SYS_ESR15 = 79, SPR_INDEX_SYS_GPR0 = 1024, SPR_INDEX_SYS_GPR1 = 1025, SPR_INDEX_SYS_GPR2 = 1026 + , SPR_INDEX_SYS_GPR3 = 1027, SPR_INDEX_SYS_GPR4 = 1028, SPR_INDEX_SYS_GPR5 = 1029, SPR_INDEX_SYS_GPR6 = 1030 + , SPR_INDEX_SYS_GPR7 = 1031, SPR_INDEX_SYS_GPR8 = 1032, SPR_INDEX_SYS_GPR9 = 1033, SPR_INDEX_SYS_GPR10 = 1034 + , SPR_INDEX_SYS_GPR11 = 1035, SPR_INDEX_SYS_GPR12 = 1036, SPR_INDEX_SYS_GPR13 = 1037, SPR_INDEX_SYS_GPR14 = 1038 + , SPR_INDEX_SYS_GPR15 = 1039, SPR_INDEX_SYS_GPR16 = 1040, SPR_INDEX_SYS_GPR17 = 1041, SPR_INDEX_SYS_GPR18 = 1042 + , SPR_INDEX_SYS_GPR19 = 1043, SPR_INDEX_SYS_GPR20 = 1044, SPR_INDEX_SYS_GPR21 = 1045, SPR_INDEX_SYS_GPR22 = 1046 + , SPR_INDEX_SYS_GPR23 = 1047, SPR_INDEX_SYS_GPR24 = 1048, SPR_INDEX_SYS_GPR25 = 1049, SPR_INDEX_SYS_GPR26 = 1050 + , SPR_INDEX_SYS_GPR27 = 1051, SPR_INDEX_SYS_GPR28 = 1052, SPR_INDEX_SYS_GPR29 = 1053, SPR_INDEX_SYS_GPR30 = 1054 + , SPR_INDEX_SYS_GPR31 = 1055, SPR_INDEX_SYS_GPR32 = 1056, SPR_INDEX_SYS_GPR33 = 1057, SPR_INDEX_SYS_GPR34 = 1058 + , SPR_INDEX_SYS_GPR35 = 1059, SPR_INDEX_SYS_GPR36 = 1060, SPR_INDEX_SYS_GPR37 = 1061, SPR_INDEX_SYS_GPR38 = 1062 + , SPR_INDEX_SYS_GPR39 = 1063, SPR_INDEX_SYS_GPR40 = 1064, SPR_INDEX_SYS_GPR41 = 1065, SPR_INDEX_SYS_GPR42 = 1066 + , SPR_INDEX_SYS_GPR43 = 1067, SPR_INDEX_SYS_GPR44 = 1068, SPR_INDEX_SYS_GPR45 = 1069, SPR_INDEX_SYS_GPR46 = 1070 + , SPR_INDEX_SYS_GPR47 = 1071, SPR_INDEX_SYS_GPR48 = 1072, SPR_INDEX_SYS_GPR49 = 1073, SPR_INDEX_SYS_GPR50 = 1074 + , SPR_INDEX_SYS_GPR51 = 1075, SPR_INDEX_SYS_GPR52 = 1076, SPR_INDEX_SYS_GPR53 = 1077, SPR_INDEX_SYS_GPR54 = 1078 + , SPR_INDEX_SYS_GPR55 = 1079, SPR_INDEX_SYS_GPR56 = 1080, SPR_INDEX_SYS_GPR57 = 1081, SPR_INDEX_SYS_GPR58 = 1082 + , SPR_INDEX_SYS_GPR59 = 1083, SPR_INDEX_SYS_GPR60 = 1084, SPR_INDEX_SYS_GPR61 = 1085, SPR_INDEX_SYS_GPR62 = 1086 + , SPR_INDEX_SYS_GPR63 = 1087, SPR_INDEX_SYS_GPR64 = 1088, SPR_INDEX_SYS_GPR65 = 1089, SPR_INDEX_SYS_GPR66 = 1090 + , SPR_INDEX_SYS_GPR67 = 1091, SPR_INDEX_SYS_GPR68 = 1092, SPR_INDEX_SYS_GPR69 = 1093, SPR_INDEX_SYS_GPR70 = 1094 + , SPR_INDEX_SYS_GPR71 = 1095, SPR_INDEX_SYS_GPR72 = 1096, SPR_INDEX_SYS_GPR73 = 1097, SPR_INDEX_SYS_GPR74 = 1098 + , SPR_INDEX_SYS_GPR75 = 1099, SPR_INDEX_SYS_GPR76 = 1100, SPR_INDEX_SYS_GPR77 = 1101, SPR_INDEX_SYS_GPR78 = 1102 + , SPR_INDEX_SYS_GPR79 = 1103, SPR_INDEX_SYS_GPR80 = 1104, SPR_INDEX_SYS_GPR81 = 1105, SPR_INDEX_SYS_GPR82 = 1106 + , SPR_INDEX_SYS_GPR83 = 1107, SPR_INDEX_SYS_GPR84 = 1108, SPR_INDEX_SYS_GPR85 = 1109, SPR_INDEX_SYS_GPR86 = 1110 + , SPR_INDEX_SYS_GPR87 = 1111, SPR_INDEX_SYS_GPR88 = 1112, SPR_INDEX_SYS_GPR89 = 1113, SPR_INDEX_SYS_GPR90 = 1114 + , SPR_INDEX_SYS_GPR91 = 1115, SPR_INDEX_SYS_GPR92 = 1116, SPR_INDEX_SYS_GPR93 = 1117, SPR_INDEX_SYS_GPR94 = 1118 + , SPR_INDEX_SYS_GPR95 = 1119, SPR_INDEX_SYS_GPR96 = 1120, SPR_INDEX_SYS_GPR97 = 1121, SPR_INDEX_SYS_GPR98 = 1122 + , SPR_INDEX_SYS_GPR99 = 1123, SPR_INDEX_SYS_GPR100 = 1124, SPR_INDEX_SYS_GPR101 = 1125, SPR_INDEX_SYS_GPR102 = 1126 + , SPR_INDEX_SYS_GPR103 = 1127, SPR_INDEX_SYS_GPR104 = 1128, SPR_INDEX_SYS_GPR105 = 1129, SPR_INDEX_SYS_GPR106 = 1130 + , SPR_INDEX_SYS_GPR107 = 1131, SPR_INDEX_SYS_GPR108 = 1132, SPR_INDEX_SYS_GPR109 = 1133, SPR_INDEX_SYS_GPR110 = 1134 + , SPR_INDEX_SYS_GPR111 = 1135, SPR_INDEX_SYS_GPR112 = 1136, SPR_INDEX_SYS_GPR113 = 1137, SPR_INDEX_SYS_GPR114 = 1138 + , SPR_INDEX_SYS_GPR115 = 1139, SPR_INDEX_SYS_GPR116 = 1140, SPR_INDEX_SYS_GPR117 = 1141, SPR_INDEX_SYS_GPR118 = 1142 + , SPR_INDEX_SYS_GPR119 = 1143, SPR_INDEX_SYS_GPR120 = 1144, SPR_INDEX_SYS_GPR121 = 1145, SPR_INDEX_SYS_GPR122 = 1146 + , SPR_INDEX_SYS_GPR123 = 1147, SPR_INDEX_SYS_GPR124 = 1148, SPR_INDEX_SYS_GPR125 = 1149, SPR_INDEX_SYS_GPR126 = 1150 + , SPR_INDEX_SYS_GPR127 = 1151, SPR_INDEX_SYS_GPR128 = 1152, SPR_INDEX_SYS_GPR129 = 1153, SPR_INDEX_SYS_GPR130 = 1154 + , SPR_INDEX_SYS_GPR131 = 1155, SPR_INDEX_SYS_GPR132 = 1156, SPR_INDEX_SYS_GPR133 = 1157, SPR_INDEX_SYS_GPR134 = 1158 + , SPR_INDEX_SYS_GPR135 = 1159, SPR_INDEX_SYS_GPR136 = 1160, SPR_INDEX_SYS_GPR137 = 1161, SPR_INDEX_SYS_GPR138 = 1162 + , SPR_INDEX_SYS_GPR139 = 1163, SPR_INDEX_SYS_GPR140 = 1164, SPR_INDEX_SYS_GPR141 = 1165, SPR_INDEX_SYS_GPR142 = 1166 + , SPR_INDEX_SYS_GPR143 = 1167, SPR_INDEX_SYS_GPR144 = 1168, SPR_INDEX_SYS_GPR145 = 1169, SPR_INDEX_SYS_GPR146 = 1170 + , SPR_INDEX_SYS_GPR147 = 1171, SPR_INDEX_SYS_GPR148 = 1172, SPR_INDEX_SYS_GPR149 = 1173, SPR_INDEX_SYS_GPR150 = 1174 + , SPR_INDEX_SYS_GPR151 = 1175, SPR_INDEX_SYS_GPR152 = 1176, SPR_INDEX_SYS_GPR153 = 1177, SPR_INDEX_SYS_GPR154 = 1178 + , SPR_INDEX_SYS_GPR155 = 1179, SPR_INDEX_SYS_GPR156 = 1180, SPR_INDEX_SYS_GPR157 = 1181, SPR_INDEX_SYS_GPR158 = 1182 + , SPR_INDEX_SYS_GPR159 = 1183, SPR_INDEX_SYS_GPR160 = 1184, SPR_INDEX_SYS_GPR161 = 1185, SPR_INDEX_SYS_GPR162 = 1186 + , SPR_INDEX_SYS_GPR163 = 1187, SPR_INDEX_SYS_GPR164 = 1188, SPR_INDEX_SYS_GPR165 = 1189, SPR_INDEX_SYS_GPR166 = 1190 + , SPR_INDEX_SYS_GPR167 = 1191, SPR_INDEX_SYS_GPR168 = 1192, SPR_INDEX_SYS_GPR169 = 1193, SPR_INDEX_SYS_GPR170 = 1194 + , SPR_INDEX_SYS_GPR171 = 1195, SPR_INDEX_SYS_GPR172 = 1196, SPR_INDEX_SYS_GPR173 = 1197, SPR_INDEX_SYS_GPR174 = 1198 + , SPR_INDEX_SYS_GPR175 = 1199, SPR_INDEX_SYS_GPR176 = 1200, SPR_INDEX_SYS_GPR177 = 1201, SPR_INDEX_SYS_GPR178 = 1202 + , SPR_INDEX_SYS_GPR179 = 1203, SPR_INDEX_SYS_GPR180 = 1204, SPR_INDEX_SYS_GPR181 = 1205, SPR_INDEX_SYS_GPR182 = 1206 + , SPR_INDEX_SYS_GPR183 = 1207, SPR_INDEX_SYS_GPR184 = 1208, SPR_INDEX_SYS_GPR185 = 1209, SPR_INDEX_SYS_GPR186 = 1210 + , SPR_INDEX_SYS_GPR187 = 1211, SPR_INDEX_SYS_GPR188 = 1212, SPR_INDEX_SYS_GPR189 = 1213, SPR_INDEX_SYS_GPR190 = 1214 + , SPR_INDEX_SYS_GPR191 = 1215, SPR_INDEX_SYS_GPR192 = 1216, SPR_INDEX_SYS_GPR193 = 1217, SPR_INDEX_SYS_GPR194 = 1218 + , SPR_INDEX_SYS_GPR195 = 1219, SPR_INDEX_SYS_GPR196 = 1220, SPR_INDEX_SYS_GPR197 = 1221, SPR_INDEX_SYS_GPR198 = 1222 + , SPR_INDEX_SYS_GPR199 = 1223, SPR_INDEX_SYS_GPR200 = 1224, SPR_INDEX_SYS_GPR201 = 1225, SPR_INDEX_SYS_GPR202 = 1226 + , SPR_INDEX_SYS_GPR203 = 1227, SPR_INDEX_SYS_GPR204 = 1228, SPR_INDEX_SYS_GPR205 = 1229, SPR_INDEX_SYS_GPR206 = 1230 + , SPR_INDEX_SYS_GPR207 = 1231, SPR_INDEX_SYS_GPR208 = 1232, SPR_INDEX_SYS_GPR209 = 1233, SPR_INDEX_SYS_GPR210 = 1234 + , SPR_INDEX_SYS_GPR211 = 1235, SPR_INDEX_SYS_GPR212 = 1236, SPR_INDEX_SYS_GPR213 = 1237, SPR_INDEX_SYS_GPR214 = 1238 + , SPR_INDEX_SYS_GPR215 = 1239, SPR_INDEX_SYS_GPR216 = 1240, SPR_INDEX_SYS_GPR217 = 1241, SPR_INDEX_SYS_GPR218 = 1242 + , SPR_INDEX_SYS_GPR219 = 1243, SPR_INDEX_SYS_GPR220 = 1244, SPR_INDEX_SYS_GPR221 = 1245, SPR_INDEX_SYS_GPR222 = 1246 + , SPR_INDEX_SYS_GPR223 = 1247, SPR_INDEX_SYS_GPR224 = 1248, SPR_INDEX_SYS_GPR225 = 1249, SPR_INDEX_SYS_GPR226 = 1250 + , SPR_INDEX_SYS_GPR227 = 1251, SPR_INDEX_SYS_GPR228 = 1252, SPR_INDEX_SYS_GPR229 = 1253, SPR_INDEX_SYS_GPR230 = 1254 + , SPR_INDEX_SYS_GPR231 = 1255, SPR_INDEX_SYS_GPR232 = 1256, SPR_INDEX_SYS_GPR233 = 1257, SPR_INDEX_SYS_GPR234 = 1258 + , SPR_INDEX_SYS_GPR235 = 1259, SPR_INDEX_SYS_GPR236 = 1260, SPR_INDEX_SYS_GPR237 = 1261, SPR_INDEX_SYS_GPR238 = 1262 + , SPR_INDEX_SYS_GPR239 = 1263, SPR_INDEX_SYS_GPR240 = 1264, SPR_INDEX_SYS_GPR241 = 1265, SPR_INDEX_SYS_GPR242 = 1266 + , SPR_INDEX_SYS_GPR243 = 1267, SPR_INDEX_SYS_GPR244 = 1268, SPR_INDEX_SYS_GPR245 = 1269, SPR_INDEX_SYS_GPR246 = 1270 + , SPR_INDEX_SYS_GPR247 = 1271, SPR_INDEX_SYS_GPR248 = 1272, SPR_INDEX_SYS_GPR249 = 1273, SPR_INDEX_SYS_GPR250 = 1274 + , SPR_INDEX_SYS_GPR251 = 1275, SPR_INDEX_SYS_GPR252 = 1276, SPR_INDEX_SYS_GPR253 = 1277, SPR_INDEX_SYS_GPR254 = 1278 + , SPR_INDEX_SYS_GPR255 = 1279, SPR_INDEX_SYS_GPR256 = 1280, SPR_INDEX_SYS_GPR257 = 1281, SPR_INDEX_SYS_GPR258 = 1282 + , SPR_INDEX_SYS_GPR259 = 1283, SPR_INDEX_SYS_GPR260 = 1284, SPR_INDEX_SYS_GPR261 = 1285, SPR_INDEX_SYS_GPR262 = 1286 + , SPR_INDEX_SYS_GPR263 = 1287, SPR_INDEX_SYS_GPR264 = 1288, SPR_INDEX_SYS_GPR265 = 1289, SPR_INDEX_SYS_GPR266 = 1290 + , SPR_INDEX_SYS_GPR267 = 1291, SPR_INDEX_SYS_GPR268 = 1292, SPR_INDEX_SYS_GPR269 = 1293, SPR_INDEX_SYS_GPR270 = 1294 + , SPR_INDEX_SYS_GPR271 = 1295, SPR_INDEX_SYS_GPR272 = 1296, SPR_INDEX_SYS_GPR273 = 1297, SPR_INDEX_SYS_GPR274 = 1298 + , SPR_INDEX_SYS_GPR275 = 1299, SPR_INDEX_SYS_GPR276 = 1300, SPR_INDEX_SYS_GPR277 = 1301, SPR_INDEX_SYS_GPR278 = 1302 + , SPR_INDEX_SYS_GPR279 = 1303, SPR_INDEX_SYS_GPR280 = 1304, SPR_INDEX_SYS_GPR281 = 1305, SPR_INDEX_SYS_GPR282 = 1306 + , SPR_INDEX_SYS_GPR283 = 1307, SPR_INDEX_SYS_GPR284 = 1308, SPR_INDEX_SYS_GPR285 = 1309, SPR_INDEX_SYS_GPR286 = 1310 + , SPR_INDEX_SYS_GPR287 = 1311, SPR_INDEX_SYS_GPR288 = 1312, SPR_INDEX_SYS_GPR289 = 1313, SPR_INDEX_SYS_GPR290 = 1314 + , SPR_INDEX_SYS_GPR291 = 1315, SPR_INDEX_SYS_GPR292 = 1316, SPR_INDEX_SYS_GPR293 = 1317, SPR_INDEX_SYS_GPR294 = 1318 + , SPR_INDEX_SYS_GPR295 = 1319, SPR_INDEX_SYS_GPR296 = 1320, SPR_INDEX_SYS_GPR297 = 1321, SPR_INDEX_SYS_GPR298 = 1322 + , SPR_INDEX_SYS_GPR299 = 1323, SPR_INDEX_SYS_GPR300 = 1324, SPR_INDEX_SYS_GPR301 = 1325, SPR_INDEX_SYS_GPR302 = 1326 + , SPR_INDEX_SYS_GPR303 = 1327, SPR_INDEX_SYS_GPR304 = 1328, SPR_INDEX_SYS_GPR305 = 1329, SPR_INDEX_SYS_GPR306 = 1330 + , SPR_INDEX_SYS_GPR307 = 1331, SPR_INDEX_SYS_GPR308 = 1332, SPR_INDEX_SYS_GPR309 = 1333, SPR_INDEX_SYS_GPR310 = 1334 + , SPR_INDEX_SYS_GPR311 = 1335, SPR_INDEX_SYS_GPR312 = 1336, SPR_INDEX_SYS_GPR313 = 1337, SPR_INDEX_SYS_GPR314 = 1338 + , SPR_INDEX_SYS_GPR315 = 1339, SPR_INDEX_SYS_GPR316 = 1340, SPR_INDEX_SYS_GPR317 = 1341, SPR_INDEX_SYS_GPR318 = 1342 + , SPR_INDEX_SYS_GPR319 = 1343, SPR_INDEX_SYS_GPR320 = 1344, SPR_INDEX_SYS_GPR321 = 1345, SPR_INDEX_SYS_GPR322 = 1346 + , SPR_INDEX_SYS_GPR323 = 1347, SPR_INDEX_SYS_GPR324 = 1348, SPR_INDEX_SYS_GPR325 = 1349, SPR_INDEX_SYS_GPR326 = 1350 + , SPR_INDEX_SYS_GPR327 = 1351, SPR_INDEX_SYS_GPR328 = 1352, SPR_INDEX_SYS_GPR329 = 1353, SPR_INDEX_SYS_GPR330 = 1354 + , SPR_INDEX_SYS_GPR331 = 1355, SPR_INDEX_SYS_GPR332 = 1356, SPR_INDEX_SYS_GPR333 = 1357, SPR_INDEX_SYS_GPR334 = 1358 + , SPR_INDEX_SYS_GPR335 = 1359, SPR_INDEX_SYS_GPR336 = 1360, SPR_INDEX_SYS_GPR337 = 1361, SPR_INDEX_SYS_GPR338 = 1362 + , SPR_INDEX_SYS_GPR339 = 1363, SPR_INDEX_SYS_GPR340 = 1364, SPR_INDEX_SYS_GPR341 = 1365, SPR_INDEX_SYS_GPR342 = 1366 + , SPR_INDEX_SYS_GPR343 = 1367, SPR_INDEX_SYS_GPR344 = 1368, SPR_INDEX_SYS_GPR345 = 1369, SPR_INDEX_SYS_GPR346 = 1370 + , SPR_INDEX_SYS_GPR347 = 1371, SPR_INDEX_SYS_GPR348 = 1372, SPR_INDEX_SYS_GPR349 = 1373, SPR_INDEX_SYS_GPR350 = 1374 + , SPR_INDEX_SYS_GPR351 = 1375, SPR_INDEX_SYS_GPR352 = 1376, SPR_INDEX_SYS_GPR353 = 1377, SPR_INDEX_SYS_GPR354 = 1378 + , SPR_INDEX_SYS_GPR355 = 1379, SPR_INDEX_SYS_GPR356 = 1380, SPR_INDEX_SYS_GPR357 = 1381, SPR_INDEX_SYS_GPR358 = 1382 + , SPR_INDEX_SYS_GPR359 = 1383, SPR_INDEX_SYS_GPR360 = 1384, SPR_INDEX_SYS_GPR361 = 1385, SPR_INDEX_SYS_GPR362 = 1386 + , SPR_INDEX_SYS_GPR363 = 1387, SPR_INDEX_SYS_GPR364 = 1388, SPR_INDEX_SYS_GPR365 = 1389, SPR_INDEX_SYS_GPR366 = 1390 + , SPR_INDEX_SYS_GPR367 = 1391, SPR_INDEX_SYS_GPR368 = 1392, SPR_INDEX_SYS_GPR369 = 1393, SPR_INDEX_SYS_GPR370 = 1394 + , SPR_INDEX_SYS_GPR371 = 1395, SPR_INDEX_SYS_GPR372 = 1396, SPR_INDEX_SYS_GPR373 = 1397, SPR_INDEX_SYS_GPR374 = 1398 + , SPR_INDEX_SYS_GPR375 = 1399, SPR_INDEX_SYS_GPR376 = 1400, SPR_INDEX_SYS_GPR377 = 1401, SPR_INDEX_SYS_GPR378 = 1402 + , SPR_INDEX_SYS_GPR379 = 1403, SPR_INDEX_SYS_GPR380 = 1404, SPR_INDEX_SYS_GPR381 = 1405, SPR_INDEX_SYS_GPR382 = 1406 + , SPR_INDEX_SYS_GPR383 = 1407, SPR_INDEX_SYS_GPR384 = 1408, SPR_INDEX_SYS_GPR385 = 1409, SPR_INDEX_SYS_GPR386 = 1410 + , SPR_INDEX_SYS_GPR387 = 1411, SPR_INDEX_SYS_GPR388 = 1412, SPR_INDEX_SYS_GPR389 = 1413, SPR_INDEX_SYS_GPR390 = 1414 + , SPR_INDEX_SYS_GPR391 = 1415, SPR_INDEX_SYS_GPR392 = 1416, SPR_INDEX_SYS_GPR393 = 1417, SPR_INDEX_SYS_GPR394 = 1418 + , SPR_INDEX_SYS_GPR395 = 1419, SPR_INDEX_SYS_GPR396 = 1420, SPR_INDEX_SYS_GPR397 = 1421, SPR_INDEX_SYS_GPR398 = 1422 + , SPR_INDEX_SYS_GPR399 = 1423, SPR_INDEX_SYS_GPR400 = 1424, SPR_INDEX_SYS_GPR401 = 1425, SPR_INDEX_SYS_GPR402 = 1426 + , SPR_INDEX_SYS_GPR403 = 1427, SPR_INDEX_SYS_GPR404 = 1428, SPR_INDEX_SYS_GPR405 = 1429, SPR_INDEX_SYS_GPR406 = 1430 + , SPR_INDEX_SYS_GPR407 = 1431, SPR_INDEX_SYS_GPR408 = 1432, SPR_INDEX_SYS_GPR409 = 1433, SPR_INDEX_SYS_GPR410 = 1434 + , SPR_INDEX_SYS_GPR411 = 1435, SPR_INDEX_SYS_GPR412 = 1436, SPR_INDEX_SYS_GPR413 = 1437, SPR_INDEX_SYS_GPR414 = 1438 + , SPR_INDEX_SYS_GPR415 = 1439, SPR_INDEX_SYS_GPR416 = 1440, SPR_INDEX_SYS_GPR417 = 1441, SPR_INDEX_SYS_GPR418 = 1442 + , SPR_INDEX_SYS_GPR419 = 1443, SPR_INDEX_SYS_GPR420 = 1444, SPR_INDEX_SYS_GPR421 = 1445, SPR_INDEX_SYS_GPR422 = 1446 + , SPR_INDEX_SYS_GPR423 = 1447, SPR_INDEX_SYS_GPR424 = 1448, SPR_INDEX_SYS_GPR425 = 1449, SPR_INDEX_SYS_GPR426 = 1450 + , SPR_INDEX_SYS_GPR427 = 1451, SPR_INDEX_SYS_GPR428 = 1452, SPR_INDEX_SYS_GPR429 = 1453, SPR_INDEX_SYS_GPR430 = 1454 + , SPR_INDEX_SYS_GPR431 = 1455, SPR_INDEX_SYS_GPR432 = 1456, SPR_INDEX_SYS_GPR433 = 1457, SPR_INDEX_SYS_GPR434 = 1458 + , SPR_INDEX_SYS_GPR435 = 1459, SPR_INDEX_SYS_GPR436 = 1460, SPR_INDEX_SYS_GPR437 = 1461, SPR_INDEX_SYS_GPR438 = 1462 + , SPR_INDEX_SYS_GPR439 = 1463, SPR_INDEX_SYS_GPR440 = 1464, SPR_INDEX_SYS_GPR441 = 1465, SPR_INDEX_SYS_GPR442 = 1466 + , SPR_INDEX_SYS_GPR443 = 1467, SPR_INDEX_SYS_GPR444 = 1468, SPR_INDEX_SYS_GPR445 = 1469, SPR_INDEX_SYS_GPR446 = 1470 + , SPR_INDEX_SYS_GPR447 = 1471, SPR_INDEX_SYS_GPR448 = 1472, SPR_INDEX_SYS_GPR449 = 1473, SPR_INDEX_SYS_GPR450 = 1474 + , SPR_INDEX_SYS_GPR451 = 1475, SPR_INDEX_SYS_GPR452 = 1476, SPR_INDEX_SYS_GPR453 = 1477, SPR_INDEX_SYS_GPR454 = 1478 + , SPR_INDEX_SYS_GPR455 = 1479, SPR_INDEX_SYS_GPR456 = 1480, SPR_INDEX_SYS_GPR457 = 1481, SPR_INDEX_SYS_GPR458 = 1482 + , SPR_INDEX_SYS_GPR459 = 1483, SPR_INDEX_SYS_GPR460 = 1484, SPR_INDEX_SYS_GPR461 = 1485, SPR_INDEX_SYS_GPR462 = 1486 + , SPR_INDEX_SYS_GPR463 = 1487, SPR_INDEX_SYS_GPR464 = 1488, SPR_INDEX_SYS_GPR465 = 1489, SPR_INDEX_SYS_GPR466 = 1490 + , SPR_INDEX_SYS_GPR467 = 1491, SPR_INDEX_SYS_GPR468 = 1492, SPR_INDEX_SYS_GPR469 = 1493, SPR_INDEX_SYS_GPR470 = 1494 + , SPR_INDEX_SYS_GPR471 = 1495, SPR_INDEX_SYS_GPR472 = 1496, SPR_INDEX_SYS_GPR473 = 1497, SPR_INDEX_SYS_GPR474 = 1498 + , SPR_INDEX_SYS_GPR475 = 1499, SPR_INDEX_SYS_GPR476 = 1500, SPR_INDEX_SYS_GPR477 = 1501, SPR_INDEX_SYS_GPR478 = 1502 + , SPR_INDEX_SYS_GPR479 = 1503, SPR_INDEX_SYS_GPR480 = 1504, SPR_INDEX_SYS_GPR481 = 1505, SPR_INDEX_SYS_GPR482 = 1506 + , SPR_INDEX_SYS_GPR483 = 1507, SPR_INDEX_SYS_GPR484 = 1508, SPR_INDEX_SYS_GPR485 = 1509, SPR_INDEX_SYS_GPR486 = 1510 + , SPR_INDEX_SYS_GPR487 = 1511, SPR_INDEX_SYS_GPR488 = 1512, SPR_INDEX_SYS_GPR489 = 1513, SPR_INDEX_SYS_GPR490 = 1514 + , SPR_INDEX_SYS_GPR491 = 1515, SPR_INDEX_SYS_GPR492 = 1516, SPR_INDEX_SYS_GPR493 = 1517, SPR_INDEX_SYS_GPR494 = 1518 + , SPR_INDEX_SYS_GPR495 = 1519, SPR_INDEX_SYS_GPR496 = 1520, SPR_INDEX_SYS_GPR497 = 1521, SPR_INDEX_SYS_GPR498 = 1522 + , SPR_INDEX_SYS_GPR499 = 1523, SPR_INDEX_SYS_GPR500 = 1524, SPR_INDEX_SYS_GPR501 = 1525, SPR_INDEX_SYS_GPR502 = 1526 + , SPR_INDEX_SYS_GPR503 = 1527, SPR_INDEX_SYS_GPR504 = 1528, SPR_INDEX_SYS_GPR505 = 1529, SPR_INDEX_SYS_GPR506 = 1530 + , SPR_INDEX_SYS_GPR507 = 1531, SPR_INDEX_SYS_GPR508 = 1532, SPR_INDEX_SYS_GPR509 = 1533, SPR_INDEX_SYS_GPR510 = 1534 + , SPR_INDEX_SYS_GPR511 = 1535, SPR_INDEX_MAC_MACLO = 1, SPR_INDEX_MAC_MACHI = 2, SPR_INDEX_TICK_TTMR = 0 +} SPR_REG_INDICES; + +/* Enum declaration for SPR field msb positions. */ +typedef enum spr_field_msbs { + SPR_FIELD_MSB_SYS_VR_REV = 5, SPR_FIELD_MSB_SYS_VR_CFG = 23, SPR_FIELD_MSB_SYS_VR_VER = 31, SPR_FIELD_MSB_SYS_UPR_UP = 0 + , SPR_FIELD_MSB_SYS_UPR_DCP = 1, SPR_FIELD_MSB_SYS_UPR_ICP = 2, SPR_FIELD_MSB_SYS_UPR_DMP = 3, SPR_FIELD_MSB_SYS_UPR_MP = 4 + , SPR_FIELD_MSB_SYS_UPR_IMP = 5, SPR_FIELD_MSB_SYS_UPR_DUP = 6, SPR_FIELD_MSB_SYS_UPR_PCUP = 7, SPR_FIELD_MSB_SYS_UPR_PICP = 8 + , SPR_FIELD_MSB_SYS_UPR_PMP = 9, SPR_FIELD_MSB_SYS_UPR_TTP = 10, SPR_FIELD_MSB_SYS_UPR_CUP = 31, SPR_FIELD_MSB_SYS_CPUCFGR_NSGR = 3 + , SPR_FIELD_MSB_SYS_CPUCFGR_CGF = 4, SPR_FIELD_MSB_SYS_CPUCFGR_OB32S = 5, SPR_FIELD_MSB_SYS_CPUCFGR_OB64S = 6, SPR_FIELD_MSB_SYS_CPUCFGR_OF32S = 7 + , SPR_FIELD_MSB_SYS_CPUCFGR_OF64S = 8, SPR_FIELD_MSB_SYS_CPUCFGR_OV64S = 9, SPR_FIELD_MSB_SYS_CPUCFGR_ND = 10, SPR_FIELD_MSB_SYS_SR_SM = 0 + , SPR_FIELD_MSB_SYS_SR_TEE = 1, SPR_FIELD_MSB_SYS_SR_IEE = 2, SPR_FIELD_MSB_SYS_SR_DCE = 3, SPR_FIELD_MSB_SYS_SR_ICE = 4 + , SPR_FIELD_MSB_SYS_SR_DME = 5, SPR_FIELD_MSB_SYS_SR_IME = 6, SPR_FIELD_MSB_SYS_SR_LEE = 7, SPR_FIELD_MSB_SYS_SR_CE = 8 + , SPR_FIELD_MSB_SYS_SR_F = 9, SPR_FIELD_MSB_SYS_SR_CY = 10, SPR_FIELD_MSB_SYS_SR_OV = 11, SPR_FIELD_MSB_SYS_SR_OVE = 12 + , SPR_FIELD_MSB_SYS_SR_DSX = 13, SPR_FIELD_MSB_SYS_SR_EPH = 14, SPR_FIELD_MSB_SYS_SR_FO = 15, SPR_FIELD_MSB_SYS_SR_SUMRA = 16 + , SPR_FIELD_MSB_SYS_SR_CID = 31, SPR_FIELD_MSB_SYS_FPCSR_FPEE = 0, SPR_FIELD_MSB_SYS_FPCSR_RM = 2, SPR_FIELD_MSB_SYS_FPCSR_OVF = 3 + , SPR_FIELD_MSB_SYS_FPCSR_UNF = 4, SPR_FIELD_MSB_SYS_FPCSR_SNF = 5, SPR_FIELD_MSB_SYS_FPCSR_QNF = 6, SPR_FIELD_MSB_SYS_FPCSR_ZF = 7 + , SPR_FIELD_MSB_SYS_FPCSR_IXF = 8, SPR_FIELD_MSB_SYS_FPCSR_IVF = 9, SPR_FIELD_MSB_SYS_FPCSR_INF = 10, SPR_FIELD_MSB_SYS_FPCSR_DZF = 11 +} SPR_FIELD_MSBS; + +/* Enum declaration for SPR field lsb positions. */ +typedef enum spr_field_lsbs { + SPR_FIELD_SIZE_SYS_VR_REV = 0, SPR_FIELD_SIZE_SYS_VR_CFG = 16, SPR_FIELD_SIZE_SYS_VR_VER = 24, SPR_FIELD_SIZE_SYS_UPR_UP = 0 + , SPR_FIELD_SIZE_SYS_UPR_DCP = 1, SPR_FIELD_SIZE_SYS_UPR_ICP = 2, SPR_FIELD_SIZE_SYS_UPR_DMP = 3, SPR_FIELD_SIZE_SYS_UPR_MP = 4 + , SPR_FIELD_SIZE_SYS_UPR_IMP = 5, SPR_FIELD_SIZE_SYS_UPR_DUP = 6, SPR_FIELD_SIZE_SYS_UPR_PCUP = 7, SPR_FIELD_SIZE_SYS_UPR_PICP = 8 + , SPR_FIELD_SIZE_SYS_UPR_PMP = 9, SPR_FIELD_SIZE_SYS_UPR_TTP = 10, SPR_FIELD_SIZE_SYS_UPR_CUP = 24, SPR_FIELD_SIZE_SYS_CPUCFGR_NSGR = 0 + , SPR_FIELD_SIZE_SYS_CPUCFGR_CGF = 4, SPR_FIELD_SIZE_SYS_CPUCFGR_OB32S = 5, SPR_FIELD_SIZE_SYS_CPUCFGR_OB64S = 6, SPR_FIELD_SIZE_SYS_CPUCFGR_OF32S = 7 + , SPR_FIELD_SIZE_SYS_CPUCFGR_OF64S = 8, SPR_FIELD_SIZE_SYS_CPUCFGR_OV64S = 9, SPR_FIELD_SIZE_SYS_CPUCFGR_ND = 10, SPR_FIELD_SIZE_SYS_SR_SM = 0 + , SPR_FIELD_SIZE_SYS_SR_TEE = 1, SPR_FIELD_SIZE_SYS_SR_IEE = 2, SPR_FIELD_SIZE_SYS_SR_DCE = 3, SPR_FIELD_SIZE_SYS_SR_ICE = 4 + , SPR_FIELD_SIZE_SYS_SR_DME = 5, SPR_FIELD_SIZE_SYS_SR_IME = 6, SPR_FIELD_SIZE_SYS_SR_LEE = 7, SPR_FIELD_SIZE_SYS_SR_CE = 8 + , SPR_FIELD_SIZE_SYS_SR_F = 9, SPR_FIELD_SIZE_SYS_SR_CY = 10, SPR_FIELD_SIZE_SYS_SR_OV = 11, SPR_FIELD_SIZE_SYS_SR_OVE = 12 + , SPR_FIELD_SIZE_SYS_SR_DSX = 13, SPR_FIELD_SIZE_SYS_SR_EPH = 14, SPR_FIELD_SIZE_SYS_SR_FO = 15, SPR_FIELD_SIZE_SYS_SR_SUMRA = 16 + , SPR_FIELD_SIZE_SYS_SR_CID = 28, SPR_FIELD_SIZE_SYS_FPCSR_FPEE = 0, SPR_FIELD_SIZE_SYS_FPCSR_RM = 1, SPR_FIELD_SIZE_SYS_FPCSR_OVF = 3 + , SPR_FIELD_SIZE_SYS_FPCSR_UNF = 4, SPR_FIELD_SIZE_SYS_FPCSR_SNF = 5, SPR_FIELD_SIZE_SYS_FPCSR_QNF = 6, SPR_FIELD_SIZE_SYS_FPCSR_ZF = 7 + , SPR_FIELD_SIZE_SYS_FPCSR_IXF = 8, SPR_FIELD_SIZE_SYS_FPCSR_IVF = 9, SPR_FIELD_SIZE_SYS_FPCSR_INF = 10, SPR_FIELD_SIZE_SYS_FPCSR_DZF = 11 +} SPR_FIELD_LSBS; + +/* Enum declaration for SPR field masks. */ +typedef enum spr_field_masks { + SPR_FIELD_MASK_SYS_VR_REV = 63, SPR_FIELD_MASK_SYS_VR_CFG = 16711680, SPR_FIELD_MASK_SYS_VR_VER = 4278190080u, SPR_FIELD_MASK_SYS_UPR_UP = 1 + , SPR_FIELD_MASK_SYS_UPR_DCP = 2, SPR_FIELD_MASK_SYS_UPR_ICP = 4, SPR_FIELD_MASK_SYS_UPR_DMP = 8, SPR_FIELD_MASK_SYS_UPR_MP = 16 + , SPR_FIELD_MASK_SYS_UPR_IMP = 32, SPR_FIELD_MASK_SYS_UPR_DUP = 64, SPR_FIELD_MASK_SYS_UPR_PCUP = 128, SPR_FIELD_MASK_SYS_UPR_PICP = 256 + , SPR_FIELD_MASK_SYS_UPR_PMP = 512, SPR_FIELD_MASK_SYS_UPR_TTP = 1024, SPR_FIELD_MASK_SYS_UPR_CUP = 4278190080u, SPR_FIELD_MASK_SYS_CPUCFGR_NSGR = 15 + , SPR_FIELD_MASK_SYS_CPUCFGR_CGF = 16, SPR_FIELD_MASK_SYS_CPUCFGR_OB32S = 32, SPR_FIELD_MASK_SYS_CPUCFGR_OB64S = 64, SPR_FIELD_MASK_SYS_CPUCFGR_OF32S = 128 + , SPR_FIELD_MASK_SYS_CPUCFGR_OF64S = 256, SPR_FIELD_MASK_SYS_CPUCFGR_OV64S = 512, SPR_FIELD_MASK_SYS_CPUCFGR_ND = 1024, SPR_FIELD_MASK_SYS_SR_SM = 1 + , SPR_FIELD_MASK_SYS_SR_TEE = 2, SPR_FIELD_MASK_SYS_SR_IEE = 4, SPR_FIELD_MASK_SYS_SR_DCE = 8, SPR_FIELD_MASK_SYS_SR_ICE = 16 + , SPR_FIELD_MASK_SYS_SR_DME = 32, SPR_FIELD_MASK_SYS_SR_IME = 64, SPR_FIELD_MASK_SYS_SR_LEE = 128, SPR_FIELD_MASK_SYS_SR_CE = 256 + , SPR_FIELD_MASK_SYS_SR_F = 512, SPR_FIELD_MASK_SYS_SR_CY = 1024, SPR_FIELD_MASK_SYS_SR_OV = 2048, SPR_FIELD_MASK_SYS_SR_OVE = 4096 + , SPR_FIELD_MASK_SYS_SR_DSX = 8192, SPR_FIELD_MASK_SYS_SR_EPH = 16384, SPR_FIELD_MASK_SYS_SR_FO = 32768, SPR_FIELD_MASK_SYS_SR_SUMRA = 65536 + , SPR_FIELD_MASK_SYS_SR_CID = 4026531840u, SPR_FIELD_MASK_SYS_FPCSR_FPEE = 1, SPR_FIELD_MASK_SYS_FPCSR_RM = 6, SPR_FIELD_MASK_SYS_FPCSR_OVF = 8 + , SPR_FIELD_MASK_SYS_FPCSR_UNF = 16, SPR_FIELD_MASK_SYS_FPCSR_SNF = 32, SPR_FIELD_MASK_SYS_FPCSR_QNF = 64, SPR_FIELD_MASK_SYS_FPCSR_ZF = 128 + , SPR_FIELD_MASK_SYS_FPCSR_IXF = 256, SPR_FIELD_MASK_SYS_FPCSR_IVF = 512, SPR_FIELD_MASK_SYS_FPCSR_INF = 1024, SPR_FIELD_MASK_SYS_FPCSR_DZF = 2048 +} SPR_FIELD_MASKS; + +/* Enum declaration for insn main opcode enums. */ +typedef enum insn_opcode { + OPC_J = 0, OPC_JAL = 1, OPC_BNF = 3, OPC_BF = 4 + , OPC_NOP = 5, OPC_MOVHIMACRC = 6, OPC_SYSTRAPSYNCS = 8, OPC_RFE = 9 + , OPC_VECTOR = 10, OPC_JR = 17, OPC_JALR = 18, OPC_MACI = 19 + , OPC_LWA = 27, OPC_CUST1 = 28, OPC_CUST2 = 29, OPC_CUST3 = 30 + , OPC_CUST4 = 31, OPC_LD = 32, OPC_LWZ = 33, OPC_LWS = 34 + , OPC_LBZ = 35, OPC_LBS = 36, OPC_LHZ = 37, OPC_LHS = 38 + , OPC_ADDI = 39, OPC_ADDIC = 40, OPC_ANDI = 41, OPC_ORI = 42 + , OPC_XORI = 43, OPC_MULI = 44, OPC_MFSPR = 45, OPC_SHROTI = 46 + , OPC_SFI = 47, OPC_MTSPR = 48, OPC_MAC = 49, OPC_FLOAT = 50 + , OPC_SWA = 51, OPC_SD = 52, OPC_SW = 53, OPC_SB = 54 + , OPC_SH = 55, OPC_ALU = 56, OPC_SF = 57, OPC_CUST5 = 60 + , OPC_CUST6 = 61, OPC_CUST7 = 62, OPC_CUST8 = 63 +} INSN_OPCODE; + +/* Enum declaration for systrapsync insn opcode enums. */ +typedef enum insn_opcode_systrapsyncs { + OPC_SYSTRAPSYNCS_SYSCALL = 0, OPC_SYSTRAPSYNCS_TRAP = 8, OPC_SYSTRAPSYNCS_MSYNC = 16, OPC_SYSTRAPSYNCS_PSYNC = 20 + , OPC_SYSTRAPSYNCS_CSYNC = 24 +} INSN_OPCODE_SYSTRAPSYNCS; + +/* Enum declaration for movhi/macrc insn opcode enums. */ +typedef enum insn_opcode_movehimacrc { + OPC_MOVHIMACRC_MOVHI, OPC_MOVHIMACRC_MACRC +} INSN_OPCODE_MOVEHIMACRC; + +/* Enum declaration for multiply/accumulate insn opcode enums. */ +typedef enum insn_opcode_mac { + OPC_MAC_MAC = 1, OPC_MAC_MSB = 2 +} INSN_OPCODE_MAC; + +/* Enum declaration for shift/rotate insn opcode enums. */ +typedef enum insn_opcode_shorts { + OPC_SHROTS_SLL, OPC_SHROTS_SRL, OPC_SHROTS_SRA, OPC_SHROTS_ROR +} INSN_OPCODE_SHORTS; + +/* Enum declaration for extend byte/half opcode enums. */ +typedef enum insn_opcode_extbhs { + OPC_EXTBHS_EXTHS, OPC_EXTBHS_EXTBS, OPC_EXTBHS_EXTHZ, OPC_EXTBHS_EXTBZ +} INSN_OPCODE_EXTBHS; + +/* Enum declaration for extend word opcode enums. */ +typedef enum insn_opcode_extws { + OPC_EXTWS_EXTWS, OPC_EXTWS_EXTWZ +} INSN_OPCODE_EXTWS; + +/* Enum declaration for alu reg/reg insn opcode enums. */ +typedef enum insn_opcode_alu_regreg { + OPC_ALU_REGREG_ADD = 0, OPC_ALU_REGREG_ADDC = 1, OPC_ALU_REGREG_SUB = 2, OPC_ALU_REGREG_AND = 3 + , OPC_ALU_REGREG_OR = 4, OPC_ALU_REGREG_XOR = 5, OPC_ALU_REGREG_MUL = 6, OPC_ALU_REGREG_SHROT = 8 + , OPC_ALU_REGREG_DIV = 9, OPC_ALU_REGREG_DIVU = 10, OPC_ALU_REGREG_MULU = 11, OPC_ALU_REGREG_EXTBH = 12 + , OPC_ALU_REGREG_EXTW = 13, OPC_ALU_REGREG_CMOV = 14, OPC_ALU_REGREG_FFL1 = 15 +} INSN_OPCODE_ALU_REGREG; + +/* Enum declaration for setflag insn opcode enums. */ +typedef enum insn_opcode_setflag { + OPC_SF_EQ = 0, OPC_SF_NE = 1, OPC_SF_GTU = 2, OPC_SF_GEU = 3 + , OPC_SF_LTU = 4, OPC_SF_LEU = 5, OPC_SF_GTS = 10, OPC_SF_GES = 11 + , OPC_SF_LTS = 12, OPC_SF_LES = 13 +} INSN_OPCODE_SETFLAG; + +/* Enum declaration for floating point reg/reg insn opcode enums. */ +typedef enum insn_opcode_float_regreg { + OPC_FLOAT_REGREG_ADD_S = 0, OPC_FLOAT_REGREG_SUB_S = 1, OPC_FLOAT_REGREG_MUL_S = 2, OPC_FLOAT_REGREG_DIV_S = 3 + , OPC_FLOAT_REGREG_ITOF_S = 4, OPC_FLOAT_REGREG_FTOI_S = 5, OPC_FLOAT_REGREG_REM_S = 6, OPC_FLOAT_REGREG_MADD_S = 7 + , OPC_FLOAT_REGREG_SFEQ_S = 8, OPC_FLOAT_REGREG_SFNE_S = 9, OPC_FLOAT_REGREG_SFGT_S = 10, OPC_FLOAT_REGREG_SFGE_S = 11 + , OPC_FLOAT_REGREG_SFLT_S = 12, OPC_FLOAT_REGREG_SFLE_S = 13, OPC_FLOAT_REGREG_ADD_D = 16, OPC_FLOAT_REGREG_SUB_D = 17 + , OPC_FLOAT_REGREG_MUL_D = 18, OPC_FLOAT_REGREG_DIV_D = 19, OPC_FLOAT_REGREG_ITOF_D = 20, OPC_FLOAT_REGREG_FTOI_D = 21 + , OPC_FLOAT_REGREG_REM_D = 22, OPC_FLOAT_REGREG_MADD_D = 23, OPC_FLOAT_REGREG_SFEQ_D = 24, OPC_FLOAT_REGREG_SFNE_D = 25 + , OPC_FLOAT_REGREG_SFGT_D = 26, OPC_FLOAT_REGREG_SFGE_D = 27, OPC_FLOAT_REGREG_SFLT_D = 28, OPC_FLOAT_REGREG_SFLE_D = 29 + , OPC_FLOAT_REGREG_CUST1_S = 208, OPC_FLOAT_REGREG_CUST1_D = 224 +} INSN_OPCODE_FLOAT_REGREG; + +/* Attributes. */ + +/* Enum declaration for machine type selection. */ +typedef enum mach_attr { + MACH_BASE, MACH_OR32, MACH_OR32ND, MACH_OR64 + , MACH_OR64ND, MACH_MAX +} MACH_ATTR; + +/* Enum declaration for instruction set selection. */ +typedef enum isa_attr { + ISA_OPENRISC, ISA_MAX +} ISA_ATTR; + +/* Number of architecture variants. */ +#define MAX_ISAS 1 +#define MAX_MACHS ((int) MACH_MAX) + +/* Ifield support. */ + +/* Ifield attribute indices. */ + +/* Enum declaration for cgen_ifld attrs. */ +typedef enum cgen_ifld_attr { + CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED + , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31 + , CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS +} CGEN_IFLD_ATTR; + +/* Number of non-boolean elements in cgen_ifld_attr. */ +#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1) + +/* cgen_ifld attribute accessor macros. */ +#define CGEN_ATTR_CGEN_IFLD_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_IFLD_MACH-CGEN_IFLD_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_IFLD_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_IFLD_PCREL_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_PCREL_ADDR)) != 0) +#define CGEN_ATTR_CGEN_IFLD_ABS_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_ABS_ADDR)) != 0) +#define CGEN_ATTR_CGEN_IFLD_RESERVED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_RESERVED)) != 0) +#define CGEN_ATTR_CGEN_IFLD_SIGN_OPT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_SIGN_OPT)) != 0) +#define CGEN_ATTR_CGEN_IFLD_SIGNED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_IFLD_SIGNED)) != 0) + +/* Enum declaration for or1k ifield types. */ +typedef enum ifield_type { + OR1K_F_NIL, OR1K_F_ANYOF, OR1K_F_OPCODE, OR1K_F_R1 + , OR1K_F_R2, OR1K_F_R3, OR1K_F_OP_25_2, OR1K_F_OP_25_5 + , OR1K_F_OP_16_1, OR1K_F_OP_7_4, OR1K_F_OP_3_4, OR1K_F_OP_9_2 + , OR1K_F_OP_9_4, OR1K_F_OP_7_8, OR1K_F_OP_7_2, OR1K_F_RESV_25_26 + , OR1K_F_RESV_25_10, OR1K_F_RESV_25_5, OR1K_F_RESV_23_8, OR1K_F_RESV_20_21 + , OR1K_F_RESV_20_5, OR1K_F_RESV_20_4, OR1K_F_RESV_15_8, OR1K_F_RESV_15_6 + , OR1K_F_RESV_10_11, OR1K_F_RESV_10_7, OR1K_F_RESV_10_3, OR1K_F_RESV_10_1 + , OR1K_F_RESV_7_4, OR1K_F_RESV_5_2, OR1K_F_IMM16_25_5, OR1K_F_IMM16_10_11 + , OR1K_F_DISP26, OR1K_F_UIMM16, OR1K_F_SIMM16, OR1K_F_UIMM6 + , OR1K_F_UIMM16_SPLIT, OR1K_F_SIMM16_SPLIT, OR1K_F_MAX +} IFIELD_TYPE; + +#define MAX_IFLD ((int) OR1K_F_MAX) + +/* Hardware attribute indices. */ + +/* Enum declaration for cgen_hw attrs. */ +typedef enum cgen_hw_attr { + CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE + , CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS +} CGEN_HW_ATTR; + +/* Number of non-boolean elements in cgen_hw_attr. */ +#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1) + +/* cgen_hw attribute accessor macros. */ +#define CGEN_ATTR_CGEN_HW_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_HW_MACH-CGEN_HW_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_HW_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_HW_CACHE_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_CACHE_ADDR)) != 0) +#define CGEN_ATTR_CGEN_HW_PC_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_PC)) != 0) +#define CGEN_ATTR_CGEN_HW_PROFILE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_HW_PROFILE)) != 0) + +/* Enum declaration for or1k hardware types. */ +typedef enum cgen_hw_type { + HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR + , HW_H_IADDR, HW_H_PC, HW_H_FSR, HW_H_FDR + , HW_H_SPR, HW_H_GPR, HW_H_SYS_VR, HW_H_SYS_UPR + , HW_H_SYS_CPUCFGR, HW_H_SYS_DMMUCFGR, HW_H_SYS_IMMUCFGR, HW_H_SYS_DCCFGR + , HW_H_SYS_ICCFGR, HW_H_SYS_DCFGR, HW_H_SYS_PCCFGR, HW_H_SYS_NPC + , HW_H_SYS_SR, HW_H_SYS_PPC, HW_H_SYS_FPCSR, HW_H_SYS_EPCR0 + , HW_H_SYS_EPCR1, HW_H_SYS_EPCR2, HW_H_SYS_EPCR3, HW_H_SYS_EPCR4 + , HW_H_SYS_EPCR5, HW_H_SYS_EPCR6, HW_H_SYS_EPCR7, HW_H_SYS_EPCR8 + , HW_H_SYS_EPCR9, HW_H_SYS_EPCR10, HW_H_SYS_EPCR11, HW_H_SYS_EPCR12 + , HW_H_SYS_EPCR13, HW_H_SYS_EPCR14, HW_H_SYS_EPCR15, HW_H_SYS_EEAR0 + , HW_H_SYS_EEAR1, HW_H_SYS_EEAR2, HW_H_SYS_EEAR3, HW_H_SYS_EEAR4 + , HW_H_SYS_EEAR5, HW_H_SYS_EEAR6, HW_H_SYS_EEAR7, HW_H_SYS_EEAR8 + , HW_H_SYS_EEAR9, HW_H_SYS_EEAR10, HW_H_SYS_EEAR11, HW_H_SYS_EEAR12 + , HW_H_SYS_EEAR13, HW_H_SYS_EEAR14, HW_H_SYS_EEAR15, HW_H_SYS_ESR0 + , HW_H_SYS_ESR1, HW_H_SYS_ESR2, HW_H_SYS_ESR3, HW_H_SYS_ESR4 + , HW_H_SYS_ESR5, HW_H_SYS_ESR6, HW_H_SYS_ESR7, HW_H_SYS_ESR8 + , HW_H_SYS_ESR9, HW_H_SYS_ESR10, HW_H_SYS_ESR11, HW_H_SYS_ESR12 + , HW_H_SYS_ESR13, HW_H_SYS_ESR14, HW_H_SYS_ESR15, HW_H_SYS_GPR0 + , HW_H_SYS_GPR1, HW_H_SYS_GPR2, HW_H_SYS_GPR3, HW_H_SYS_GPR4 + , HW_H_SYS_GPR5, HW_H_SYS_GPR6, HW_H_SYS_GPR7, HW_H_SYS_GPR8 + , HW_H_SYS_GPR9, HW_H_SYS_GPR10, HW_H_SYS_GPR11, HW_H_SYS_GPR12 + , HW_H_SYS_GPR13, HW_H_SYS_GPR14, HW_H_SYS_GPR15, HW_H_SYS_GPR16 + , HW_H_SYS_GPR17, HW_H_SYS_GPR18, HW_H_SYS_GPR19, HW_H_SYS_GPR20 + , HW_H_SYS_GPR21, HW_H_SYS_GPR22, HW_H_SYS_GPR23, HW_H_SYS_GPR24 + , HW_H_SYS_GPR25, HW_H_SYS_GPR26, HW_H_SYS_GPR27, HW_H_SYS_GPR28 + , HW_H_SYS_GPR29, HW_H_SYS_GPR30, HW_H_SYS_GPR31, HW_H_SYS_GPR32 + , HW_H_SYS_GPR33, HW_H_SYS_GPR34, HW_H_SYS_GPR35, HW_H_SYS_GPR36 + , HW_H_SYS_GPR37, HW_H_SYS_GPR38, HW_H_SYS_GPR39, HW_H_SYS_GPR40 + , HW_H_SYS_GPR41, HW_H_SYS_GPR42, HW_H_SYS_GPR43, HW_H_SYS_GPR44 + , HW_H_SYS_GPR45, HW_H_SYS_GPR46, HW_H_SYS_GPR47, HW_H_SYS_GPR48 + , HW_H_SYS_GPR49, HW_H_SYS_GPR50, HW_H_SYS_GPR51, HW_H_SYS_GPR52 + , HW_H_SYS_GPR53, HW_H_SYS_GPR54, HW_H_SYS_GPR55, HW_H_SYS_GPR56 + , HW_H_SYS_GPR57, HW_H_SYS_GPR58, HW_H_SYS_GPR59, HW_H_SYS_GPR60 + , HW_H_SYS_GPR61, HW_H_SYS_GPR62, HW_H_SYS_GPR63, HW_H_SYS_GPR64 + , HW_H_SYS_GPR65, HW_H_SYS_GPR66, HW_H_SYS_GPR67, HW_H_SYS_GPR68 + , HW_H_SYS_GPR69, HW_H_SYS_GPR70, HW_H_SYS_GPR71, HW_H_SYS_GPR72 + , HW_H_SYS_GPR73, HW_H_SYS_GPR74, HW_H_SYS_GPR75, HW_H_SYS_GPR76 + , HW_H_SYS_GPR77, HW_H_SYS_GPR78, HW_H_SYS_GPR79, HW_H_SYS_GPR80 + , HW_H_SYS_GPR81, HW_H_SYS_GPR82, HW_H_SYS_GPR83, HW_H_SYS_GPR84 + , HW_H_SYS_GPR85, HW_H_SYS_GPR86, HW_H_SYS_GPR87, HW_H_SYS_GPR88 + , HW_H_SYS_GPR89, HW_H_SYS_GPR90, HW_H_SYS_GPR91, HW_H_SYS_GPR92 + , HW_H_SYS_GPR93, HW_H_SYS_GPR94, HW_H_SYS_GPR95, HW_H_SYS_GPR96 + , HW_H_SYS_GPR97, HW_H_SYS_GPR98, HW_H_SYS_GPR99, HW_H_SYS_GPR100 + , HW_H_SYS_GPR101, HW_H_SYS_GPR102, HW_H_SYS_GPR103, HW_H_SYS_GPR104 + , HW_H_SYS_GPR105, HW_H_SYS_GPR106, HW_H_SYS_GPR107, HW_H_SYS_GPR108 + , HW_H_SYS_GPR109, HW_H_SYS_GPR110, HW_H_SYS_GPR111, HW_H_SYS_GPR112 + , HW_H_SYS_GPR113, HW_H_SYS_GPR114, HW_H_SYS_GPR115, HW_H_SYS_GPR116 + , HW_H_SYS_GPR117, HW_H_SYS_GPR118, HW_H_SYS_GPR119, HW_H_SYS_GPR120 + , HW_H_SYS_GPR121, HW_H_SYS_GPR122, HW_H_SYS_GPR123, HW_H_SYS_GPR124 + , HW_H_SYS_GPR125, HW_H_SYS_GPR126, HW_H_SYS_GPR127, HW_H_SYS_GPR128 + , HW_H_SYS_GPR129, HW_H_SYS_GPR130, HW_H_SYS_GPR131, HW_H_SYS_GPR132 + , HW_H_SYS_GPR133, HW_H_SYS_GPR134, HW_H_SYS_GPR135, HW_H_SYS_GPR136 + , HW_H_SYS_GPR137, HW_H_SYS_GPR138, HW_H_SYS_GPR139, HW_H_SYS_GPR140 + , HW_H_SYS_GPR141, HW_H_SYS_GPR142, HW_H_SYS_GPR143, HW_H_SYS_GPR144 + , HW_H_SYS_GPR145, HW_H_SYS_GPR146, HW_H_SYS_GPR147, HW_H_SYS_GPR148 + , HW_H_SYS_GPR149, HW_H_SYS_GPR150, HW_H_SYS_GPR151, HW_H_SYS_GPR152 + , HW_H_SYS_GPR153, HW_H_SYS_GPR154, HW_H_SYS_GPR155, HW_H_SYS_GPR156 + , HW_H_SYS_GPR157, HW_H_SYS_GPR158, HW_H_SYS_GPR159, HW_H_SYS_GPR160 + , HW_H_SYS_GPR161, HW_H_SYS_GPR162, HW_H_SYS_GPR163, HW_H_SYS_GPR164 + , HW_H_SYS_GPR165, HW_H_SYS_GPR166, HW_H_SYS_GPR167, HW_H_SYS_GPR168 + , HW_H_SYS_GPR169, HW_H_SYS_GPR170, HW_H_SYS_GPR171, HW_H_SYS_GPR172 + , HW_H_SYS_GPR173, HW_H_SYS_GPR174, HW_H_SYS_GPR175, HW_H_SYS_GPR176 + , HW_H_SYS_GPR177, HW_H_SYS_GPR178, HW_H_SYS_GPR179, HW_H_SYS_GPR180 + , HW_H_SYS_GPR181, HW_H_SYS_GPR182, HW_H_SYS_GPR183, HW_H_SYS_GPR184 + , HW_H_SYS_GPR185, HW_H_SYS_GPR186, HW_H_SYS_GPR187, HW_H_SYS_GPR188 + , HW_H_SYS_GPR189, HW_H_SYS_GPR190, HW_H_SYS_GPR191, HW_H_SYS_GPR192 + , HW_H_SYS_GPR193, HW_H_SYS_GPR194, HW_H_SYS_GPR195, HW_H_SYS_GPR196 + , HW_H_SYS_GPR197, HW_H_SYS_GPR198, HW_H_SYS_GPR199, HW_H_SYS_GPR200 + , HW_H_SYS_GPR201, HW_H_SYS_GPR202, HW_H_SYS_GPR203, HW_H_SYS_GPR204 + , HW_H_SYS_GPR205, HW_H_SYS_GPR206, HW_H_SYS_GPR207, HW_H_SYS_GPR208 + , HW_H_SYS_GPR209, HW_H_SYS_GPR210, HW_H_SYS_GPR211, HW_H_SYS_GPR212 + , HW_H_SYS_GPR213, HW_H_SYS_GPR214, HW_H_SYS_GPR215, HW_H_SYS_GPR216 + , HW_H_SYS_GPR217, HW_H_SYS_GPR218, HW_H_SYS_GPR219, HW_H_SYS_GPR220 + , HW_H_SYS_GPR221, HW_H_SYS_GPR222, HW_H_SYS_GPR223, HW_H_SYS_GPR224 + , HW_H_SYS_GPR225, HW_H_SYS_GPR226, HW_H_SYS_GPR227, HW_H_SYS_GPR228 + , HW_H_SYS_GPR229, HW_H_SYS_GPR230, HW_H_SYS_GPR231, HW_H_SYS_GPR232 + , HW_H_SYS_GPR233, HW_H_SYS_GPR234, HW_H_SYS_GPR235, HW_H_SYS_GPR236 + , HW_H_SYS_GPR237, HW_H_SYS_GPR238, HW_H_SYS_GPR239, HW_H_SYS_GPR240 + , HW_H_SYS_GPR241, HW_H_SYS_GPR242, HW_H_SYS_GPR243, HW_H_SYS_GPR244 + , HW_H_SYS_GPR245, HW_H_SYS_GPR246, HW_H_SYS_GPR247, HW_H_SYS_GPR248 + , HW_H_SYS_GPR249, HW_H_SYS_GPR250, HW_H_SYS_GPR251, HW_H_SYS_GPR252 + , HW_H_SYS_GPR253, HW_H_SYS_GPR254, HW_H_SYS_GPR255, HW_H_SYS_GPR256 + , HW_H_SYS_GPR257, HW_H_SYS_GPR258, HW_H_SYS_GPR259, HW_H_SYS_GPR260 + , HW_H_SYS_GPR261, HW_H_SYS_GPR262, HW_H_SYS_GPR263, HW_H_SYS_GPR264 + , HW_H_SYS_GPR265, HW_H_SYS_GPR266, HW_H_SYS_GPR267, HW_H_SYS_GPR268 + , HW_H_SYS_GPR269, HW_H_SYS_GPR270, HW_H_SYS_GPR271, HW_H_SYS_GPR272 + , HW_H_SYS_GPR273, HW_H_SYS_GPR274, HW_H_SYS_GPR275, HW_H_SYS_GPR276 + , HW_H_SYS_GPR277, HW_H_SYS_GPR278, HW_H_SYS_GPR279, HW_H_SYS_GPR280 + , HW_H_SYS_GPR281, HW_H_SYS_GPR282, HW_H_SYS_GPR283, HW_H_SYS_GPR284 + , HW_H_SYS_GPR285, HW_H_SYS_GPR286, HW_H_SYS_GPR287, HW_H_SYS_GPR288 + , HW_H_SYS_GPR289, HW_H_SYS_GPR290, HW_H_SYS_GPR291, HW_H_SYS_GPR292 + , HW_H_SYS_GPR293, HW_H_SYS_GPR294, HW_H_SYS_GPR295, HW_H_SYS_GPR296 + , HW_H_SYS_GPR297, HW_H_SYS_GPR298, HW_H_SYS_GPR299, HW_H_SYS_GPR300 + , HW_H_SYS_GPR301, HW_H_SYS_GPR302, HW_H_SYS_GPR303, HW_H_SYS_GPR304 + , HW_H_SYS_GPR305, HW_H_SYS_GPR306, HW_H_SYS_GPR307, HW_H_SYS_GPR308 + , HW_H_SYS_GPR309, HW_H_SYS_GPR310, HW_H_SYS_GPR311, HW_H_SYS_GPR312 + , HW_H_SYS_GPR313, HW_H_SYS_GPR314, HW_H_SYS_GPR315, HW_H_SYS_GPR316 + , HW_H_SYS_GPR317, HW_H_SYS_GPR318, HW_H_SYS_GPR319, HW_H_SYS_GPR320 + , HW_H_SYS_GPR321, HW_H_SYS_GPR322, HW_H_SYS_GPR323, HW_H_SYS_GPR324 + , HW_H_SYS_GPR325, HW_H_SYS_GPR326, HW_H_SYS_GPR327, HW_H_SYS_GPR328 + , HW_H_SYS_GPR329, HW_H_SYS_GPR330, HW_H_SYS_GPR331, HW_H_SYS_GPR332 + , HW_H_SYS_GPR333, HW_H_SYS_GPR334, HW_H_SYS_GPR335, HW_H_SYS_GPR336 + , HW_H_SYS_GPR337, HW_H_SYS_GPR338, HW_H_SYS_GPR339, HW_H_SYS_GPR340 + , HW_H_SYS_GPR341, HW_H_SYS_GPR342, HW_H_SYS_GPR343, HW_H_SYS_GPR344 + , HW_H_SYS_GPR345, HW_H_SYS_GPR346, HW_H_SYS_GPR347, HW_H_SYS_GPR348 + , HW_H_SYS_GPR349, HW_H_SYS_GPR350, HW_H_SYS_GPR351, HW_H_SYS_GPR352 + , HW_H_SYS_GPR353, HW_H_SYS_GPR354, HW_H_SYS_GPR355, HW_H_SYS_GPR356 + , HW_H_SYS_GPR357, HW_H_SYS_GPR358, HW_H_SYS_GPR359, HW_H_SYS_GPR360 + , HW_H_SYS_GPR361, HW_H_SYS_GPR362, HW_H_SYS_GPR363, HW_H_SYS_GPR364 + , HW_H_SYS_GPR365, HW_H_SYS_GPR366, HW_H_SYS_GPR367, HW_H_SYS_GPR368 + , HW_H_SYS_GPR369, HW_H_SYS_GPR370, HW_H_SYS_GPR371, HW_H_SYS_GPR372 + , HW_H_SYS_GPR373, HW_H_SYS_GPR374, HW_H_SYS_GPR375, HW_H_SYS_GPR376 + , HW_H_SYS_GPR377, HW_H_SYS_GPR378, HW_H_SYS_GPR379, HW_H_SYS_GPR380 + , HW_H_SYS_GPR381, HW_H_SYS_GPR382, HW_H_SYS_GPR383, HW_H_SYS_GPR384 + , HW_H_SYS_GPR385, HW_H_SYS_GPR386, HW_H_SYS_GPR387, HW_H_SYS_GPR388 + , HW_H_SYS_GPR389, HW_H_SYS_GPR390, HW_H_SYS_GPR391, HW_H_SYS_GPR392 + , HW_H_SYS_GPR393, HW_H_SYS_GPR394, HW_H_SYS_GPR395, HW_H_SYS_GPR396 + , HW_H_SYS_GPR397, HW_H_SYS_GPR398, HW_H_SYS_GPR399, HW_H_SYS_GPR400 + , HW_H_SYS_GPR401, HW_H_SYS_GPR402, HW_H_SYS_GPR403, HW_H_SYS_GPR404 + , HW_H_SYS_GPR405, HW_H_SYS_GPR406, HW_H_SYS_GPR407, HW_H_SYS_GPR408 + , HW_H_SYS_GPR409, HW_H_SYS_GPR410, HW_H_SYS_GPR411, HW_H_SYS_GPR412 + , HW_H_SYS_GPR413, HW_H_SYS_GPR414, HW_H_SYS_GPR415, HW_H_SYS_GPR416 + , HW_H_SYS_GPR417, HW_H_SYS_GPR418, HW_H_SYS_GPR419, HW_H_SYS_GPR420 + , HW_H_SYS_GPR421, HW_H_SYS_GPR422, HW_H_SYS_GPR423, HW_H_SYS_GPR424 + , HW_H_SYS_GPR425, HW_H_SYS_GPR426, HW_H_SYS_GPR427, HW_H_SYS_GPR428 + , HW_H_SYS_GPR429, HW_H_SYS_GPR430, HW_H_SYS_GPR431, HW_H_SYS_GPR432 + , HW_H_SYS_GPR433, HW_H_SYS_GPR434, HW_H_SYS_GPR435, HW_H_SYS_GPR436 + , HW_H_SYS_GPR437, HW_H_SYS_GPR438, HW_H_SYS_GPR439, HW_H_SYS_GPR440 + , HW_H_SYS_GPR441, HW_H_SYS_GPR442, HW_H_SYS_GPR443, HW_H_SYS_GPR444 + , HW_H_SYS_GPR445, HW_H_SYS_GPR446, HW_H_SYS_GPR447, HW_H_SYS_GPR448 + , HW_H_SYS_GPR449, HW_H_SYS_GPR450, HW_H_SYS_GPR451, HW_H_SYS_GPR452 + , HW_H_SYS_GPR453, HW_H_SYS_GPR454, HW_H_SYS_GPR455, HW_H_SYS_GPR456 + , HW_H_SYS_GPR457, HW_H_SYS_GPR458, HW_H_SYS_GPR459, HW_H_SYS_GPR460 + , HW_H_SYS_GPR461, HW_H_SYS_GPR462, HW_H_SYS_GPR463, HW_H_SYS_GPR464 + , HW_H_SYS_GPR465, HW_H_SYS_GPR466, HW_H_SYS_GPR467, HW_H_SYS_GPR468 + , HW_H_SYS_GPR469, HW_H_SYS_GPR470, HW_H_SYS_GPR471, HW_H_SYS_GPR472 + , HW_H_SYS_GPR473, HW_H_SYS_GPR474, HW_H_SYS_GPR475, HW_H_SYS_GPR476 + , HW_H_SYS_GPR477, HW_H_SYS_GPR478, HW_H_SYS_GPR479, HW_H_SYS_GPR480 + , HW_H_SYS_GPR481, HW_H_SYS_GPR482, HW_H_SYS_GPR483, HW_H_SYS_GPR484 + , HW_H_SYS_GPR485, HW_H_SYS_GPR486, HW_H_SYS_GPR487, HW_H_SYS_GPR488 + , HW_H_SYS_GPR489, HW_H_SYS_GPR490, HW_H_SYS_GPR491, HW_H_SYS_GPR492 + , HW_H_SYS_GPR493, HW_H_SYS_GPR494, HW_H_SYS_GPR495, HW_H_SYS_GPR496 + , HW_H_SYS_GPR497, HW_H_SYS_GPR498, HW_H_SYS_GPR499, HW_H_SYS_GPR500 + , HW_H_SYS_GPR501, HW_H_SYS_GPR502, HW_H_SYS_GPR503, HW_H_SYS_GPR504 + , HW_H_SYS_GPR505, HW_H_SYS_GPR506, HW_H_SYS_GPR507, HW_H_SYS_GPR508 + , HW_H_SYS_GPR509, HW_H_SYS_GPR510, HW_H_SYS_GPR511, HW_H_MAC_MACLO + , HW_H_MAC_MACHI, HW_H_TICK_TTMR, HW_H_SYS_VR_REV, HW_H_SYS_VR_CFG + , HW_H_SYS_VR_VER, HW_H_SYS_UPR_UP, HW_H_SYS_UPR_DCP, HW_H_SYS_UPR_ICP + , HW_H_SYS_UPR_DMP, HW_H_SYS_UPR_MP, HW_H_SYS_UPR_IMP, HW_H_SYS_UPR_DUP + , HW_H_SYS_UPR_PCUP, HW_H_SYS_UPR_PICP, HW_H_SYS_UPR_PMP, HW_H_SYS_UPR_TTP + , HW_H_SYS_UPR_CUP, HW_H_SYS_CPUCFGR_NSGR, HW_H_SYS_CPUCFGR_CGF, HW_H_SYS_CPUCFGR_OB32S + , HW_H_SYS_CPUCFGR_OB64S, HW_H_SYS_CPUCFGR_OF32S, HW_H_SYS_CPUCFGR_OF64S, HW_H_SYS_CPUCFGR_OV64S + , HW_H_SYS_CPUCFGR_ND, HW_H_SYS_SR_SM, HW_H_SYS_SR_TEE, HW_H_SYS_SR_IEE + , HW_H_SYS_SR_DCE, HW_H_SYS_SR_ICE, HW_H_SYS_SR_DME, HW_H_SYS_SR_IME + , HW_H_SYS_SR_LEE, HW_H_SYS_SR_CE, HW_H_SYS_SR_F, HW_H_SYS_SR_CY + , HW_H_SYS_SR_OV, HW_H_SYS_SR_OVE, HW_H_SYS_SR_DSX, HW_H_SYS_SR_EPH + , HW_H_SYS_SR_FO, HW_H_SYS_SR_SUMRA, HW_H_SYS_SR_CID, HW_H_SYS_FPCSR_FPEE + , HW_H_SYS_FPCSR_RM, HW_H_SYS_FPCSR_OVF, HW_H_SYS_FPCSR_UNF, HW_H_SYS_FPCSR_SNF + , HW_H_SYS_FPCSR_QNF, HW_H_SYS_FPCSR_ZF, HW_H_SYS_FPCSR_IXF, HW_H_SYS_FPCSR_IVF + , HW_H_SYS_FPCSR_INF, HW_H_SYS_FPCSR_DZF, HW_H_SIMM16, HW_H_UIMM16 + , HW_H_UIMM6, HW_H_ATOMIC_RESERVE, HW_H_ATOMIC_ADDRESS, HW_MAX +} CGEN_HW_TYPE; + +#define MAX_HW ((int) HW_MAX) + +/* Operand attribute indices. */ + +/* Enum declaration for cgen_operand attrs. */ +typedef enum cgen_operand_attr { + CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT + , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY + , CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH, CGEN_OPERAND_END_NBOOLS +} CGEN_OPERAND_ATTR; + +/* Number of non-boolean elements in cgen_operand_attr. */ +#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1) + +/* cgen_operand attribute accessor macros. */ +#define CGEN_ATTR_CGEN_OPERAND_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_MACH-CGEN_OPERAND_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_OPERAND_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_PCREL_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_PCREL_ADDR)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_ABS_ADDR_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_ABS_ADDR)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SIGN_OPT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SIGN_OPT)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SIGNED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SIGNED)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_NEGATIVE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_NEGATIVE)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_RELAX_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_RELAX)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SEM_ONLY_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_OPERAND_SEM_ONLY)) != 0) + +/* Enum declaration for or1k operand types. */ +typedef enum cgen_operand_type { + OR1K_OPERAND_PC, OR1K_OPERAND_SYS_SR, OR1K_OPERAND_SYS_ESR0, OR1K_OPERAND_SYS_EPCR0 + , OR1K_OPERAND_SYS_SR_LEE, OR1K_OPERAND_SYS_SR_F, OR1K_OPERAND_SYS_SR_CY, OR1K_OPERAND_SYS_SR_OV + , OR1K_OPERAND_SYS_SR_OVE, OR1K_OPERAND_SYS_CPUCFGR_OB64S, OR1K_OPERAND_SYS_CPUCFGR_ND, OR1K_OPERAND_SYS_FPCSR_RM + , OR1K_OPERAND_MAC_MACHI, OR1K_OPERAND_MAC_MACLO, OR1K_OPERAND_ATOMIC_RESERVE, OR1K_OPERAND_ATOMIC_ADDRESS + , OR1K_OPERAND_UIMM6, OR1K_OPERAND_RD, OR1K_OPERAND_RA, OR1K_OPERAND_RB + , OR1K_OPERAND_DISP26, OR1K_OPERAND_SIMM16, OR1K_OPERAND_UIMM16, OR1K_OPERAND_SIMM16_SPLIT + , OR1K_OPERAND_UIMM16_SPLIT, OR1K_OPERAND_RDSF, OR1K_OPERAND_RASF, OR1K_OPERAND_RBSF + , OR1K_OPERAND_RDDF, OR1K_OPERAND_RADF, OR1K_OPERAND_RBDF, OR1K_OPERAND_MAX +} CGEN_OPERAND_TYPE; + +/* Number of operands types. */ +#define MAX_OPERANDS 31 + +/* Maximum number of operands referenced by any insn. */ +#define MAX_OPERAND_INSTANCES 9 + +/* Insn attribute indices. */ + +/* Enum declaration for cgen_insn attrs. */ +typedef enum cgen_insn_attr { + CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI + , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAXED + , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_DELAYED_CTI, CGEN_INSN_NOT_IN_DELAY_SLOT + , CGEN_INSN_FORCED_CTI, CGEN_INSN_END_BOOLS, CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH + , CGEN_INSN_END_NBOOLS +} CGEN_INSN_ATTR; + +/* Number of non-boolean elements in cgen_insn_attr. */ +#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1) + +/* cgen_insn attribute accessor macros. */ +#define CGEN_ATTR_CGEN_INSN_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_MACH-CGEN_INSN_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_ALIAS)) != 0) +#define CGEN_ATTR_CGEN_INSN_VIRTUAL_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_INSN_UNCOND_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_UNCOND_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_COND_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_COND_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_SKIP_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_SKIP_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_DELAY_SLOT)) != 0) +#define CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_RELAXABLE)) != 0) +#define CGEN_ATTR_CGEN_INSN_RELAXED_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_RELAXED)) != 0) +#define CGEN_ATTR_CGEN_INSN_NO_DIS_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_NO_DIS)) != 0) +#define CGEN_ATTR_CGEN_INSN_PBB_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_PBB)) != 0) +#define CGEN_ATTR_CGEN_INSN_DELAYED_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_DELAYED_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_NOT_IN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_NOT_IN_DELAY_SLOT)) != 0) +#define CGEN_ATTR_CGEN_INSN_FORCED_CTI_VALUE(attrs) (((attrs)->bool_ & (1 << CGEN_INSN_FORCED_CTI)) != 0) + +/* cgen.h uses things we just defined. */ +#include "opcode/cgen.h" + +extern const struct cgen_ifld or1k_cgen_ifld_table[]; + +/* Attributes. */ +extern const CGEN_ATTR_TABLE or1k_cgen_hardware_attr_table[]; +extern const CGEN_ATTR_TABLE or1k_cgen_ifield_attr_table[]; +extern const CGEN_ATTR_TABLE or1k_cgen_operand_attr_table[]; +extern const CGEN_ATTR_TABLE or1k_cgen_insn_attr_table[]; + +/* Hardware decls. */ + +extern CGEN_KEYWORD or1k_cgen_opval_h_fsr; +extern CGEN_KEYWORD or1k_cgen_opval_h_fdr; +extern CGEN_KEYWORD or1k_cgen_opval_h_gpr; + +extern const CGEN_HW_ENTRY or1k_cgen_hw_table[]; + + + +#endif /* OR1K_CPU_H */ diff -rNU3 dist.orig/opcodes/or1k-dis.c dist/opcodes/or1k-dis.c --- dist.orig/opcodes/or1k-dis.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-dis.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,561 @@ +/* Disassembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + + THIS FILE IS MACHINE GENERATED WITH CGEN. + - the resultant file is machine generated, cgen-dis.in isn't + + Copyright (C) 1996-2014 Free Software Foundation, Inc. + + This file is part of libopcodes. + + 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. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "libiberty.h" +#include "or1k-desc.h" +#include "or1k-opc.h" +#include "opintl.h" + +/* Default text to print if an instruction isn't recognized. */ +#define UNKNOWN_INSN_MSG _("*unknown*") + +static void print_normal + (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); +static void print_address + (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED; +static void print_keyword + (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED; +static void print_insn_normal + (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int); +static int print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned); +static int default_print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED; +static int read_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *, + unsigned long *); + +/* -- disassembler routines inserted here. */ + + +void or1k_cgen_print_operand + (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int); + +/* Main entry point for printing operands. + XINFO is a `void *' and not a `disassemble_info *' to not put a requirement + of dis-asm.h on cgen.h. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +void +or1k_cgen_print_operand (CGEN_CPU_DESC cd, + int opindex, + void * xinfo, + CGEN_FIELDS *fields, + void const *attrs ATTRIBUTE_UNUSED, + bfd_vma pc, + int length) +{ + disassemble_info *info = (disassemble_info *) xinfo; + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + print_address (cd, info, fields->f_disp26, 0|(1<f_r2, 0); + break; + case OR1K_OPERAND_RADF : + print_keyword (cd, info, & or1k_cgen_opval_h_fdr, fields->f_r1, 0); + break; + case OR1K_OPERAND_RASF : + print_keyword (cd, info, & or1k_cgen_opval_h_fsr, fields->f_r2, 0); + break; + case OR1K_OPERAND_RB : + print_keyword (cd, info, & or1k_cgen_opval_h_gpr, fields->f_r3, 0); + break; + case OR1K_OPERAND_RBDF : + print_keyword (cd, info, & or1k_cgen_opval_h_fdr, fields->f_r1, 0); + break; + case OR1K_OPERAND_RBSF : + print_keyword (cd, info, & or1k_cgen_opval_h_fsr, fields->f_r3, 0); + break; + case OR1K_OPERAND_RD : + print_keyword (cd, info, & or1k_cgen_opval_h_gpr, fields->f_r1, 0); + break; + case OR1K_OPERAND_RDDF : + print_keyword (cd, info, & or1k_cgen_opval_h_fdr, fields->f_r1, 0); + break; + case OR1K_OPERAND_RDSF : + print_keyword (cd, info, & or1k_cgen_opval_h_fsr, fields->f_r1, 0); + break; + case OR1K_OPERAND_SIMM16 : + print_normal (cd, info, fields->f_simm16, 0|(1<f_simm16_split, 0|(1<f_uimm16, 0, pc, length); + break; + case OR1K_OPERAND_UIMM16_SPLIT : + print_normal (cd, info, fields->f_uimm16_split, 0|(1<f_uimm6, 0, pc, length); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while printing insn.\n"), + opindex); + abort (); + } +} + +cgen_print_fn * const or1k_cgen_print_handlers[] = +{ + print_insn_normal, +}; + + +void +or1k_cgen_init_dis (CGEN_CPU_DESC cd) +{ + or1k_cgen_init_opcode_table (cd); + or1k_cgen_init_ibld_table (cd); + cd->print_handlers = & or1k_cgen_print_handlers[0]; + cd->print_operand = or1k_cgen_print_operand; +} + + +/* Default print handler. */ + +static void +print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void *dis_info, + long value, + unsigned int attrs, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* nothing to do */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", value); + else + (*info->fprintf_func) (info->stream, "0x%lx", value); +} + +/* Default address handler. */ + +static void +print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void *dis_info, + bfd_vma value, + unsigned int attrs, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* Nothing to do. */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", (long) value); + else + (*info->fprintf_func) (info->stream, "0x%lx", (long) value); +} + +/* Keyword print handler. */ + +static void +print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void *dis_info, + CGEN_KEYWORD *keyword_table, + long value, + unsigned int attrs ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_KEYWORD_ENTRY *ke; + + ke = cgen_keyword_lookup_value (keyword_table, value); + if (ke != NULL) + (*info->fprintf_func) (info->stream, "%s", ke->name); + else + (*info->fprintf_func) (info->stream, "???"); +} + +/* Default insn printer. + + DIS_INFO is defined as `void *' so the disassembler needn't know anything + about disassemble_info. */ + +static void +print_insn_normal (CGEN_CPU_DESC cd, + void *dis_info, + const CGEN_INSN *insn, + CGEN_FIELDS *fields, + bfd_vma pc, + int length) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_INIT_PRINT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + if (CGEN_SYNTAX_MNEMONIC_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn)); + continue; + } + if (CGEN_SYNTAX_CHAR_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn)); + continue; + } + + /* We have an operand. */ + or1k_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info, + fields, CGEN_INSN_ATTRS (insn), pc, length); + } +} + +/* Subroutine of print_insn. Reads an insn into the given buffers and updates + the extract info. + Returns 0 if all is well, non-zero otherwise. */ + +static int +read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + bfd_vma pc, + disassemble_info *info, + bfd_byte *buf, + int buflen, + CGEN_EXTRACT_INFO *ex_info, + unsigned long *insn_value) +{ + int status = (*info->read_memory_func) (pc, buf, buflen, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + ex_info->dis_info = info; + ex_info->valid = (1 << buflen) - 1; + ex_info->insn_bytes = buf; + + *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG); + return 0; +} + +/* Utility to print an insn. + BUF is the base part of the insn, target byte order, BUFLEN bytes long. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +print_insn (CGEN_CPU_DESC cd, + bfd_vma pc, + disassemble_info *info, + bfd_byte *buf, + unsigned int buflen) +{ + CGEN_INSN_INT insn_value; + const CGEN_INSN_LIST *insn_list; + CGEN_EXTRACT_INFO ex_info; + int basesize; + + /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */ + basesize = cd->base_insn_bitsize < buflen * 8 ? + cd->base_insn_bitsize : buflen * 8; + insn_value = cgen_get_insn_value (cd, buf, basesize); + + + /* Fill in ex_info fields like read_insn would. Don't actually call + read_insn, since the incoming buffer is already read (and possibly + modified a la m32r). */ + ex_info.valid = (1 << buflen) - 1; + ex_info.dis_info = info; + ex_info.insn_bytes = buf; + + /* The instructions are stored in hash lists. + Pick the first one and keep trying until we find the right one. */ + + insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value); + while (insn_list != NULL) + { + const CGEN_INSN *insn = insn_list->insn; + CGEN_FIELDS fields; + int length; + unsigned long insn_value_cropped; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not needed as insn shouldn't be in hash lists if not supported. */ + /* Supported by this cpu? */ + if (! or1k_cgen_insn_supported (cd, insn)) + { + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + continue; + } +#endif + + /* Basic bit mask must be correct. */ + /* ??? May wish to allow target to defer this check until the extract + handler. */ + + /* Base size may exceed this instruction's size. Extract the + relevant part from the buffer. */ + if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), + info->endian == BFD_ENDIAN_BIG); + else + insn_value_cropped = insn_value; + + if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn)) + == CGEN_INSN_BASE_VALUE (insn)) + { + /* Printing is handled in two passes. The first pass parses the + machine insn and extracts the fields. The second pass prints + them. */ + + /* Make sure the entire insn is loaded into insn_value, if it + can fit. */ + if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + { + unsigned long full_insn_value; + int rc = read_insn (cd, pc, info, buf, + CGEN_INSN_BITSIZE (insn) / 8, + & ex_info, & full_insn_value); + if (rc != 0) + return rc; + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, full_insn_value, &fields, pc); + } + else + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, insn_value_cropped, &fields, pc); + + /* Length < 0 -> error. */ + if (length < 0) + return length; + if (length > 0) + { + CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length); + /* Length is in bits, result is in bytes. */ + return length / 8; + } + } + + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + } + + return 0; +} + +/* Default value for CGEN_PRINT_INSN. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occured fetching bytes. */ + +#ifndef CGEN_PRINT_INSN +#define CGEN_PRINT_INSN default_print_insn +#endif + +static int +default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) +{ + bfd_byte buf[CGEN_MAX_INSN_SIZE]; + int buflen; + int status; + + /* Attempt to read the base part of the insn. */ + buflen = cd->base_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + + /* Try again with the minimum part, if min < base. */ + if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize)) + { + buflen = cd->min_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + } + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + return print_insn (cd, pc, info, buf, buflen); +} + +/* Main entry point. + Print one instruction from PC on INFO->STREAM. + Return the size of the instruction (in bytes). */ + +typedef struct cpu_desc_list +{ + struct cpu_desc_list *next; + CGEN_BITSET *isa; + int mach; + int endian; + CGEN_CPU_DESC cd; +} cpu_desc_list; + +int +print_insn_or1k (bfd_vma pc, disassemble_info *info) +{ + static cpu_desc_list *cd_list = 0; + cpu_desc_list *cl = 0; + static CGEN_CPU_DESC cd = 0; + static CGEN_BITSET *prev_isa; + static int prev_mach; + static int prev_endian; + int length; + CGEN_BITSET *isa; + int mach; + int endian = (info->endian == BFD_ENDIAN_BIG + ? CGEN_ENDIAN_BIG + : CGEN_ENDIAN_LITTLE); + enum bfd_architecture arch; + + /* ??? gdb will set mach but leave the architecture as "unknown" */ +#ifndef CGEN_BFD_ARCH +#define CGEN_BFD_ARCH bfd_arch_or1k +#endif + arch = info->arch; + if (arch == bfd_arch_unknown) + arch = CGEN_BFD_ARCH; + + /* There's no standard way to compute the machine or isa number + so we leave it to the target. */ +#ifdef CGEN_COMPUTE_MACH + mach = CGEN_COMPUTE_MACH (info); +#else + mach = info->mach; +#endif + +#ifdef CGEN_COMPUTE_ISA + { + static CGEN_BITSET *permanent_isa; + + if (!permanent_isa) + permanent_isa = cgen_bitset_create (MAX_ISAS); + isa = permanent_isa; + cgen_bitset_clear (isa); + cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info)); + } +#else + isa = info->insn_sets; +#endif + + /* If we've switched cpu's, try to find a handle we've used before */ + if (cd + && (cgen_bitset_compare (isa, prev_isa) != 0 + || mach != prev_mach + || endian != prev_endian)) + { + cd = 0; + for (cl = cd_list; cl; cl = cl->next) + { + if (cgen_bitset_compare (cl->isa, isa) == 0 && + cl->mach == mach && + cl->endian == endian) + { + cd = cl->cd; + prev_isa = cd->isas; + break; + } + } + } + + /* If we haven't initialized yet, initialize the opcode table. */ + if (! cd) + { + const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach); + const char *mach_name; + + if (!arch_type) + abort (); + mach_name = arch_type->printable_name; + + prev_isa = cgen_bitset_copy (isa); + prev_mach = mach; + prev_endian = endian; + cd = or1k_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa, + CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, prev_endian, + CGEN_CPU_OPEN_END); + if (!cd) + abort (); + + /* Save this away for future reference. */ + cl = xmalloc (sizeof (struct cpu_desc_list)); + cl->cd = cd; + cl->isa = prev_isa; + cl->mach = mach; + cl->endian = endian; + cl->next = cd_list; + cd_list = cl; + + or1k_cgen_init_dis (cd); + } + + /* We try to have as much common code as possible. + But at this point some targets need to take over. */ + /* ??? Some targets may need a hook elsewhere. Try to avoid this, + but if not possible try to move this hook elsewhere rather than + have two hooks. */ + length = CGEN_PRINT_INSN (cd, pc, info); + if (length > 0) + return length; + if (length < 0) + return -1; + + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + return cd->default_insn_bitsize / 8; +} diff -rNU3 dist.orig/opcodes/or1k-ibld.c dist/opcodes/or1k-ibld.c --- dist.orig/opcodes/or1k-ibld.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-ibld.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,1050 @@ +/* Instruction building/extraction support for or1k. -*- C -*- + + THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. + - the resultant file is machine generated, cgen-ibld.in isn't + + Copyright (C) 1996-2014 Free Software Foundation, Inc. + + This file is part of libopcodes. + + 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. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "or1k-desc.h" +#include "or1k-opc.h" +#include "cgen/basic-modes.h" +#include "opintl.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + +static const char * insert_normal + (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR); +static const char * insert_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, + CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); +static int extract_normal + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, bfd_vma, long *); +static int extract_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, + CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); +#if CGEN_INT_INSN_P +static void put_insn_int_value + (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT); +#endif +#if ! CGEN_INT_INSN_P +static CGEN_INLINE void insert_1 + (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *); +static CGEN_INLINE int fill_cache + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma); +static CGEN_INLINE long extract_1 + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma); +#endif + +/* Operand insertion. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of insert_normal. */ + +static CGEN_INLINE void +insert_1 (CGEN_CPU_DESC cd, + unsigned long value, + int start, + int length, + int word_length, + unsigned char *bufp) +{ + unsigned long x,mask; + int shift; + + x = cgen_get_insn_value (cd, bufp, word_length); + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + x = (x & ~(mask << shift)) | ((value & mask) << shift); + + cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x); +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default insertion routine. + + ATTRS is a mask of the boolean attributes. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + The result is an error message or NULL if success. */ + +/* ??? This duplicates functionality with bfd's howto table and + bfd_install_relocation. */ +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static const char * +insert_normal (CGEN_CPU_DESC cd, + long value, + unsigned int attrs, + unsigned int word_offset, + unsigned int start, + unsigned int length, + unsigned int word_length, + unsigned int total_length, + CGEN_INSN_BYTES_PTR buffer) +{ + static char errbuf[100]; + /* Written this way to avoid undefined behaviour. */ + unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1; + + /* If LENGTH is zero, this operand doesn't contribute to the value. */ + if (length == 0) + return NULL; + + if (word_length > 8 * sizeof (CGEN_INSN_INT)) + abort (); + + /* For architectures with insns smaller than the base-insn-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset == 0 + && word_length > total_length) + word_length = total_length; + } + + /* Ensure VALUE will fit. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) + { + long minval = - (1L << (length - 1)); + unsigned long maxval = mask; + + if ((value > 0 && (unsigned long) value > maxval) + || value < minval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (%ld not between %ld and %lu)"), + value, minval, maxval); + return errbuf; + } + } + else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) + { + unsigned long maxval = mask; + unsigned long val = (unsigned long) value; + + /* For hosts with a word size > 32 check to see if value has been sign + extended beyond 32 bits. If so then ignore these higher sign bits + as the user is attempting to store a 32-bit signed value into an + unsigned 32-bit field which is allowed. */ + if (sizeof (unsigned long) > 4 && ((value >> 32) == -1)) + val &= 0xFFFFFFFF; + + if (val > maxval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (0x%lx not between 0 and 0x%lx)"), + val, maxval); + return errbuf; + } + } + else + { + if (! cgen_signed_overflow_ok_p (cd)) + { + long minval = - (1L << (length - 1)); + long maxval = (1L << (length - 1)) - 1; + + if (value < minval || value > maxval) + { + sprintf + /* xgettext:c-format */ + (errbuf, _("operand out of range (%ld not between %ld and %ld)"), + value, minval, maxval); + return errbuf; + } + } + } + +#if CGEN_INT_INSN_P + + { + int shift; + + if (CGEN_INSN_LSB0_P) + shift = (word_offset + start + 1) - length; + else + shift = total_length - (word_offset + start + length); + *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); + } + +#else /* ! CGEN_INT_INSN_P */ + + { + unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; + + insert_1 (cd, value, start, length, word_length, bufp); + } + +#endif /* ! CGEN_INT_INSN_P */ + + return NULL; +} + +/* Default insn builder (insert handler). + The instruction is recorded in CGEN_INT_INSN_P byte order (meaning + that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is + recorded in host byte order, otherwise BUFFER is an array of bytes + and the value is recorded in target byte order). + The result is an error message or NULL if success. */ + +static const char * +insert_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN * insn, + CGEN_FIELDS * fields, + CGEN_INSN_BYTES_PTR buffer, + bfd_vma pc) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + unsigned long value; + const CGEN_SYNTAX_CHAR_TYPE * syn; + + CGEN_INIT_INSERT (cd); + value = CGEN_INSN_BASE_VALUE (insn); + + /* If we're recording insns as numbers (rather than a string of bytes), + target byte order handling is deferred until later. */ + +#if CGEN_INT_INSN_P + + put_insn_int_value (cd, buffer, cd->base_insn_bitsize, + CGEN_FIELDS_BITSIZE (fields), value); + +#else + + cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, + (unsigned) CGEN_FIELDS_BITSIZE (fields)), + value); + +#endif /* ! CGEN_INT_INSN_P */ + + /* ??? It would be better to scan the format's fields. + Still need to be able to insert a value based on the operand though; + e.g. storing a branch displacement that got resolved later. + Needs more thought first. */ + + for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) + { + const char *errmsg; + + if (CGEN_SYNTAX_CHAR_P (* syn)) + continue; + + errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + fields, buffer, pc); + if (errmsg) + return errmsg; + } + + return NULL; +} + +#if CGEN_INT_INSN_P +/* Cover function to store an insn value into an integral insn. Must go here + because it needs -desc.h for CGEN_INT_INSN_P. */ + +static void +put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + CGEN_INSN_BYTES_PTR buf, + int length, + int insn_length, + CGEN_INSN_INT value) +{ + /* For architectures with insns smaller than the base-insn-bitsize, + length may be too big. */ + if (length > insn_length) + *buf = value; + else + { + int shift = insn_length - length; + /* Written this way to avoid undefined behaviour. */ + CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; + + *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); + } +} +#endif + +/* Operand extraction. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of extract_normal. + Ensure sufficient bytes are cached in EX_INFO. + OFFSET is the offset in bytes from the start of the insn of the value. + BYTES is the length of the needed value. + Returns 1 for success, 0 for failure. */ + +static CGEN_INLINE int +fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + CGEN_EXTRACT_INFO *ex_info, + int offset, + int bytes, + bfd_vma pc) +{ + /* It's doubtful that the middle part has already been fetched so + we don't optimize that case. kiss. */ + unsigned int mask; + disassemble_info *info = (disassemble_info *) ex_info->dis_info; + + /* First do a quick check. */ + mask = (1 << bytes) - 1; + if (((ex_info->valid >> offset) & mask) == mask) + return 1; + + /* Search for the first byte we need to read. */ + for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) + if (! (mask & ex_info->valid)) + break; + + if (bytes) + { + int status; + + pc += offset; + status = (*info->read_memory_func) + (pc, ex_info->insn_bytes + offset, bytes, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return 0; + } + + ex_info->valid |= ((1 << bytes) - 1) << offset; + } + + return 1; +} + +/* Subroutine of extract_normal. */ + +static CGEN_INLINE long +extract_1 (CGEN_CPU_DESC cd, + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, + int start, + int length, + int word_length, + unsigned char *bufp, + bfd_vma pc ATTRIBUTE_UNUSED) +{ + unsigned long x; + int shift; + + x = cgen_get_insn_value (cd, bufp, word_length); + + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + return x >> shift; +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default extraction routine. + + INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, + or sometimes less for cases like the m32r where the base insn size is 32 + but some insns are 16 bits. + ATTRS is a mask of the boolean attributes. We only need `SIGNED', + but for generality we take a bitmask of all of them. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + Returns 1 for success, 0 for failure. */ + +/* ??? The return code isn't properly used. wip. */ + +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static int +extract_normal (CGEN_CPU_DESC cd, +#if ! CGEN_INT_INSN_P + CGEN_EXTRACT_INFO *ex_info, +#else + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, +#endif + CGEN_INSN_INT insn_value, + unsigned int attrs, + unsigned int word_offset, + unsigned int start, + unsigned int length, + unsigned int word_length, + unsigned int total_length, +#if ! CGEN_INT_INSN_P + bfd_vma pc, +#else + bfd_vma pc ATTRIBUTE_UNUSED, +#endif + long *valuep) +{ + long value, mask; + + /* If LENGTH is zero, this operand doesn't contribute to the value + so give it a standard value of zero. */ + if (length == 0) + { + *valuep = 0; + return 1; + } + + if (word_length > 8 * sizeof (CGEN_INSN_INT)) + abort (); + + /* For architectures with insns smaller than the insn-base-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset + word_length > total_length) + word_length = total_length - word_offset; + } + + /* Does the value reside in INSN_VALUE, and at the right alignment? */ + + if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) + { + if (CGEN_INSN_LSB0_P) + value = insn_value >> ((word_offset + start + 1) - length); + else + value = insn_value >> (total_length - ( word_offset + start + length)); + } + +#if ! CGEN_INT_INSN_P + + else + { + unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; + + if (word_length > 8 * sizeof (CGEN_INSN_INT)) + abort (); + + if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) + return 0; + + value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); + } + +#endif /* ! CGEN_INT_INSN_P */ + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + + value &= mask; + /* sign extend? */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) + && (value & (1L << (length - 1)))) + value |= ~mask; + + *valuep = value; + + return 1; +} + +/* Default insn extractor. + + INSN_VALUE is the first base_insn_bitsize bits, translated to host order. + The extracted fields are stored in FIELDS. + EX_INFO is used to handle reading variable length insns. + Return the length of the insn in bits, or 0 if no match, + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +extract_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN *insn, + CGEN_EXTRACT_INFO *ex_info, + CGEN_INSN_INT insn_value, + CGEN_FIELDS *fields, + bfd_vma pc) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + CGEN_INIT_EXTRACT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + int length; + + if (CGEN_SYNTAX_CHAR_P (*syn)) + continue; + + length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + ex_info, insn_value, fields, pc); + if (length <= 0) + return length; + } + + /* We recognized and successfully extracted this insn. */ + return CGEN_INSN_BITSIZE (insn); +} + +/* Machine generated code added here. */ + +const char * or1k_cgen_insert_operand + (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); + +/* Main entry point for operand insertion. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. It's also needed by GAS to insert operands that couldn't be + resolved during parsing. */ + +const char * +or1k_cgen_insert_operand (CGEN_CPU_DESC cd, + int opindex, + CGEN_FIELDS * fields, + CGEN_INSN_BYTES_PTR buffer, + bfd_vma pc ATTRIBUTE_UNUSED) +{ + const char * errmsg = NULL; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + { + long value = fields->f_disp26; + value = ((SI) (((value) - (pc))) >> (2)); + errmsg = insert_normal (cd, value, 0|(1<f_r2, 0, 0, 20, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RADF : + errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RASF : + errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RB : + errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RBDF : + errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RBSF : + errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RD : + errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RDDF : + errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_RDSF : + errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer); + break; + case OR1K_OPERAND_SIMM16 : + errmsg = insert_normal (cd, fields->f_simm16, 0|(1<> (11))) & (31)); + FLD (f_imm16_10_11) = ((FLD (f_simm16_split)) & (2047)); +} + errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case OR1K_OPERAND_UIMM16 : + errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 15, 16, 32, total_length, buffer); + break; + case OR1K_OPERAND_UIMM16_SPLIT : + { +{ + FLD (f_imm16_25_5) = ((((UINT) (FLD (f_uimm16_split)) >> (11))) & (31)); + FLD (f_imm16_10_11) = ((FLD (f_uimm16_split)) & (2047)); +} + errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case OR1K_OPERAND_UIMM6 : + errmsg = insert_normal (cd, fields->f_uimm6, 0, 0, 5, 6, 32, total_length, buffer); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while building insn.\n"), + opindex); + abort (); + } + + return errmsg; +} + +int or1k_cgen_extract_operand + (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); + +/* Main entry point for operand extraction. + The result is <= 0 for error, >0 for success. + ??? Actual values aren't well defined right now. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +int +or1k_cgen_extract_operand (CGEN_CPU_DESC cd, + int opindex, + CGEN_EXTRACT_INFO *ex_info, + CGEN_INSN_INT insn_value, + CGEN_FIELDS * fields, + bfd_vma pc) +{ + /* Assume success (for those operands that are nops). */ + int length = 1; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_disp26 = value; + } + break; + case OR1K_OPERAND_RA : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2); + break; + case OR1K_OPERAND_RADF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); + break; + case OR1K_OPERAND_RASF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2); + break; + case OR1K_OPERAND_RB : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3); + break; + case OR1K_OPERAND_RBDF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); + break; + case OR1K_OPERAND_RBSF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3); + break; + case OR1K_OPERAND_RD : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); + break; + case OR1K_OPERAND_RDDF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); + break; + case OR1K_OPERAND_RDSF : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1); + break; + case OR1K_OPERAND_SIMM16 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_simm16); + break; + case OR1K_OPERAND_SIMM16_SPLIT : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11); + if (length <= 0) break; + FLD (f_simm16_split) = ((HI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11))))); + } + break; + case OR1K_OPERAND_UIMM16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm16); + break; + case OR1K_OPERAND_UIMM16_SPLIT : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11); + if (length <= 0) break; + FLD (f_uimm16_split) = ((UHI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11))))); + } + break; + case OR1K_OPERAND_UIMM6 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_uimm6); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"), + opindex); + abort (); + } + + return length; +} + +cgen_insert_fn * const or1k_cgen_insert_handlers[] = +{ + insert_insn_normal, +}; + +cgen_extract_fn * const or1k_cgen_extract_handlers[] = +{ + extract_insn_normal, +}; + +int or1k_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); +bfd_vma or1k_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); + +/* Getting values from cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they return. + TODO: floating point, inlining support, remove cases where result type + not appropriate. */ + +int +or1k_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + const CGEN_FIELDS * fields) +{ + int value; + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + value = fields->f_disp26; + break; + case OR1K_OPERAND_RA : + value = fields->f_r2; + break; + case OR1K_OPERAND_RADF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RASF : + value = fields->f_r2; + break; + case OR1K_OPERAND_RB : + value = fields->f_r3; + break; + case OR1K_OPERAND_RBDF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RBSF : + value = fields->f_r3; + break; + case OR1K_OPERAND_RD : + value = fields->f_r1; + break; + case OR1K_OPERAND_RDDF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RDSF : + value = fields->f_r1; + break; + case OR1K_OPERAND_SIMM16 : + value = fields->f_simm16; + break; + case OR1K_OPERAND_SIMM16_SPLIT : + value = fields->f_simm16_split; + break; + case OR1K_OPERAND_UIMM16 : + value = fields->f_uimm16; + break; + case OR1K_OPERAND_UIMM16_SPLIT : + value = fields->f_uimm16_split; + break; + case OR1K_OPERAND_UIMM6 : + value = fields->f_uimm6; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"), + opindex); + abort (); + } + + return value; +} + +bfd_vma +or1k_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + const CGEN_FIELDS * fields) +{ + bfd_vma value; + + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + value = fields->f_disp26; + break; + case OR1K_OPERAND_RA : + value = fields->f_r2; + break; + case OR1K_OPERAND_RADF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RASF : + value = fields->f_r2; + break; + case OR1K_OPERAND_RB : + value = fields->f_r3; + break; + case OR1K_OPERAND_RBDF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RBSF : + value = fields->f_r3; + break; + case OR1K_OPERAND_RD : + value = fields->f_r1; + break; + case OR1K_OPERAND_RDDF : + value = fields->f_r1; + break; + case OR1K_OPERAND_RDSF : + value = fields->f_r1; + break; + case OR1K_OPERAND_SIMM16 : + value = fields->f_simm16; + break; + case OR1K_OPERAND_SIMM16_SPLIT : + value = fields->f_simm16_split; + break; + case OR1K_OPERAND_UIMM16 : + value = fields->f_uimm16; + break; + case OR1K_OPERAND_UIMM16_SPLIT : + value = fields->f_uimm16_split; + break; + case OR1K_OPERAND_UIMM6 : + value = fields->f_uimm6; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"), + opindex); + abort (); + } + + return value; +} + +void or1k_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int); +void or1k_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma); + +/* Stuffing values in cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they accept. + TODO: floating point, inlining support, remove cases where argument type + not appropriate. */ + +void +or1k_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + CGEN_FIELDS * fields, + int value) +{ + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + fields->f_disp26 = value; + break; + case OR1K_OPERAND_RA : + fields->f_r2 = value; + break; + case OR1K_OPERAND_RADF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RASF : + fields->f_r2 = value; + break; + case OR1K_OPERAND_RB : + fields->f_r3 = value; + break; + case OR1K_OPERAND_RBDF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RBSF : + fields->f_r3 = value; + break; + case OR1K_OPERAND_RD : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RDDF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RDSF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_SIMM16 : + fields->f_simm16 = value; + break; + case OR1K_OPERAND_SIMM16_SPLIT : + fields->f_simm16_split = value; + break; + case OR1K_OPERAND_UIMM16 : + fields->f_uimm16 = value; + break; + case OR1K_OPERAND_UIMM16_SPLIT : + fields->f_uimm16_split = value; + break; + case OR1K_OPERAND_UIMM6 : + fields->f_uimm6 = value; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"), + opindex); + abort (); + } +} + +void +or1k_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + CGEN_FIELDS * fields, + bfd_vma value) +{ + switch (opindex) + { + case OR1K_OPERAND_DISP26 : + fields->f_disp26 = value; + break; + case OR1K_OPERAND_RA : + fields->f_r2 = value; + break; + case OR1K_OPERAND_RADF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RASF : + fields->f_r2 = value; + break; + case OR1K_OPERAND_RB : + fields->f_r3 = value; + break; + case OR1K_OPERAND_RBDF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RBSF : + fields->f_r3 = value; + break; + case OR1K_OPERAND_RD : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RDDF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_RDSF : + fields->f_r1 = value; + break; + case OR1K_OPERAND_SIMM16 : + fields->f_simm16 = value; + break; + case OR1K_OPERAND_SIMM16_SPLIT : + fields->f_simm16_split = value; + break; + case OR1K_OPERAND_UIMM16 : + fields->f_uimm16 = value; + break; + case OR1K_OPERAND_UIMM16_SPLIT : + fields->f_uimm16_split = value; + break; + case OR1K_OPERAND_UIMM6 : + fields->f_uimm6 = value; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"), + opindex); + abort (); + } +} + +/* Function to call before using the instruction builder tables. */ + +void +or1k_cgen_init_ibld_table (CGEN_CPU_DESC cd) +{ + cd->insert_handlers = & or1k_cgen_insert_handlers[0]; + cd->extract_handlers = & or1k_cgen_extract_handlers[0]; + + cd->insert_operand = or1k_cgen_insert_operand; + cd->extract_operand = or1k_cgen_extract_operand; + + cd->get_int_operand = or1k_cgen_get_int_operand; + cd->set_int_operand = or1k_cgen_set_int_operand; + cd->get_vma_operand = or1k_cgen_get_vma_operand; + cd->set_vma_operand = or1k_cgen_set_vma_operand; +} diff -rNU3 dist.orig/opcodes/or1k-opc.c dist/opcodes/or1k-opc.c --- dist.orig/opcodes/or1k-opc.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-opc.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,1081 @@ +/* Instruction opcode table for or1k. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright (C) 1996-2014 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + + This file 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 "sysdep.h" +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "or1k-desc.h" +#include "or1k-opc.h" +#include "libiberty.h" + +/* -- opc.c */ +/* -- */ +/* The hash functions are recorded here to help keep assembler code out of + the disassembler and vice versa. */ + +static int asm_hash_insn_p (const CGEN_INSN *); +static unsigned int asm_hash_insn (const char *); +static int dis_hash_insn_p (const CGEN_INSN *); +static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT); + +/* Instruction formats. */ + +#define F(f) & or1k_cgen_ifld_table[OR1K_##f] +static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = { + 0, 0, 0x0, { { 0 } } +}; + +static const CGEN_IFMT ifmt_l_j ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_DISP26) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_jr ATTRIBUTE_UNUSED = { + 32, 32, 0xffff07ff, { { F (F_OPCODE) }, { F (F_RESV_25_10) }, { F (F_R3) }, { F (F_RESV_10_11) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_trap ATTRIBUTE_UNUSED = { + 32, 32, 0xffff0000, { { F (F_OPCODE) }, { F (F_OP_25_5) }, { F (F_RESV_20_5) }, { F (F_UIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_msync ATTRIBUTE_UNUSED = { + 32, 32, 0xffffffff, { { F (F_OPCODE) }, { F (F_OP_25_5) }, { F (F_RESV_20_21) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_rfe ATTRIBUTE_UNUSED = { + 32, 32, 0xffffffff, { { F (F_OPCODE) }, { F (F_RESV_25_26) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_nop_imm ATTRIBUTE_UNUSED = { + 32, 32, 0xffff0000, { { F (F_OPCODE) }, { F (F_OP_25_2) }, { F (F_RESV_23_8) }, { F (F_UIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_movhi ATTRIBUTE_UNUSED = { + 32, 32, 0xfc1f0000, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_RESV_20_4) }, { F (F_OP_16_1) }, { F (F_UIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_macrc ATTRIBUTE_UNUSED = { + 32, 32, 0xfc1fffff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_RESV_20_4) }, { F (F_OP_16_1) }, { F (F_UIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_mfspr ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_mtspr ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R2) }, { F (F_R3) }, { F (F_UIMM16_SPLIT) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_lwz ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_sw ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R2) }, { F (F_R3) }, { F (F_SIMM16_SPLIT) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_swa ATTRIBUTE_UNUSED = { + 32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R2) }, { F (F_R3) }, { F (F_SIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_sll ATTRIBUTE_UNUSED = { + 32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_2) }, { F (F_RESV_5_2) }, { F (F_OP_3_4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_slli ATTRIBUTE_UNUSED = { + 32, 32, 0xfc00ffc0, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV_15_8) }, { F (F_OP_7_2) }, { F (F_UIMM6) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_and ATTRIBUTE_UNUSED = { + 32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_7) }, { F (F_OP_3_4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_exths ATTRIBUTE_UNUSED = { + 32, 32, 0xfc00ffff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV_15_6) }, { F (F_OP_9_4) }, { F (F_RESV_5_2) }, { F (F_OP_3_4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_cmov ATTRIBUTE_UNUSED = { + 32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_1) }, { F (F_OP_9_2) }, { F (F_RESV_7_4) }, { F (F_OP_3_4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_sfgts ATTRIBUTE_UNUSED = { + 32, 32, 0xffe007ff, { { F (F_OPCODE) }, { F (F_OP_25_5) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_11) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_sfgtsi ATTRIBUTE_UNUSED = { + 32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_OP_25_5) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_mac ATTRIBUTE_UNUSED = { + 32, 32, 0xffe007ff, { { F (F_OPCODE) }, { F (F_OP_25_5) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_7) }, { F (F_OP_3_4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_l_maci ATTRIBUTE_UNUSED = { + 32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_RESV_25_5) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_add_s ATTRIBUTE_UNUSED = { + 32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_add_d ATTRIBUTE_UNUSED = { + 32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R1) }, { F (F_R1) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_itof_s ATTRIBUTE_UNUSED = { + 32, 32, 0xfc00ffff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_ftoi_s ATTRIBUTE_UNUSED = { + 32, 32, 0xfc00ffff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_ftoi_d ATTRIBUTE_UNUSED = { + 32, 32, 0xfc00ffff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R1) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_eq_s ATTRIBUTE_UNUSED = { + 32, 32, 0xffe007ff, { { F (F_OPCODE) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_cust1_s ATTRIBUTE_UNUSED = { + 32, 32, 0xffe007ff, { { F (F_OPCODE) }, { F (F_RESV_25_5) }, { F (F_R2) }, { F (F_R3) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lf_cust1_d ATTRIBUTE_UNUSED = { + 32, 32, 0xffe007ff, { { F (F_OPCODE) }, { F (F_RESV_25_5) }, { F (F_R1) }, { F (F_R1) }, { F (F_RESV_10_3) }, { F (F_OP_7_8) }, { 0 } } +}; + +#undef F + +#define A(a) (1 << CGEN_INSN_##a) +#define OPERAND(op) OR1K_OPERAND_##op +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The instruction table. */ + +static const CGEN_OPCODE or1k_cgen_insn_opcode_table[MAX_INSNS] = +{ + /* Special null first entry. + A `num' value of zero is thus invalid. + Also, the special `invalid' insn resides here. */ + { { 0, 0, 0, 0 }, {{0}}, 0, {0}}, +/* l.j ${disp26} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (DISP26), 0 } }, + & ifmt_l_j, { 0x0 } + }, +/* l.jal ${disp26} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (DISP26), 0 } }, + & ifmt_l_j, { 0x4000000 } + }, +/* l.jr $rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RB), 0 } }, + & ifmt_l_jr, { 0x44000000 } + }, +/* l.jalr $rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RB), 0 } }, + & ifmt_l_jr, { 0x48000000 } + }, +/* l.bnf ${disp26} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (DISP26), 0 } }, + & ifmt_l_j, { 0xc000000 } + }, +/* l.bf ${disp26} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (DISP26), 0 } }, + & ifmt_l_j, { 0x10000000 } + }, +/* l.trap ${uimm16} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (UIMM16), 0 } }, + & ifmt_l_trap, { 0x21000000 } + }, +/* l.sys ${uimm16} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (UIMM16), 0 } }, + & ifmt_l_trap, { 0x20000000 } + }, +/* l.msync */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_msync, { 0x22000000 } + }, +/* l.psync */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_msync, { 0x22800000 } + }, +/* l.csync */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_msync, { 0x23000000 } + }, +/* l.rfe */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0x24000000 } + }, +/* l.nop ${uimm16} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (UIMM16), 0 } }, + & ifmt_l_nop_imm, { 0x15000000 } + }, +/* l.nop */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_nop_imm, { 0x15000000 } + }, +/* l.movhi $rD,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (UIMM16), 0 } }, + & ifmt_l_movhi, { 0x18000000 } + }, +/* l.macrc $rD */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), 0 } }, + & ifmt_l_macrc, { 0x18010000 } + }, +/* l.mfspr $rD,$rA,${uimm16} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM16), 0 } }, + & ifmt_l_mfspr, { 0xb4000000 } + }, +/* l.mtspr $rA,$rB,${uimm16-split} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), ',', OP (UIMM16_SPLIT), 0 } }, + & ifmt_l_mtspr, { 0xc0000000 } + }, +/* l.lwz $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x84000000 } + }, +/* l.lws $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x88000000 } + }, +/* l.lwa $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x6c000000 } + }, +/* l.lbz $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x8c000000 } + }, +/* l.lbs $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x90000000 } + }, +/* l.lhz $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x94000000 } + }, +/* l.lhs $rD,${simm16}($rA) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (SIMM16), '(', OP (RA), ')', 0 } }, + & ifmt_l_lwz, { 0x98000000 } + }, +/* l.sw ${simm16-split}($rA),$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (SIMM16_SPLIT), '(', OP (RA), ')', ',', OP (RB), 0 } }, + & ifmt_l_sw, { 0xd4000000 } + }, +/* l.sb ${simm16-split}($rA),$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (SIMM16_SPLIT), '(', OP (RA), ')', ',', OP (RB), 0 } }, + & ifmt_l_sw, { 0xd8000000 } + }, +/* l.sh ${simm16-split}($rA),$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (SIMM16_SPLIT), '(', OP (RA), ')', ',', OP (RB), 0 } }, + & ifmt_l_sw, { 0xdc000000 } + }, +/* l.swa ${simm16-split}($rA),$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (SIMM16_SPLIT), '(', OP (RA), ')', ',', OP (RB), 0 } }, + & ifmt_l_swa, { 0xcc000000 } + }, +/* l.sll $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sll, { 0xe0000008 } + }, +/* l.slli $rD,$rA,${uimm6} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM6), 0 } }, + & ifmt_l_slli, { 0xb8000000 } + }, +/* l.srl $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sll, { 0xe0000048 } + }, +/* l.srli $rD,$rA,${uimm6} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM6), 0 } }, + & ifmt_l_slli, { 0xb8000040 } + }, +/* l.sra $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sll, { 0xe0000088 } + }, +/* l.srai $rD,$rA,${uimm6} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM6), 0 } }, + & ifmt_l_slli, { 0xb8000080 } + }, +/* l.ror $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sll, { 0xe00000c8 } + }, +/* l.rori $rD,$rA,${uimm6} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM6), 0 } }, + & ifmt_l_slli, { 0xb80000c0 } + }, +/* l.and $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000003 } + }, +/* l.or $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000004 } + }, +/* l.xor $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000005 } + }, +/* l.add $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000000 } + }, +/* l.sub $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000002 } + }, +/* l.addc $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000001 } + }, +/* l.mul $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000306 } + }, +/* l.mulu $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe000030b } + }, +/* l.div $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe0000309 } + }, +/* l.divu $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_and, { 0xe000030a } + }, +/* l.ff1 $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_and, { 0xe000000f } + }, +/* l.fl1 $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_and, { 0xe000010f } + }, +/* l.andi $rD,$rA,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM16), 0 } }, + & ifmt_l_mfspr, { 0xa4000000 } + }, +/* l.ori $rD,$rA,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM16), 0 } }, + & ifmt_l_mfspr, { 0xa8000000 } + }, +/* l.xori $rD,$rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_lwz, { 0xac000000 } + }, +/* l.addi $rD,$rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_lwz, { 0x9c000000 } + }, +/* l.addic $rD,$rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_lwz, { 0xa0000000 } + }, +/* l.muli $rD,$rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_lwz, { 0xb0000000 } + }, +/* l.exths $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe000000c } + }, +/* l.extbs $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe000004c } + }, +/* l.exthz $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe000008c } + }, +/* l.extbz $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe00000cc } + }, +/* l.extws $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe000000d } + }, +/* l.extwz $rD,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), 0 } }, + & ifmt_l_exths, { 0xe000004d } + }, +/* l.cmov $rD,$rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_cmov, { 0xe000000e } + }, +/* l.sfgts $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe5400000 } + }, +/* l.sfgtsi $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbd400000 } + }, +/* l.sfgtu $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4400000 } + }, +/* l.sfgtui $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbc400000 } + }, +/* l.sfges $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe5600000 } + }, +/* l.sfgesi $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbd600000 } + }, +/* l.sfgeu $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4600000 } + }, +/* l.sfgeui $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbc600000 } + }, +/* l.sflts $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe5800000 } + }, +/* l.sfltsi $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbd800000 } + }, +/* l.sfltu $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4800000 } + }, +/* l.sfltui $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbc800000 } + }, +/* l.sfles $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe5a00000 } + }, +/* l.sflesi $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbda00000 } + }, +/* l.sfleu $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4a00000 } + }, +/* l.sfleui $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbca00000 } + }, +/* l.sfeq $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4000000 } + }, +/* l.sfeqi $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbc000000 } + }, +/* l.sfne $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_sfgts, { 0xe4200000 } + }, +/* l.sfnei $rA,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_sfgtsi, { 0xbc200000 } + }, +/* l.mac $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_mac, { 0xc4000001 } + }, +/* l.msb $rA,$rB */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (RB), 0 } }, + & ifmt_l_mac, { 0xc4000002 } + }, +/* l.maci $rA,${simm16} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RA), ',', OP (SIMM16), 0 } }, + & ifmt_l_maci, { 0x4c000000 } + }, +/* l.cust1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0x70000000 } + }, +/* l.cust2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0x74000000 } + }, +/* l.cust3 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0x78000000 } + }, +/* l.cust4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0x7c000000 } + }, +/* l.cust5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0xf0000000 } + }, +/* l.cust6 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0xf4000000 } + }, +/* l.cust7 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0xf8000000 } + }, +/* l.cust8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_l_rfe, { 0xfc000000 } + }, +/* lf.add.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000000 } + }, +/* lf.add.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000010 } + }, +/* lf.sub.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000001 } + }, +/* lf.sub.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000011 } + }, +/* lf.mul.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000002 } + }, +/* lf.mul.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000012 } + }, +/* lf.div.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000003 } + }, +/* lf.div.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000013 } + }, +/* lf.rem.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000006 } + }, +/* lf.rem.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000016 } + }, +/* lf.itof.s $rDSF,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RA), 0 } }, + & ifmt_lf_itof_s, { 0xc8000004 } + }, +/* lf.itof.d $rDSF,$rA */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RA), 0 } }, + & ifmt_lf_itof_s, { 0xc8000014 } + }, +/* lf.ftoi.s $rD,$rASF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RASF), 0 } }, + & ifmt_lf_ftoi_s, { 0xc8000005 } + }, +/* lf.ftoi.d $rD,$rADF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RD), ',', OP (RADF), 0 } }, + & ifmt_lf_ftoi_d, { 0xc8000015 } + }, +/* lf.sfeq.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc8000008 } + }, +/* lf.sfeq.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc8000018 } + }, +/* lf.sfne.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc8000009 } + }, +/* lf.sfne.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc8000019 } + }, +/* lf.sfge.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800000b } + }, +/* lf.sfge.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800001b } + }, +/* lf.sfgt.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800000a } + }, +/* lf.sfgt.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800001a } + }, +/* lf.sflt.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800000c } + }, +/* lf.sflt.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800001c } + }, +/* lf.sfle.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800000d } + }, +/* lf.sfle.d $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_eq_s, { 0xc800001d } + }, +/* lf.madd.s $rDSF,$rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDSF), ',', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_add_s, { 0xc8000007 } + }, +/* lf.madd.d $rDDF,$rADF,$rBDF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RDDF), ',', OP (RADF), ',', OP (RBDF), 0 } }, + & ifmt_lf_add_d, { 0xc8000017 } + }, +/* lf.cust1.s $rASF,$rBSF */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RASF), ',', OP (RBSF), 0 } }, + & ifmt_lf_cust1_s, { 0xc80000d0 } + }, +/* lf.cust1.d */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_lf_cust1_d, { 0xc80000e0 } + }, +}; + +#undef A +#undef OPERAND +#undef MNEM +#undef OP + +/* Formats for ALIAS macro-insns. */ + +#define F(f) & or1k_cgen_ifld_table[OR1K_##f] +#undef F + +/* Each non-simple macro entry points to an array of expansion possibilities. */ + +#define A(a) (1 << CGEN_INSN_##a) +#define OPERAND(op) OR1K_OPERAND_##op +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The macro instruction table. */ + +static const CGEN_IBASE or1k_cgen_macro_insn_table[] = +{ +}; + +/* The macro instruction opcode table. */ + +static const CGEN_OPCODE or1k_cgen_macro_insn_opcode_table[] = +{ +}; + +#undef A +#undef OPERAND +#undef MNEM +#undef OP + +#ifndef CGEN_ASM_HASH_P +#define CGEN_ASM_HASH_P(insn) 1 +#endif + +#ifndef CGEN_DIS_HASH_P +#define CGEN_DIS_HASH_P(insn) 1 +#endif + +/* Return non-zero if INSN is to be added to the hash table. + Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */ + +static int +asm_hash_insn_p (insn) + const CGEN_INSN *insn ATTRIBUTE_UNUSED; +{ + return CGEN_ASM_HASH_P (insn); +} + +static int +dis_hash_insn_p (insn) + const CGEN_INSN *insn; +{ + /* If building the hash table and the NO-DIS attribute is present, + ignore. */ + if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS)) + return 0; + return CGEN_DIS_HASH_P (insn); +} + +#ifndef CGEN_ASM_HASH +#define CGEN_ASM_HASH_SIZE 127 +#ifdef CGEN_MNEMONIC_OPERANDS +#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) +#else +#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/ +#endif +#endif + +/* It doesn't make much sense to provide a default here, + but while this is under development we do. + BUFFER is a pointer to the bytes of the insn, target order. + VALUE is the first base_insn_bitsize bits as an int in host order. */ + +#ifndef CGEN_DIS_HASH +#define CGEN_DIS_HASH_SIZE 256 +#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf)) +#endif + +/* The result is the hash value of the insn. + Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */ + +static unsigned int +asm_hash_insn (mnem) + const char * mnem; +{ + return CGEN_ASM_HASH (mnem); +} + +/* BUF is a pointer to the bytes of the insn, target order. + VALUE is the first base_insn_bitsize bits as an int in host order. */ + +static unsigned int +dis_hash_insn (buf, value) + const char * buf ATTRIBUTE_UNUSED; + CGEN_INSN_INT value ATTRIBUTE_UNUSED; +{ + return CGEN_DIS_HASH (buf, value); +} + +/* Set the recorded length of the insn in the CGEN_FIELDS struct. */ + +static void +set_fields_bitsize (CGEN_FIELDS *fields, int size) +{ + CGEN_FIELDS_BITSIZE (fields) = size; +} + +/* Function to call before using the operand instance table. + This plugs the opcode entries and macro instructions into the cpu table. */ + +void +or1k_cgen_init_opcode_table (CGEN_CPU_DESC cd) +{ + int i; + int num_macros = (sizeof (or1k_cgen_macro_insn_table) / + sizeof (or1k_cgen_macro_insn_table[0])); + const CGEN_IBASE *ib = & or1k_cgen_macro_insn_table[0]; + const CGEN_OPCODE *oc = & or1k_cgen_macro_insn_opcode_table[0]; + CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN)); + + /* This test has been added to avoid a warning generated + if memset is called with a third argument of value zero. */ + if (num_macros >= 1) + memset (insns, 0, num_macros * sizeof (CGEN_INSN)); + for (i = 0; i < num_macros; ++i) + { + insns[i].base = &ib[i]; + insns[i].opcode = &oc[i]; + or1k_cgen_build_insn_regex (& insns[i]); + } + cd->macro_insn_table.init_entries = insns; + cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); + cd->macro_insn_table.num_init_entries = num_macros; + + oc = & or1k_cgen_insn_opcode_table[0]; + insns = (CGEN_INSN *) cd->insn_table.init_entries; + for (i = 0; i < MAX_INSNS; ++i) + { + insns[i].opcode = &oc[i]; + or1k_cgen_build_insn_regex (& insns[i]); + } + + cd->sizeof_fields = sizeof (CGEN_FIELDS); + cd->set_fields_bitsize = set_fields_bitsize; + + cd->asm_hash_p = asm_hash_insn_p; + cd->asm_hash = asm_hash_insn; + cd->asm_hash_size = CGEN_ASM_HASH_SIZE; + + cd->dis_hash_p = dis_hash_insn_p; + cd->dis_hash = dis_hash_insn; + cd->dis_hash_size = CGEN_DIS_HASH_SIZE; +} diff -rNU3 dist.orig/opcodes/or1k-opc.h dist/opcodes/or1k-opc.h --- dist.orig/opcodes/or1k-opc.h 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-opc.h 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,135 @@ +/* Instruction opcode header for or1k. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright (C) 1996-2014 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + + This file 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. + +*/ + +#ifndef OR1K_OPC_H +#define OR1K_OPC_H + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 256 +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) + +/* -- */ +/* Enum declaration for or1k instruction types. */ +typedef enum cgen_insn_type { + OR1K_INSN_INVALID, OR1K_INSN_L_J, OR1K_INSN_L_JAL, OR1K_INSN_L_JR + , OR1K_INSN_L_JALR, OR1K_INSN_L_BNF, OR1K_INSN_L_BF, OR1K_INSN_L_TRAP + , OR1K_INSN_L_SYS, OR1K_INSN_L_MSYNC, OR1K_INSN_L_PSYNC, OR1K_INSN_L_CSYNC + , OR1K_INSN_L_RFE, OR1K_INSN_L_NOP_IMM, OR1K_INSN_L_NOP, OR1K_INSN_L_MOVHI + , OR1K_INSN_L_MACRC, OR1K_INSN_L_MFSPR, OR1K_INSN_L_MTSPR, OR1K_INSN_L_LWZ + , OR1K_INSN_L_LWS, OR1K_INSN_L_LWA, OR1K_INSN_L_LBZ, OR1K_INSN_L_LBS + , OR1K_INSN_L_LHZ, OR1K_INSN_L_LHS, OR1K_INSN_L_SW, OR1K_INSN_L_SB + , OR1K_INSN_L_SH, OR1K_INSN_L_SWA, OR1K_INSN_L_SLL, OR1K_INSN_L_SLLI + , OR1K_INSN_L_SRL, OR1K_INSN_L_SRLI, OR1K_INSN_L_SRA, OR1K_INSN_L_SRAI + , OR1K_INSN_L_ROR, OR1K_INSN_L_RORI, OR1K_INSN_L_AND, OR1K_INSN_L_OR + , OR1K_INSN_L_XOR, OR1K_INSN_L_ADD, OR1K_INSN_L_SUB, OR1K_INSN_L_ADDC + , OR1K_INSN_L_MUL, OR1K_INSN_L_MULU, OR1K_INSN_L_DIV, OR1K_INSN_L_DIVU + , OR1K_INSN_L_FF1, OR1K_INSN_L_FL1, OR1K_INSN_L_ANDI, OR1K_INSN_L_ORI + , OR1K_INSN_L_XORI, OR1K_INSN_L_ADDI, OR1K_INSN_L_ADDIC, OR1K_INSN_L_MULI + , OR1K_INSN_L_EXTHS, OR1K_INSN_L_EXTBS, OR1K_INSN_L_EXTHZ, OR1K_INSN_L_EXTBZ + , OR1K_INSN_L_EXTWS, OR1K_INSN_L_EXTWZ, OR1K_INSN_L_CMOV, OR1K_INSN_L_SFGTS + , OR1K_INSN_L_SFGTSI, OR1K_INSN_L_SFGTU, OR1K_INSN_L_SFGTUI, OR1K_INSN_L_SFGES + , OR1K_INSN_L_SFGESI, OR1K_INSN_L_SFGEU, OR1K_INSN_L_SFGEUI, OR1K_INSN_L_SFLTS + , OR1K_INSN_L_SFLTSI, OR1K_INSN_L_SFLTU, OR1K_INSN_L_SFLTUI, OR1K_INSN_L_SFLES + , OR1K_INSN_L_SFLESI, OR1K_INSN_L_SFLEU, OR1K_INSN_L_SFLEUI, OR1K_INSN_L_SFEQ + , OR1K_INSN_L_SFEQI, OR1K_INSN_L_SFNE, OR1K_INSN_L_SFNEI, OR1K_INSN_L_MAC + , OR1K_INSN_L_MSB, OR1K_INSN_L_MACI, OR1K_INSN_L_CUST1, OR1K_INSN_L_CUST2 + , OR1K_INSN_L_CUST3, OR1K_INSN_L_CUST4, OR1K_INSN_L_CUST5, OR1K_INSN_L_CUST6 + , OR1K_INSN_L_CUST7, OR1K_INSN_L_CUST8, OR1K_INSN_LF_ADD_S, OR1K_INSN_LF_ADD_D + , OR1K_INSN_LF_SUB_S, OR1K_INSN_LF_SUB_D, OR1K_INSN_LF_MUL_S, OR1K_INSN_LF_MUL_D + , OR1K_INSN_LF_DIV_S, OR1K_INSN_LF_DIV_D, OR1K_INSN_LF_REM_S, OR1K_INSN_LF_REM_D + , OR1K_INSN_LF_ITOF_S, OR1K_INSN_LF_ITOF_D, OR1K_INSN_LF_FTOI_S, OR1K_INSN_LF_FTOI_D + , OR1K_INSN_LF_EQ_S, OR1K_INSN_LF_EQ_D, OR1K_INSN_LF_NE_S, OR1K_INSN_LF_NE_D + , OR1K_INSN_LF_GE_S, OR1K_INSN_LF_GE_D, OR1K_INSN_LF_GT_S, OR1K_INSN_LF_GT_D + , OR1K_INSN_LF_LT_S, OR1K_INSN_LF_LT_D, OR1K_INSN_LF_LE_S, OR1K_INSN_LF_LE_D + , OR1K_INSN_LF_MADD_S, OR1K_INSN_LF_MADD_D, OR1K_INSN_LF_CUST1_S, OR1K_INSN_LF_CUST1_D +} CGEN_INSN_TYPE; + +/* Index of `invalid' insn place holder. */ +#define CGEN_INSN_INVALID OR1K_INSN_INVALID + +/* Total number of insns in table. */ +#define MAX_INSNS ((int) OR1K_INSN_LF_CUST1_D + 1) + +/* This struct records data prior to insertion or after extraction. */ +struct cgen_fields +{ + int length; + long f_nil; + long f_anyof; + long f_opcode; + long f_r1; + long f_r2; + long f_r3; + long f_op_25_2; + long f_op_25_5; + long f_op_16_1; + long f_op_7_4; + long f_op_3_4; + long f_op_9_2; + long f_op_9_4; + long f_op_7_8; + long f_op_7_2; + long f_resv_25_26; + long f_resv_25_10; + long f_resv_25_5; + long f_resv_23_8; + long f_resv_20_21; + long f_resv_20_5; + long f_resv_20_4; + long f_resv_15_8; + long f_resv_15_6; + long f_resv_10_11; + long f_resv_10_7; + long f_resv_10_3; + long f_resv_10_1; + long f_resv_7_4; + long f_resv_5_2; + long f_imm16_25_5; + long f_imm16_10_11; + long f_disp26; + long f_uimm16; + long f_simm16; + long f_uimm6; + long f_uimm16_split; + long f_simm16_split; +}; + +#define CGEN_INIT_PARSE(od) \ +{\ +} +#define CGEN_INIT_INSERT(od) \ +{\ +} +#define CGEN_INIT_EXTRACT(od) \ +{\ +} +#define CGEN_INIT_PRINT(od) \ +{\ +} + + +#endif /* OR1K_OPC_H */ diff -rNU3 dist.orig/opcodes/or1k-opinst.c dist/opcodes/or1k-opinst.c --- dist.orig/opcodes/or1k-opinst.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/or1k-opinst.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,590 @@ +/* Semantic operand instances for or1k. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright (C) 1996-2014 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + + This file 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 "sysdep.h" +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "or1k-desc.h" +#include "or1k-opc.h" + +/* Operand references. */ + +#define OP_ENT(op) OR1K_OPERAND_##op +#define INPUT CGEN_OPINST_INPUT +#define OUTPUT CGEN_OPINST_OUTPUT +#define END CGEN_OPINST_END +#define COND_REF CGEN_OPINST_COND_REF + +static const CGEN_OPINST sfmt_empty_ops[] ATTRIBUTE_UNUSED = { + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_j_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "disp26", HW_H_IADDR, CGEN_MODE_UDI, OP_ENT (DISP26), 0, 0 }, + { INPUT, "sys_cpucfgr_nd", HW_H_SYS_CPUCFGR_ND, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_jal_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "disp26", HW_H_IADDR, CGEN_MODE_UDI, OP_ENT (DISP26), 0, 0 }, + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_cpucfgr_nd", HW_H_SYS_CPUCFGR_ND, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "h_gpr_UDI_9", HW_H_GPR, CGEN_MODE_UDI, 0, 9, 0 }, + { OUTPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_jr_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "sys_cpucfgr_nd", HW_H_SYS_CPUCFGR_ND, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_jalr_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "sys_cpucfgr_nd", HW_H_SYS_CPUCFGR_ND, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "h_gpr_UDI_9", HW_H_GPR, CGEN_MODE_UDI, 0, 9, 0 }, + { OUTPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_bnf_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "disp26", HW_H_IADDR, CGEN_MODE_UDI, OP_ENT (DISP26), 0, COND_REF }, + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "sys_cpucfgr_nd", HW_H_SYS_CPUCFGR_ND, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_trap_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_msync_ops[] ATTRIBUTE_UNUSED = { + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_nop_imm_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "uimm16", HW_H_UIMM16, CGEN_MODE_UINT, OP_ENT (UIMM16), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_movhi_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "uimm16", HW_H_UIMM16, CGEN_MODE_UINT, OP_ENT (UIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_macrc_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "mac_machi", HW_H_MAC_MACHI, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_mfspr_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "uimm16", HW_H_UIMM16, CGEN_MODE_UINT, OP_ENT (UIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_mtspr_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "uimm16_split", HW_H_UIMM16, CGEN_MODE_UINT, OP_ENT (UIMM16_SPLIT), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lwz_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_USI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_4", HW_H_MEMORY, CGEN_MODE_USI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lws_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_SI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_4", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lwa_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_USI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_4", HW_H_MEMORY, CGEN_MODE_USI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "atomic_address", HW_H_ATOMIC_ADDRESS, CGEN_MODE_SI, 0, 0, 0 }, + { OUTPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lbz_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_UQI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_1", HW_H_MEMORY, CGEN_MODE_UQI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lbs_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_QI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_1", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lhz_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_UHI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_2", HW_H_MEMORY, CGEN_MODE_UHI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_lhs_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "h_memory_HI_c_call__AI_@cpu@_make_load_store_addr_rA_ext__SI_simm16_2", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sw_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "atomic_address", HW_H_ATOMIC_ADDRESS, CGEN_MODE_SI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "simm16_split", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16_SPLIT), 0, 0 }, + { OUTPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, COND_REF }, + { OUTPUT, "h_memory_USI_addr", HW_H_MEMORY, CGEN_MODE_USI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sb_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "atomic_address", HW_H_ATOMIC_ADDRESS, CGEN_MODE_SI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "simm16_split", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16_SPLIT), 0, 0 }, + { OUTPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, COND_REF }, + { OUTPUT, "h_memory_UQI_addr", HW_H_MEMORY, CGEN_MODE_UQI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sh_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "atomic_address", HW_H_ATOMIC_ADDRESS, CGEN_MODE_SI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "simm16_split", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16_SPLIT), 0, 0 }, + { OUTPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, COND_REF }, + { OUTPUT, "h_memory_UHI_addr", HW_H_MEMORY, CGEN_MODE_UHI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_swa_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "atomic_address", HW_H_ATOMIC_ADDRESS, CGEN_MODE_SI, 0, 0, 0 }, + { INPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, COND_REF }, + { INPUT, "simm16_split", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16_SPLIT), 0, 0 }, + { INPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "atomic_reserve", HW_H_ATOMIC_RESERVE, CGEN_MODE_BI, 0, 0, 0 }, + { OUTPUT, "h_memory_USI_addr", HW_H_MEMORY, CGEN_MODE_USI, 0, 0, COND_REF }, + { OUTPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sll_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_slli_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "uimm6", HW_H_UIMM6, CGEN_MODE_UINT, OP_ENT (UIMM6), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_and_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_add_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ove", HW_H_SYS_SR_OVE, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { OUTPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_addc_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ove", HW_H_SYS_SR_OVE, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { OUTPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_div_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, COND_REF }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { INPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ove", HW_H_SYS_SR_OVE, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, COND_REF }, + { OUTPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, COND_REF }, + { OUTPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_ff1_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_xori_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_addi_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { INPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ove", HW_H_SYS_SR_OVE, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { OUTPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_addic_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "pc", HW_H_PC, CGEN_MODE_UDI, 0, 0, COND_REF }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { INPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "sys_sr_ove", HW_H_SYS_SR_OVE, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { OUTPUT, "sys_sr_cy", HW_H_SYS_SR_CY, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "sys_sr_ov", HW_H_SYS_SR_OV, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_exths_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_cmov_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, COND_REF }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, COND_REF }, + { INPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, COND_REF }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sfgts_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { OUTPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_sfgtsi_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_mac_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "mac_machi", HW_H_MAC_MACHI, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "rB", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RB), 0, 0 }, + { OUTPUT, "mac_machi", HW_H_MAC_MACHI, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_l_maci_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "mac_machi", HW_H_MAC_MACHI, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "simm16", HW_H_SIMM16, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 }, + { OUTPUT, "mac_machi", HW_H_MAC_MACHI, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "mac_maclo", HW_H_MAC_MACLO, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_add_s_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rASF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RASF), 0, 0 }, + { INPUT, "rBSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RBSF), 0, 0 }, + { OUTPUT, "rDSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RDSF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_add_d_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rADF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RADF), 0, 0 }, + { INPUT, "rBDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RBDF), 0, 0 }, + { OUTPUT, "rDDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RDDF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_itof_s_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "sys_fpcsr_rm", HW_H_SYS_FPCSR_RM, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rDSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RDSF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_itof_d_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rA", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RA), 0, 0 }, + { INPUT, "sys_fpcsr_rm", HW_H_SYS_FPCSR_RM, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rDDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RDDF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_ftoi_s_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rASF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RASF), 0, 0 }, + { INPUT, "sys_fpcsr_rm", HW_H_SYS_FPCSR_RM, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_ftoi_d_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rADF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RADF), 0, 0 }, + { INPUT, "sys_fpcsr_rm", HW_H_SYS_FPCSR_RM, CGEN_MODE_UDI, 0, 0, 0 }, + { OUTPUT, "rD", HW_H_GPR, CGEN_MODE_UDI, OP_ENT (RD), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_eq_s_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rASF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RASF), 0, 0 }, + { INPUT, "rBSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RBSF), 0, 0 }, + { OUTPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_eq_d_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rADF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RADF), 0, 0 }, + { INPUT, "rBDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RBDF), 0, 0 }, + { OUTPUT, "sys_sr_f", HW_H_SYS_SR_F, CGEN_MODE_UDI, 0, 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_madd_s_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rASF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RASF), 0, 0 }, + { INPUT, "rBSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RBSF), 0, 0 }, + { INPUT, "rDSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RDSF), 0, 0 }, + { OUTPUT, "rDSF", HW_H_FSR, CGEN_MODE_SF, OP_ENT (RDSF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +static const CGEN_OPINST sfmt_lf_madd_d_ops[] ATTRIBUTE_UNUSED = { + { INPUT, "rADF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RADF), 0, 0 }, + { INPUT, "rBDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RBDF), 0, 0 }, + { INPUT, "rDDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RDDF), 0, 0 }, + { OUTPUT, "rDDF", HW_H_FDR, CGEN_MODE_DF, OP_ENT (RDDF), 0, 0 }, + { END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 } +}; + +#undef OP_ENT +#undef INPUT +#undef OUTPUT +#undef END +#undef COND_REF + +/* Operand instance lookup table. */ + +static const CGEN_OPINST *or1k_cgen_opinst_table[MAX_INSNS] = { + 0, + & sfmt_l_j_ops[0], + & sfmt_l_jal_ops[0], + & sfmt_l_jr_ops[0], + & sfmt_l_jalr_ops[0], + & sfmt_l_bnf_ops[0], + & sfmt_l_bnf_ops[0], + & sfmt_l_trap_ops[0], + & sfmt_l_trap_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_nop_imm_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_movhi_ops[0], + & sfmt_l_macrc_ops[0], + & sfmt_l_mfspr_ops[0], + & sfmt_l_mtspr_ops[0], + & sfmt_l_lwz_ops[0], + & sfmt_l_lws_ops[0], + & sfmt_l_lwa_ops[0], + & sfmt_l_lbz_ops[0], + & sfmt_l_lbs_ops[0], + & sfmt_l_lhz_ops[0], + & sfmt_l_lhs_ops[0], + & sfmt_l_sw_ops[0], + & sfmt_l_sb_ops[0], + & sfmt_l_sh_ops[0], + & sfmt_l_swa_ops[0], + & sfmt_l_sll_ops[0], + & sfmt_l_slli_ops[0], + & sfmt_l_sll_ops[0], + & sfmt_l_slli_ops[0], + & sfmt_l_sll_ops[0], + & sfmt_l_slli_ops[0], + & sfmt_l_sll_ops[0], + & sfmt_l_slli_ops[0], + & sfmt_l_and_ops[0], + & sfmt_l_and_ops[0], + & sfmt_l_and_ops[0], + & sfmt_l_add_ops[0], + & sfmt_l_add_ops[0], + & sfmt_l_addc_ops[0], + & sfmt_l_add_ops[0], + & sfmt_l_add_ops[0], + & sfmt_l_div_ops[0], + & sfmt_l_div_ops[0], + & sfmt_l_ff1_ops[0], + & sfmt_l_ff1_ops[0], + & sfmt_l_mfspr_ops[0], + & sfmt_l_mfspr_ops[0], + & sfmt_l_xori_ops[0], + & sfmt_l_addi_ops[0], + & sfmt_l_addic_ops[0], + & sfmt_l_addi_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_exths_ops[0], + & sfmt_l_cmov_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_sfgts_ops[0], + & sfmt_l_sfgtsi_ops[0], + & sfmt_l_mac_ops[0], + & sfmt_l_mac_ops[0], + & sfmt_l_maci_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_lf_add_s_ops[0], + & sfmt_lf_add_d_ops[0], + & sfmt_lf_add_s_ops[0], + & sfmt_lf_add_d_ops[0], + & sfmt_lf_add_s_ops[0], + & sfmt_lf_add_d_ops[0], + & sfmt_lf_add_s_ops[0], + & sfmt_lf_add_d_ops[0], + & sfmt_lf_add_s_ops[0], + & sfmt_lf_add_d_ops[0], + & sfmt_lf_itof_s_ops[0], + & sfmt_lf_itof_d_ops[0], + & sfmt_lf_ftoi_s_ops[0], + & sfmt_lf_ftoi_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_eq_s_ops[0], + & sfmt_lf_eq_d_ops[0], + & sfmt_lf_madd_s_ops[0], + & sfmt_lf_madd_d_ops[0], + & sfmt_l_msync_ops[0], + & sfmt_l_msync_ops[0], +}; + +/* Function to call before using the operand instance table. */ + +void +or1k_cgen_init_opinst_table (cd) + CGEN_CPU_DESC cd; +{ + int i; + const CGEN_OPINST **oi = & or1k_cgen_opinst_table[0]; + CGEN_INSN *insns = (CGEN_INSN *) cd->insn_table.init_entries; + for (i = 0; i < MAX_INSNS; ++i) + insns[i].opinst = oi[i]; +} diff -rNU3 dist.orig/opcodes/or32-dis.c dist/opcodes/or32-dis.c --- dist.orig/opcodes/or32-dis.c 2012-05-18 03:59:38.000000000 +0200 +++ dist/opcodes/or32-dis.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,325 +0,0 @@ -/* Instruction printing code for the OpenRISC 1000 - Copyright (C) 2002, 2005, 2007, 2012 Free Software Foundation, Inc. - Contributed by Damjan Lampret . - Modified from a29k port. - - 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. */ - -#ifndef DEBUG -#define DEBUG 0 -#endif - -#include "sysdep.h" -#include "dis-asm.h" -#include "opcode/or32.h" -#include "safe-ctype.h" - -#define EXTEND29(x) ((x) & (unsigned long) 0x10000000 ? ((x) | (unsigned long) 0xf0000000) : ((x))) - -/* Now find the four bytes of INSN_CH and put them in *INSN. */ - -static void -find_bytes_big (unsigned char *insn_ch, unsigned long *insn) -{ - *insn = - ((unsigned long) insn_ch[0] << 24) + - ((unsigned long) insn_ch[1] << 16) + - ((unsigned long) insn_ch[2] << 8) + - ((unsigned long) insn_ch[3]); -#if DEBUG - printf ("find_bytes_big3: %lx\n", *insn); -#endif -} - -static void -find_bytes_little (unsigned char *insn_ch, unsigned long *insn) -{ - *insn = - ((unsigned long) insn_ch[3] << 24) + - ((unsigned long) insn_ch[2] << 16) + - ((unsigned long) insn_ch[1] << 8) + - ((unsigned long) insn_ch[0]); -} - -typedef void (*find_byte_func_type) (unsigned char *, unsigned long *); - -static unsigned long -or32_extract (char param_ch, char *enc_initial, unsigned long insn) -{ - char *enc; - unsigned long ret = 0; - int opc_pos = 0; - int param_pos = 0; - - for (enc = enc_initial; *enc != '\0'; enc++) - if (*enc == param_ch) - { - if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x')) - continue; - else - param_pos++; - } - -#if DEBUG - printf ("or32_extract: %c %x ", param_ch, param_pos); -#endif - opc_pos = 32; - - for (enc = enc_initial; *enc != '\0'; ) - if ((*enc == '0') && (*(enc + 1) == 'x')) - { - opc_pos -= 4; - - if ((param_ch == '0') || (param_ch == '1')) - { - unsigned long tmp = strtoul (enc, NULL, 16); -#if DEBUG - printf (" enc=%s, tmp=%lx ", enc, tmp); -#endif - if (param_ch == '0') - tmp = 15 - tmp; - ret |= tmp << opc_pos; - } - enc += 3; - } - else if ((*enc == '0') || (*enc == '1')) - { - opc_pos--; - if (param_ch == *enc) - ret |= 1 << opc_pos; - enc++; - } - else if (*enc == param_ch) - { - opc_pos--; - param_pos--; -#if DEBUG - printf ("\n ret=%lx opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos); -#endif - ret += ((insn >> opc_pos) & 0x1) << param_pos; - - if (!param_pos - && letter_signed (param_ch) - && ret >> (letter_range (param_ch) - 1)) - { -#if DEBUG - printf ("\n ret=%lx opc_pos=%x, param_pos=%x\n", - ret, opc_pos, param_pos); -#endif - ret |= 0xffffffff << letter_range(param_ch); -#if DEBUG - printf ("\n after conversion to signed: ret=%lx\n", ret); -#endif - } - enc++; - } - else if (ISALPHA (*enc)) - { - opc_pos--; - enc++; - } - else if (*enc == '-') - { - opc_pos--; - enc++; - } - else - enc++; - -#if DEBUG - printf ("ret=%lx\n", ret); -#endif - return ret; -} - -static int -or32_opcode_match (unsigned long insn, char *encoding) -{ - unsigned long ones, zeros; - -#if DEBUG - printf ("or32_opcode_match: %.8lx\n", insn); -#endif - ones = or32_extract ('1', encoding, insn); - zeros = or32_extract ('0', encoding, insn); - -#if DEBUG - printf ("ones: %lx \n", ones); - printf ("zeros: %lx \n", zeros); -#endif - if ((insn & ones) != ones) - { -#if DEBUG - printf ("ret1\n"); -#endif - return 0; - } - - if ((~insn & zeros) != zeros) - { -#if DEBUG - printf ("ret2\n"); -#endif - return 0; - } - -#if DEBUG - printf ("ret3\n"); -#endif - return 1; -} - -/* Print register to INFO->STREAM. Used only by print_insn. */ - -static void -or32_print_register (char param_ch, - char *encoding, - unsigned long insn, - struct disassemble_info *info) -{ - int regnum = or32_extract (param_ch, encoding, insn); - -#if DEBUG - printf ("or32_print_register: %c, %s, %lx\n", param_ch, encoding, insn); -#endif - if (param_ch == 'A') - (*info->fprintf_func) (info->stream, "r%d", regnum); - else if (param_ch == 'B') - (*info->fprintf_func) (info->stream, "r%d", regnum); - else if (param_ch == 'D') - (*info->fprintf_func) (info->stream, "r%d", regnum); - else if (regnum < 16) - (*info->fprintf_func) (info->stream, "r%d", regnum); - else if (regnum < 32) - (*info->fprintf_func) (info->stream, "r%d", regnum-16); - else - (*info->fprintf_func) (info->stream, "X%d", regnum); -} - -/* Print immediate to INFO->STREAM. Used only by print_insn. */ - -static void -or32_print_immediate (char param_ch, - char *encoding, - unsigned long insn, - struct disassemble_info *info) -{ - int imm = or32_extract(param_ch, encoding, insn); - - if (letter_signed(param_ch)) - (*info->fprintf_func) (info->stream, "0x%x", imm); -/* (*info->fprintf_func) (info->stream, "%d", imm); */ - else - (*info->fprintf_func) (info->stream, "0x%x", imm); -} - -/* Print one instruction from MEMADDR on INFO->STREAM. - Return the size of the instruction (always 4 on or32). */ - -static int -print_insn (bfd_vma memaddr, struct disassemble_info *info) -{ - /* The raw instruction. */ - unsigned char insn_ch[4]; - /* Address. Will be sign extened 27-bit. */ - unsigned long addr; - /* The four bytes of the instruction. */ - unsigned long insn; - find_byte_func_type find_byte_func = (find_byte_func_type) info->private_data; - struct or32_opcode const * opcode; - - { - int status = - (*info->read_memory_func) (memaddr, (bfd_byte *) &insn_ch[0], 4, info); - - if (status != 0) - { - (*info->memory_error_func) (status, memaddr, info); - return -1; - } - } - - (*find_byte_func) (&insn_ch[0], &insn); - - for (opcode = &or32_opcodes[0]; - opcode < &or32_opcodes[or32_num_opcodes]; - ++opcode) - { - if (or32_opcode_match (insn, opcode->encoding)) - { - char *s; - - (*info->fprintf_func) (info->stream, "%s ", opcode->name); - - for (s = opcode->args; *s != '\0'; ++s) - { - switch (*s) - { - case '\0': - return 4; - - case 'r': - or32_print_register (*++s, opcode->encoding, insn, info); - break; - - case 'X': - addr = or32_extract ('X', opcode->encoding, insn) << 2; - - /* Calulate the correct address. XXX is this really correct ?? */ - addr = memaddr + EXTEND29 (addr); - - (*info->print_address_func) - (addr, info); - break; - - default: - if (strchr (opcode->encoding, *s)) - or32_print_immediate (*s, opcode->encoding, insn, info); - else - (*info->fprintf_func) (info->stream, "%c", *s); - } - } - - return 4; - } - } - - /* This used to be %8x for binutils. */ - (*info->fprintf_func) - (info->stream, ".word 0x%08lx", insn); - return 4; -} - -/* Disassemble a big-endian or32 instruction. */ - -int -print_insn_big_or32 (bfd_vma memaddr, struct disassemble_info *info) -{ - info->private_data = find_bytes_big; - - return print_insn (memaddr, info); -} - -/* Disassemble a little-endian or32 instruction. */ - -int -print_insn_little_or32 (bfd_vma memaddr, struct disassemble_info *info) -{ - info->private_data = find_bytes_little; - return print_insn (memaddr, info); -} diff -rNU3 dist.orig/opcodes/or32-opc.c dist/opcodes/or32-opc.c --- dist.orig/opcodes/or32-opc.c 2012-05-17 17:13:25.000000000 +0200 +++ dist/opcodes/or32-opc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1031 +0,0 @@ -/* Table of opcodes for the OpenRISC 1000 ISA. - Copyright 2002, 2004, 2005, 2007, 2008, 2009, 2012 - Free Software Foundation, Inc. - Contributed by Damjan Lampret (lampret@opencores.org). - - 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 "sysdep.h" -#include -#include -#include -#include "safe-ctype.h" -#include "ansidecl.h" -#include "opcode/or32.h" - -/* We treat all letters the same in encode/decode routines so - we need to assign some characteristics to them like signess etc. */ - -const struct or32_letter or32_letters[] = -{ - { 'A', NUM_UNSIGNED }, - { 'B', NUM_UNSIGNED }, - { 'D', NUM_UNSIGNED }, - { 'I', NUM_SIGNED }, - { 'K', NUM_UNSIGNED }, - { 'L', NUM_UNSIGNED }, - { 'N', NUM_SIGNED }, - { '0', NUM_UNSIGNED }, - { '\0', 0 } /* Dummy entry. */ -}; - -/* Opcode encoding: - machine[31:30]: first two bits of opcode - 00 - neither of source operands is GPR - 01 - second source operand is GPR (rB) - 10 - first source operand is GPR (rA) - 11 - both source operands are GPRs (rA and rB) - machine[29:26]: next four bits of opcode - machine[25:00]: instruction operands (specific to individual instruction) - - Recommendation: irrelevant instruction bits should be set with a value of - bits in same positions of instruction preceding current instruction in the - code (when assembling). */ - -#define EFN &l_none - -#ifdef HAS_EXECUTION -#define EF(func) &(func) -#define EFI &l_invalid -#else /* HAS_EXECUTION */ -#define EF(func) EFN -#define EFI EFN -#endif /* HAS_EXECUTION */ - -const struct or32_opcode or32_opcodes[] = -{ - { "l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY }, - { "l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY }, - { "l.bnf", "N", "00 0x3 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG}, - { "l.bf", "N", "00 0x4 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG }, - { "l.nop", "K", "00 0x5 01--- ----- KKKK KKKK KKKK KKKK", EF(l_nop), 0 }, - { "l.movhi", "rD,K", "00 0x6 DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/ - { "l.macrc", "rD", "00 0x6 DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/ - - { "l.sys", "K", "00 0x8 00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 }, - { "l.trap", "K", "00 0x8 01000 00000 KKKK KKKK KKKK KKKK", EF(l_trap), 0 }, /* CZ 21/06/01 */ - { "l.msync", "", "00 0x8 10000 00000 0000 0000 0000 0000", EFN, 0 }, - { "l.psync", "", "00 0x8 10100 00000 0000 0000 0000 0000", EFN, 0 }, - { "l.csync", "", "00 0x8 11000 00000 0000 0000 0000 0000", EFN, 0 }, - { "l.rfe", "", "00 0x9 ----- ----- ---- ---- ---- ----", EF(l_rfe), OR32_IF_DELAY }, - - { "lv.all_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 }, - { "lv.all_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 }, - { "lv.all_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 }, - { "lv.all_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 }, - { "lv.all_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 }, - { "lv.all_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 }, - { "lv.all_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 }, - { "lv.all_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 }, - { "lv.all_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0 }, - { "lv.all_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0 }, - { "lv.all_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0 }, - { "lv.all_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0 }, - { "lv.any_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0 }, - { "lv.any_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0 }, - { "lv.any_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0 }, - { "lv.any_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0 }, - { "lv.any_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0 }, - { "lv.any_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0 }, - { "lv.any_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0 }, - { "lv.any_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0 }, - { "lv.any_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0 }, - { "lv.any_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0 }, - { "lv.any_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0 }, - { "lv.any_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0 }, - { "lv.add.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0 }, - { "lv.add.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0 }, - { "lv.adds.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0 }, - { "lv.adds.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0 }, - { "lv.addu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0 }, - { "lv.addu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0 }, - { "lv.addus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0 }, - { "lv.addus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0 }, - { "lv.and", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0 }, - { "lv.avg.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0 }, - { "lv.avg.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0 }, - { "lv.cmp_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0 }, - { "lv.cmp_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0 }, - { "lv.cmp_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0 }, - { "lv.cmp_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0 }, - { "lv.cmp_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0 }, - { "lv.cmp_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0 }, - { "lv.cmp_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0 }, - { "lv.cmp_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0 }, - { "lv.cmp_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0 }, - { "lv.cmp_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0 }, - { "lv.cmp_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0 }, - { "lv.cmp_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0 }, - { "lv.madds.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0 }, - { "lv.max.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0 }, - { "lv.max.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0 }, - { "lv.merge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0 }, - { "lv.merge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0 }, - { "lv.min.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0 }, - { "lv.min.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0 }, - { "lv.msubs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0 }, - { "lv.muls.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0 }, - { "lv.nand", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0 }, - { "lv.nor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0 }, - { "lv.or", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0 }, - { "lv.pack.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0 }, - { "lv.pack.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0 }, - { "lv.packs.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0 }, - { "lv.packs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0 }, - { "lv.packus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0 }, - { "lv.packus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0 }, - { "lv.perm.n", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0 }, - { "lv.rl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0 }, - { "lv.rl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0 }, - { "lv.sll.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0 }, - { "lv.sll.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0 }, - { "lv.sll", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0 }, - { "lv.srl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0 }, - { "lv.srl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0 }, - { "lv.sra.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0 }, - { "lv.sra.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0 }, - { "lv.srl", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0 }, - { "lv.sub.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0 }, - { "lv.sub.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0 }, - { "lv.subs.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0 }, - { "lv.subs.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0 }, - { "lv.subu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0 }, - { "lv.subu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0 }, - { "lv.subus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0 }, - { "lv.subus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0 }, - { "lv.unpack.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0 }, - { "lv.unpack.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0 }, - { "lv.xor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0 }, - { "lv.cust1", "", "00 0xA ----- ----- ---- ---- 0xC ----", EFI, 0 }, - { "lv.cust2", "", "00 0xA ----- ----- ---- ---- 0xD ----", EFI, 0 }, - { "lv.cust3", "", "00 0xA ----- ----- ---- ---- 0xE ----", EFI, 0 }, - { "lv.cust4", "", "00 0xA ----- ----- ---- ---- 0xF ----", EFI, 0 }, - - { "lf.add.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 }, - { "lf.sub.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 }, - { "lf.mul.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 }, - { "lf.div.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 }, - { "lf.itof.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 }, - { "lf.ftoi.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 }, - { "lf.rem.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 }, - { "lf.madd.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 }, - { "lf.sfeq.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 }, - { "lf.sfne.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 }, - { "lf.sfgt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 }, - { "lf.sfge.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 }, - { "lf.sflt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 }, - { "lf.sfle.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 }, - { "lf.cust1.s", "", "00 0xB ----- ----- ---- ---- 0xE ----", EFI, 0 }, - - { "lf.add.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 }, - { "lf.sub.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 }, - { "lf.mul.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 }, - { "lf.div.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 }, - { "lf.itof.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 }, - { "lf.ftoi.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 }, - { "lf.rem.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 }, - { "lf.madd.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 }, - { "lf.sfeq.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 }, - { "lf.sfne.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 }, - { "lf.sfgt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 }, - { "lf.sfge.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 }, - { "lf.sflt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 }, - { "lf.sfle.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 }, - { "lf.cust1.d", "", "00 0xC ----- ----- ---- ---- 0xE ----", EFI, 0 }, - - { "lvf.ld", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x0", EFI, 0 }, - { "lvf.lw", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x1", EFI, 0 }, - { "lvf.sd", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x0", EFI, 0 }, - { "lvf.sw", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x1", EFI, 0 }, - - { "l.jr", "rB", "01 0x1 ----- ----- BBBB B--- ---- ----", EF(l_jr), OR32_IF_DELAY }, - { "l.jalr", "rB", "01 0x2 ----- ----- BBBB B--- ---- ----", EF(l_jalr), OR32_IF_DELAY }, - { "l.maci", "rB,I", "01 0x3 IIIII ----- BBBB BIII IIII IIII", EF(l_mac), 0 }, - { "l.cust1", "", "01 0xC ----- ----- ---- ---- ---- ----", EF(l_cust1), 0 }, - { "l.cust2", "", "01 0xD ----- ----- ---- ---- ---- ----", EF(l_cust2), 0 }, - { "l.cust3", "", "01 0xE ----- ----- ---- ---- ---- ----", EF(l_cust3), 0 }, - { "l.cust4", "", "01 0xF ----- ----- ---- ---- ---- ----", EF(l_cust4), 0 }, - - { "l.ld", "rD,I(rA)", "10 0x0 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 }, - { "l.lwz", "rD,I(rA)", "10 0x1 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lwz), 0 }, - { "l.lws", "rD,I(rA)", "10 0x2 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 }, - { "l.lbz", "rD,I(rA)", "10 0x3 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbz), 0 }, - { "l.lbs", "rD,I(rA)", "10 0x4 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbs), 0 }, - { "l.lhz", "rD,I(rA)", "10 0x5 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhz), 0 }, - { "l.lhs", "rD,I(rA)", "10 0x6 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhs), 0 }, - - { "l.addi", "rD,rA,I", "10 0x7 DDDDD AAAAA IIII IIII IIII IIII", EF(l_add), 0 }, - { "l.addic", "rD,rA,I", "10 0x8 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 }, - { "l.andi", "rD,rA,K", "10 0x9 DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_and), 0 }, - { "l.ori", "rD,rA,K", "10 0xA DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_or), 0 }, - { "l.xori", "rD,rA,I", "10 0xB DDDDD AAAAA IIII IIII IIII IIII", EF(l_xor), 0 }, - { "l.muli", "rD,rA,I", "10 0xC DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 }, - { "l.mfspr", "rD,rA,K", "10 0xD DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 }, - { "l.slli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 }, - { "l.srli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 }, - { "l.srai", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 }, - { "l.rori", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 }, - - { "l.sfeqi", "rA,I", "10 0xF 00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), OR32_W_FLAG }, - { "l.sfnei", "rA,I", "10 0xF 00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), OR32_W_FLAG }, - { "l.sfgtui", "rA,I", "10 0xF 00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), OR32_W_FLAG }, - { "l.sfgeui", "rA,I", "10 0xF 00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), OR32_W_FLAG }, - { "l.sfltui", "rA,I", "10 0xF 00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), OR32_W_FLAG }, - { "l.sfleui", "rA,I", "10 0xF 00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), OR32_W_FLAG }, - { "l.sfgtsi", "rA,I", "10 0xF 01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), OR32_W_FLAG }, - { "l.sfgesi", "rA,I", "10 0xF 01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), OR32_W_FLAG }, - { "l.sfltsi", "rA,I", "10 0xF 01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), OR32_W_FLAG }, - { "l.sflesi", "rA,I", "10 0xF 01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), OR32_W_FLAG }, - - { "l.mtspr", "rA,rB,K", "11 0x0 KKKKK AAAAA BBBB BKKK KKKK KKKK", EF(l_mtspr), 0 }, - { "l.mac", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x1", EF(l_mac), 0 }, /*MM*/ - { "l.msb", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x2", EF(l_msb), 0 }, /*MM*/ - - { "l.sd", "I(rA),rB", "11 0x4 IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 }, - { "l.sw", "I(rA),rB", "11 0x5 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 }, - { "l.sb", "I(rA),rB", "11 0x6 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 }, - { "l.sh", "I(rA),rB", "11 0x7 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 }, - - { "l.add", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x0", EF(l_add), 0 }, - { "l.addc", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x1", EFI, 0 }, - { "l.sub", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x2", EF(l_sub), 0 }, - { "l.and", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x3", EF(l_and), 0 }, - { "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 }, - { "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 }, - { "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 }, - - { "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 }, - { "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 }, - { "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 }, - { "l.ror", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 }, - { "l.div", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 }, - { "l.divu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 }, - { "l.mulu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 }, - { "l.exths", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xC", EFI, 0 }, - { "l.extbs", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xC", EFI, 0 }, - { "l.exthz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0xC", EFI, 0 }, - { "l.extbz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0xC", EFI, 0 }, - { "l.extws", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xD", EFI, 0 }, - { "l.extwz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xD", EFI, 0 }, - { "l.cmov", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 }, - { "l.ff1", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 }, - - { "l.sfeq", "rA,rB", "11 0x9 00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), OR32_W_FLAG }, - { "l.sfne", "rA,rB", "11 0x9 00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), OR32_W_FLAG }, - { "l.sfgtu", "rA,rB", "11 0x9 00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), OR32_W_FLAG }, - { "l.sfgeu", "rA,rB", "11 0x9 00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), OR32_W_FLAG }, - { "l.sfltu", "rA,rB", "11 0x9 00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), OR32_W_FLAG }, - { "l.sfleu", "rA,rB", "11 0x9 00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), OR32_W_FLAG }, - { "l.sfgts", "rA,rB", "11 0x9 01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), OR32_W_FLAG }, - { "l.sfges", "rA,rB", "11 0x9 01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), OR32_W_FLAG }, - { "l.sflts", "rA,rB", "11 0x9 01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), OR32_W_FLAG }, - { "l.sfles", "rA,rB", "11 0x9 01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), OR32_W_FLAG }, - - { "l.cust5", "", "11 0xC ----- ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust6", "", "11 0xD ----- ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 }, - - /* This section should not be defined in or1ksim, since it contains duplicates, - which would cause machine builder to complain. */ -#ifdef HAS_CUST - { "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 }, - { "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 }, - - { "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 }, - { "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 }, - - { "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 }, - { "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 }, - - { "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 }, - { "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 }, - { "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 }, -#endif - - /* Dummy entry, not included in num_opcodes. This - lets code examine entry i+1 without checking - if we've run off the end of the table. */ - { "", "", "", EFI, 0 } -}; - -#undef EFI -#undef EFN -#undef EF - -/* Define dummy, if debug is not defined. */ - -#if !defined HAS_DEBUG -static void ATTRIBUTE_PRINTF_2 -debug (int level ATTRIBUTE_UNUSED, const char *format ATTRIBUTE_UNUSED, ...) -{ -} -#endif - -const unsigned int or32_num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1; - -/* Calculates instruction length in bytes. Always 4 for OR32. */ - -int -insn_len (int i_index ATTRIBUTE_UNUSED) -{ - return 4; -} - -/* Is individual insn's operand signed or unsigned? */ - -int -letter_signed (char l) -{ - const struct or32_letter *pletter; - - for (pletter = or32_letters; pletter->letter != '\0'; pletter++) - if (pletter->letter == l) - return pletter->sign; - - printf ("letter_signed(%c): Unknown letter.\n", l); - return 0; -} - -/* Number of letters in the individual lettered operand. */ - -int -letter_range (char l) -{ - const struct or32_opcode *pinsn; - char *enc; - int range = 0; - - for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn ++) - { - if (strchr (pinsn->encoding,l)) - { - for (enc = pinsn->encoding; *enc != '\0'; enc ++) - if ((*enc == '0') && (*(enc + 1) == 'x')) - enc += 2; - else if (*enc == l) - range++; - return range; - } - } - - printf ("\nABORT: letter_range(%c): Never used letter.\n", l); - exit (1); -} - -/* MM: Returns index of given instruction name. */ - -int -insn_index (char *insn) -{ - unsigned int i; - int found = -1; - - for (i = 0; i < or32_num_opcodes; i++) - if (!strcmp (or32_opcodes[i].name, insn)) - { - found = i; - break; - } - return found; -} - -const char * -insn_name (int op_index) -{ - if (op_index >= 0 && op_index < (int) or32_num_opcodes) - return or32_opcodes[op_index].name; - else - return "???"; -} - -void -l_none (void) -{ -} - -/* Finite automata for instruction decoding building code. */ - -/* Find simbols in encoding. */ - -static unsigned long -insn_extract (char param_ch, char *enc_initial) -{ - char *enc; - unsigned long ret = 0; - unsigned opc_pos = 32; - - for (enc = enc_initial; *enc != '\0'; ) - if ((*enc == '0') && (*(enc + 1) == 'x')) - { - unsigned long tmp = strtol (enc+2, NULL, 16); - - opc_pos -= 4; - if (param_ch == '0' || param_ch == '1') - { - if (param_ch == '0') - tmp = 15 - tmp; - ret |= tmp << opc_pos; - } - enc += 3; - } - else - { - if (*enc == '0' || *enc == '1' || *enc == '-' || ISALPHA (*enc)) - { - opc_pos--; - if (param_ch == *enc) - ret |= 1 << opc_pos; - } - enc++; - } - return ret; -} - -#define MAX_AUTOMATA_SIZE 1200 -#define MAX_OP_TABLE_SIZE 1200 -#define LEAF_FLAG 0x80000000 -#define MAX_LEN 8 - -#ifndef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#endif - -unsigned long *automata; -int nuncovered; -int curpass = 0; - -/* MM: Struct that hold runtime build information about instructions. */ -struct temp_insn_struct -{ - unsigned long insn; - unsigned long insn_mask; - int in_pass; -} *ti; - -struct insn_op_struct *op_data, **op_start; - -/* Recursive utility function used to find best match and to build automata. */ - -static unsigned long * -cover_insn (unsigned long * cur, int pass, unsigned int mask) -{ - int best_first = 0, last_match = -1, ninstr = 0; - unsigned int best_len = 0; - unsigned int i; - unsigned long cur_mask = mask; - unsigned long *next; - - for (i = 0; i < or32_num_opcodes; i++) - if (ti[i].in_pass == pass) - { - cur_mask &= ti[i].insn_mask; - ninstr++; - last_match = i; - } - - debug (8, "%08X %08lX\n", mask, cur_mask); - - if (ninstr == 0) - return 0; - - if (ninstr == 1) - { - /* Leaf holds instruction index. */ - debug (8, "%li>I%i %s\n", - (long)(cur - automata), last_match, or32_opcodes[last_match].name); - - *cur = LEAF_FLAG | last_match; - cur++; - nuncovered--; - } - else - { - /* Find longest match. */ - for (i = 0; i < 32; i++) - { - unsigned int len; - - for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++) - { - unsigned long m = (1UL << ((unsigned long) len)) - 1; - - debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)", - len,m, cur_mask, i, (cur_mask >> (unsigned)i), - (cur_mask >> (unsigned) i) & m); - - if ((m & (cur_mask >> (unsigned) i)) == m) - { - best_len = len; - best_first = i; - debug (9, "!"); - } - else - break; - } - } - - debug (9, "\n"); - - if (!best_len) - { - fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask); - - for (i = 0; i < or32_num_opcodes; i++) - if (ti[i].in_pass == pass) - fprintf (stderr, "%s ", or32_opcodes[i].name); - - fprintf (stderr, "\n"); - exit (1); - } - - debug (8, "%li> #### %i << %i (%i) ####\n", - (long)(cur - automata), best_len, best_first, ninstr); - - *cur = best_first; - cur++; - *cur = (1 << best_len) - 1; - cur++; - next = cur; - - /* Allocate space for pointers. */ - cur += 1 << best_len; - cur_mask = (1 << (unsigned long) best_len) - 1; - - for (i = 0; i < ((unsigned) 1 << best_len); i++) - { - unsigned int j; - unsigned long *c; - - curpass++; - for (j = 0; j < or32_num_opcodes; j++) - if (ti[j].in_pass == pass - && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i - && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask) - ti[j].in_pass = curpass; - - debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first); - c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first))); - if (c) - { - debug (8, "%li> #%X -> %lu\n", (long)(next - automata), i, - (unsigned long)(cur - automata)); - *next = cur - automata; - cur = c; - } - else - { - debug (8, "%li> N/A\n", (long)(next - automata)); - *next = 0; - } - next++; - } - } - return cur; -} - -/* Returns number of nonzero bits. */ - -static int -num_ones (unsigned long value) -{ - int c = 0; - - while (value) - { - if (value & 1) - c++; - value >>= 1; - } - return c; -} - -/* Utility function, which converts parameters from or32_opcode - format to more binary form. Parameters are stored in ti struct. */ - -static struct insn_op_struct * -parse_params (const struct or32_opcode * opcode, - struct insn_op_struct * cur) -{ - char *args = opcode->args; - int i, type; - - i = 0; - type = 0; - /* In case we don't have any parameters, we add dummy read from r0. */ - - if (!(*args)) - { - cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST; - cur->data = 0; - debug (9, "#%08lX %08lX\n", cur->type, cur->data); - cur++; - return cur; - } - - while (*args != '\0') - { - if (*args == 'r') - { - args++; - type |= OPTYPE_REG; - } - else if (ISALPHA (*args)) - { - unsigned long arg; - - arg = insn_extract (*args, opcode->encoding); - debug (9, "%s : %08lX ------\n", opcode->name, arg); - if (letter_signed (*args)) - { - type |= OPTYPE_SIG; - type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT; - } - - /* Split argument to sequences of consecutive ones. */ - while (arg) - { - int shr = 0; - unsigned long tmp = arg, mask = 0; - - while ((tmp & 1) == 0) - { - shr++; - tmp >>= 1; - } - while (tmp & 1) - { - mask++; - tmp >>= 1; - } - cur->type = type | shr; - cur->data = mask; - arg &= ~(((1 << mask) - 1) << shr); - debug (6, "|%08lX %08lX\n", cur->type, cur->data); - cur++; - } - args++; - } - else if (*args == '(') - { - /* Next param is displacement. - Later we will treat them as one operand. */ - cur--; - cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP; - debug (9, ">%08lX %08lX\n", cur->type, cur->data); - cur++; - type = 0; - i++; - args++; - } - else if (*args == OPERAND_DELIM) - { - cur--; - cur->type = type | cur->type | OPTYPE_OP; - debug (9, ">%08lX %08lX\n", cur->type, cur->data); - cur++; - type = 0; - i++; - args++; - } - else if (*args == '0') - { - cur->type = type; - cur->data = 0; - debug (9, ">%08lX %08lX\n", cur->type, cur->data); - cur++; - type = 0; - i++; - args++; - } - else if (*args == ')') - args++; - else - { - fprintf (stderr, "%s : parse error in args.\n", opcode->name); - exit (1); - } - } - - cur--; - cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST; - debug (9, "#%08lX %08lX\n", cur->type, cur->data); - cur++; - - return cur; -} - -/* Constructs new automata based on or32_opcodes array. */ - -void -build_automata (void) -{ - unsigned int i; - unsigned long *end; - struct insn_op_struct *cur; - - automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long)); - ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes); - - nuncovered = or32_num_opcodes; - printf ("Building automata... "); - /* Build temporary information about instructions. */ - for (i = 0; i < or32_num_opcodes; i++) - { - unsigned long ones, zeros; - char *encoding = or32_opcodes[i].encoding; - - ones = insn_extract('1', encoding); - zeros = insn_extract('0', encoding); - - ti[i].insn_mask = ones | zeros; - ti[i].insn = ones; - ti[i].in_pass = curpass = 0; - - /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name, - or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/ - } - - /* Until all are covered search for best criteria to separate them. */ - end = cover_insn (automata, curpass, 0xFFFFFFFF); - - if (end - automata > MAX_AUTOMATA_SIZE) - { - fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE."); - exit (1); - } - - printf ("done, num uncovered: %i/%i.\n", nuncovered, or32_num_opcodes); - printf ("Parsing operands data... "); - - op_data = malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct)); - op_start = malloc (or32_num_opcodes * sizeof (struct insn_op_struct *)); - cur = op_data; - - for (i = 0; i < or32_num_opcodes; i++) - { - op_start[i] = cur; - cur = parse_params (&or32_opcodes[i], cur); - - if (cur - op_data > MAX_OP_TABLE_SIZE) - { - fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n"); - exit (1); - } - } - printf ("done.\n"); -} - -void -destruct_automata (void) -{ - free (ti); - free (automata); - free (op_data); - free (op_start); -} - -/* Decodes instruction and returns instruction index. */ - -int -insn_decode (unsigned int insn) -{ - unsigned long *a = automata; - int i; - - while (!(*a & LEAF_FLAG)) - { - unsigned int first = *a; - - debug (9, "%li ", (long)(a - automata)); - - a++; - i = (insn >> first) & *a; - a++; - if (!*(a + i)) - { - /* Invalid instruction found? */ - debug (9, "XXX\n"); - return -1; - } - a = automata + *(a + i); - } - - i = *a & ~LEAF_FLAG; - - debug (9, "%i\n", i); - - /* Final check - do we have direct match? - (based on or32_opcodes this should be the only possibility, - but in case of invalid/missing instruction we must perform a check) */ - if ((ti[i].insn_mask & insn) == ti[i].insn) - return i; - else - return -1; -} - -static char disassembled_str[50]; -char *disassembled = &disassembled_str[0]; - -/* Automagically does zero- or sign- extension and also finds correct - sign bit position if sign extension is correct extension. Which extension - is proper is figured out from letter description. */ - -static unsigned long -extend_imm (unsigned long imm, char l) -{ - unsigned long mask; - int letter_bits; - - /* First truncate all bits above valid range for this letter - in case it is zero extend. */ - letter_bits = letter_range (l); - mask = (1 << letter_bits) - 1; - imm &= mask; - - /* Do sign extend if this is the right one. */ - if (letter_signed(l) && (imm >> (letter_bits - 1))) - imm |= (~mask); - - return imm; -} - -static unsigned long -or32_extract (char param_ch, char *enc_initial, unsigned long insn) -{ - char *enc; - unsigned long ret = 0; - int opc_pos = 0; - int param_pos = 0; - - for (enc = enc_initial; *enc != '\0'; enc++) - if (*enc == param_ch) - { - if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x')) - continue; - else - param_pos++; - } - -#if DEBUG - printf ("or32_extract: %x ", param_pos); -#endif - opc_pos = 32; - - for (enc = enc_initial; *enc != '\0'; ) - if ((*enc == '0') && (*(enc + 1) == 'x')) - { - opc_pos -= 4; - if ((param_ch == '0') || (param_ch == '1')) - { - unsigned long tmp = strtol (enc, NULL, 16); -#if DEBUG - printf (" enc=%s, tmp=%lx ", enc, tmp); -#endif - if (param_ch == '0') - tmp = 15 - tmp; - ret |= tmp << opc_pos; - } - enc += 3; - } - else if ((*enc == '0') || (*enc == '1')) - { - opc_pos--; - if (param_ch == *enc) - ret |= 1 << opc_pos; - enc++; - } - else if (*enc == param_ch) - { - opc_pos--; - param_pos--; -#if DEBUG - printf ("\n ret=%lx opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos); -#endif - if (ISLOWER (param_ch)) - ret -= ((insn >> opc_pos) & 0x1) << param_pos; - else - ret += ((insn >> opc_pos) & 0x1) << param_pos; - enc++; - } - else if (ISALPHA (*enc)) - { - opc_pos--; - enc++; - } - else if (*enc == '-') - { - opc_pos--; - enc++; - } - else - enc++; - -#if DEBUG - printf ("ret=%lx\n", ret); -#endif - return ret; -} - -/* Print register. Used only by print_insn. */ - -static void -or32_print_register (char param_ch, char *encoding, unsigned long insn) -{ - int regnum = or32_extract(param_ch, encoding, insn); - char s_regnum[20]; - - sprintf (s_regnum, "r%d", regnum); - strcat (disassembled, s_regnum); -} - -/* Print immediate. Used only by print_insn. */ - -static void -or32_print_immediate (char param_ch, char *encoding, unsigned long insn) -{ - int imm = or32_extract (param_ch, encoding, insn); - char s_imm[20]; - - imm = extend_imm (imm, param_ch); - - if (letter_signed (param_ch)) - { - if (imm < 0) - sprintf (s_imm, "%d", imm); - else - sprintf (s_imm, "0x%x", imm); - } - else - sprintf (s_imm, "%#x", imm); - strcat (disassembled, s_imm); -} - -/* Disassemble one instruction from insn to disassemble. - Return the size of the instruction. */ - -int -disassemble_insn (unsigned long insn) -{ - int op_index; - op_index = insn_decode (insn); - - if (op_index >= 0) - { - struct or32_opcode const *opcode = &or32_opcodes[op_index]; - char *s; - - sprintf (disassembled, "%s ", opcode->name); - for (s = opcode->args; *s != '\0'; ++s) - { - switch (*s) - { - case '\0': - return 4; - - case 'r': - or32_print_register (*++s, opcode->encoding, insn); - break; - - default: - if (strchr (opcode->encoding, *s)) - or32_print_immediate (*s, opcode->encoding, insn); - else - { - char s_encoding[2] = { *s, '\0' }; - - strcat (disassembled, s_encoding); - } - - } - } - } - else - { - char s_insn[20]; - - /* This used to be %8x for binutils. */ - sprintf (s_insn, ".word 0x%08lx", insn); - strcat (disassembled, s_insn); - } - - return insn_len (insn); -} diff -rNU3 dist.orig/opcodes/riscv-dis.c dist/opcodes/riscv-dis.c --- dist.orig/opcodes/riscv-dis.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/riscv-dis.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,492 @@ +/* RISC-V disassembler + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + 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 "sysdep.h" +#include "dis-asm.h" +#include "libiberty.h" +#include "opcode/riscv.h" +#include "opintl.h" +#include "elf-bfd.h" +#include "elf/riscv.h" + +#include +#include + +struct riscv_private_data +{ + bfd_vma gp; + bfd_vma print_addr; + bfd_vma hi_addr[OP_MASK_RD + 1]; +}; + +static const char * const *riscv_gpr_names; +static const char * const *riscv_fpr_names; + +/* Other options */ +static int no_aliases; /* If set disassemble as most general inst. */ + +static void +set_default_riscv_dis_options (void) +{ + riscv_gpr_names = riscv_gpr_names_abi; + riscv_fpr_names = riscv_fpr_names_abi; + no_aliases = 0; +} + +static void +parse_riscv_dis_option (const char *option) +{ + if (CONST_STRNEQ (option, "no-aliases")) + no_aliases = 1; + else if (CONST_STRNEQ (option, "numeric")) + { + riscv_gpr_names = riscv_gpr_names_numeric; + riscv_fpr_names = riscv_fpr_names_numeric; + } + + /* Invalid option. */ + fprintf (stderr, _("Unrecognized disassembler option: %s\n"), option); +} + +static void +parse_riscv_dis_options (const char *opts_in) +{ + char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts; + + set_default_riscv_dis_options (); + + for ( ; opt_end != NULL; opt = opt_end + 1) + { + if ((opt_end = strchr (opt, ',')) != NULL) + *opt_end = 0; + parse_riscv_dis_option (opt); + } + + free (opts); +} + +/* Print one argument from an array. */ + +static void +arg_print (struct disassemble_info *info, unsigned long val, + const char* const* array, size_t size) +{ + const char *s = val >= size || array[val] == NULL ? "unknown" : array[val]; + (*info->fprintf_func) (info->stream, "%s", s); +} + +static void +maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset) +{ + if (pd->hi_addr[base_reg] != (bfd_vma)-1) + { + pd->print_addr = pd->hi_addr[base_reg] + offset; + pd->hi_addr[base_reg] = -1; + } + else if (base_reg == X_GP && pd->gp != (bfd_vma)-1) + pd->print_addr = pd->gp + offset; + else if (base_reg == X_TP) + pd->print_addr = offset; +} + +/* Print insn arguments for 32/64-bit code. */ + +static void +print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info) +{ + struct riscv_private_data *pd = info->private_data; + int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1; + int rd = (l >> OP_SH_RD) & OP_MASK_RD; + + if (*d != '\0') + (*info->fprintf_func) (info->stream, "\t"); + + for (; *d != '\0'; d++) + { + switch (*d) + { + /* Xcustom */ + case '^': + switch (*++d) + { + case 'd': + (*info->fprintf_func) (info->stream, "%d", rd); + break; + case 's': + (*info->fprintf_func) (info->stream, "%d", rs1); + break; + case 't': + (*info->fprintf_func) + ( info->stream, "%d", (int)((l >> OP_SH_RS2) & OP_MASK_RS2)); + break; + case 'j': + (*info->fprintf_func) + ( info->stream, "%d", (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM)); + break; + } + break; + + /* Xhwacha */ + case '#': + switch ( *++d ) { + case 'g': + (*info->fprintf_func) + ( info->stream, "%d", + (int)((l >> OP_SH_IMMNGPR) & OP_MASK_IMMNGPR)); + break; + case 'f': + (*info->fprintf_func) + ( info->stream, "%d", + (int)((l >> OP_SH_IMMNFPR) & OP_MASK_IMMNFPR)); + break; + case 'p': + (*info->fprintf_func) + ( info->stream, "%d", + (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM)); + break; + case 'n': + (*info->fprintf_func) + ( info->stream, "%d", + (int)(((l >> OP_SH_IMMSEGNELM) & OP_MASK_IMMSEGNELM) + 1)); + break; + case 'd': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_gpr_names[(l >> OP_SH_VRD) & OP_MASK_VRD]); + break; + case 's': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_gpr_names[(l >> OP_SH_VRS) & OP_MASK_VRS]); + break; + case 't': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_gpr_names[(l >> OP_SH_VRT) & OP_MASK_VRT]); + break; + case 'r': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_gpr_names[(l >> OP_SH_VRR) & OP_MASK_VRR]); + break; + case 'D': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_fpr_names[(l >> OP_SH_VFD) & OP_MASK_VFD]); + break; + case 'S': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_fpr_names[(l >> OP_SH_VFS) & OP_MASK_VFS]); + break; + case 'T': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_fpr_names[(l >> OP_SH_VFT) & OP_MASK_VFT]); + break; + case 'R': + (*info->fprintf_func) + ( info->stream, "%s", + riscv_vec_fpr_names[(l >> OP_SH_VFR) & OP_MASK_VFR]); + break; + } + break; + + case ',': + case '(': + case ')': + case '[': + case ']': + (*info->fprintf_func) (info->stream, "%c", *d); + break; + + case '0': + break; + + case 'b': + case 's': + (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rs1]); + break; + + case 't': + (*info->fprintf_func) (info->stream, "%s", + riscv_gpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]); + break; + + case 'u': + (*info->fprintf_func) (info->stream, "0x%x", (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS); + break; + + case 'm': + arg_print(info, (l >> OP_SH_RM) & OP_MASK_RM, + riscv_rm, ARRAY_SIZE(riscv_rm)); + break; + + case 'P': + arg_print(info, (l >> OP_SH_PRED) & OP_MASK_PRED, + riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); + break; + + case 'Q': + arg_print(info, (l >> OP_SH_SUCC) & OP_MASK_SUCC, + riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); + break; + + case 'o': + maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l)); + case 'j': + if ((l & MASK_ADDI) == MATCH_ADDI || (l & MASK_JALR) == MATCH_JALR) + maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l)); + (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_ITYPE_IMM (l)); + break; + + case 'q': + maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l)); + (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_STYPE_IMM (l)); + break; + + case 'a': + info->target = EXTRACT_UJTYPE_IMM (l) + pc; + (*info->print_address_func) (info->target, info); + break; + + case 'p': + info->target = EXTRACT_SBTYPE_IMM (l) + pc; + (*info->print_address_func) (info->target, info); + break; + + case 'd': + if ((l & MASK_AUIPC) == MATCH_AUIPC) + pd->hi_addr[rd] = pc + EXTRACT_UTYPE_IMM (l); + else if ((l & MASK_LUI) == MATCH_LUI) + pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l); + (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rd]); + break; + + case 'z': + (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[0]); + break; + + case '>': + (*info->fprintf_func) (info->stream, "0x%x", + (unsigned)((l >> OP_SH_SHAMT) & OP_MASK_SHAMT)); + break; + + case '<': + (*info->fprintf_func) (info->stream, "0x%x", + (unsigned)((l >> OP_SH_SHAMTW) & OP_MASK_SHAMTW)); + break; + + case 'S': + case 'U': + (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rs1]); + break; + + case 'T': + (*info->fprintf_func) (info->stream, "%s", + riscv_fpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]); + break; + + case 'D': + (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rd]); + break; + + case 'R': + (*info->fprintf_func) (info->stream, "%s", + riscv_fpr_names[(l >> OP_SH_RS3) & OP_MASK_RS3]); + break; + + case 'E': + { + const char* csr_name = NULL; + unsigned int csr = (l >> OP_SH_CSR) & OP_MASK_CSR; + switch (csr) + { + #define DECLARE_CSR(name, num) case num: csr_name = #name; break; + #include "opcode/riscv-opc.h" + #undef DECLARE_CSR + } + if (csr_name) + (*info->fprintf_func) (info->stream, "%s", csr_name); + else + (*info->fprintf_func) (info->stream, "0x%x", csr); + break; + } + + case 'Z': + (*info->fprintf_func) (info->stream, "%d", rs1); + break; + + default: + /* xgettext:c-format */ + (*info->fprintf_func) (info->stream, + _("# internal error, undefined modifier (%c)"), + *d); + return; + } + } +} + +/* Print the RISC-V instruction at address MEMADDR in debugged memory, + on using INFO. Returns length of the instruction, in bytes. + BIGENDIAN must be 1 if this is big-endian code, 0 if + this is little-endian code. */ + +static int +riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) +{ + const struct riscv_opcode *op; + static bfd_boolean init = 0; + static const char *extension = NULL; + static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; + struct riscv_private_data *pd; + int insnlen; + + /* Build a hash table to shorten the search time. */ + if (! init) + { + unsigned int i; + unsigned int e_flags = elf_elfheader (info->section->owner)->e_flags; + extension = riscv_elf_flag_to_name(EF_GET_RISCV_EXT(e_flags)); + + for (i = 0; i <= OP_MASK_OP; i++) + for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++) + if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)) + { + riscv_hash[i] = op; + break; + } + + init = 1; + } + + if (info->private_data == NULL) + { + int i; + + pd = info->private_data = calloc(1, sizeof (struct riscv_private_data)); + pd->gp = -1; + pd->print_addr = -1; + for (i = 0; i < (int) ARRAY_SIZE(pd->hi_addr); i++) + pd->hi_addr[i] = -1; + + for (i = 0; i < info->symtab_size; i++) + if (strcmp (bfd_asymbol_name (info->symtab[i]), "_gp") == 0) + pd->gp = bfd_asymbol_value (info->symtab[i]); + } + else + pd = info->private_data; + + insnlen = riscv_insn_length (word); + + info->bytes_per_chunk = insnlen % 4 == 0 ? 4 : 2; + info->bytes_per_line = 8; + info->display_endian = info->endian; + info->insn_info_valid = 1; + info->branch_delay_insns = 0; + info->data_size = 0; + info->insn_type = dis_nonbranch; + info->target = 0; + info->target2 = 0; + + op = riscv_hash[(word >> OP_SH_OP) & OP_MASK_OP]; + if (op != NULL) + { + for (; op < &riscv_opcodes[NUMOPCODES]; op++) + { + if ((op->match_func) (op, word) + && !(no_aliases && (op->pinfo & INSN_ALIAS)) + && !(op->subset[0] == 'X' && strcmp(op->subset, extension))) + { + (*info->fprintf_func) (info->stream, "%s", op->name); + print_insn_args (op->args, word, memaddr, info); + if (pd->print_addr != (bfd_vma)-1) + { + info->target = pd->print_addr; + (*info->fprintf_func) (info->stream, " # "); + (*info->print_address_func) (info->target, info); + pd->print_addr = -1; + } + return insnlen; + } + } + } + + /* Handle undefined instructions. */ + info->insn_type = dis_noninsn; + (*info->fprintf_func) (info->stream, "0x%llx", (unsigned long long)word); + return insnlen; +} + +int +print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) +{ + uint16_t i2; + insn_t insn = 0; + bfd_vma n; + int status; + + if (info->disassembler_options != NULL) + { + parse_riscv_dis_options (info->disassembler_options); + /* Avoid repeatedly parsing the options. */ + info->disassembler_options = NULL; + } + else if (riscv_gpr_names == NULL) + set_default_riscv_dis_options (); + + /* Instructions are a sequence of 2-byte packets in little-endian order. */ + for (n = 0; n < sizeof(insn) && n < riscv_insn_length (insn); n += 2) + { + status = (*info->read_memory_func) (memaddr + n, (bfd_byte*)&i2, 2, info); + if (status != 0) + { + if (n > 0) /* Don't fail just because we fell off the end. */ + break; + (*info->memory_error_func) (status, memaddr, info); + return status; + } + + i2 = bfd_getl16 (&i2); + insn |= (insn_t)i2 << (8*n); + } + + return riscv_disassemble_insn (memaddr, insn, info); +} + +void +print_riscv_disassembler_options (FILE *stream) +{ + fprintf (stream, _("\n\ +The following RISC-V-specific disassembler options are supported for use\n\ +with the -M switch (multiple options should be separated by commas):\n")); + + fprintf (stream, _("\n\ + numeric Print numeric reigster names, rather than ABI names.\n")); + + fprintf (stream, _("\n\ + no-aliases Disassemble only into canonical instructions, rather\n\ + than into pseudoinstructions.\n")); + + fprintf (stream, _("\n")); +} diff -rNU3 dist.orig/opcodes/riscv-opc.c dist/opcodes/riscv-opc.c --- dist.orig/opcodes/riscv-opc.c 1970-01-01 01:00:00.000000000 +0100 +++ dist/opcodes/riscv-opc.c 2015-10-18 13:11:20.000000000 +0200 @@ -0,0 +1,734 @@ +/* RISC-V opcode list + Copyright 2011-2014 Free Software Foundation, Inc. + + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. + Based on MIPS target. + + 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 "sysdep.h" +#include "opcode/riscv.h" +#include + +/* Register names used by gas and objdump. */ + +const char * const riscv_gpr_names_numeric[32] = +{ + "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", + "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", + "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", + "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31" +}; + +const char * const riscv_gpr_names_abi[32] = { + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" +}; + +const char * const riscv_fpr_names_numeric[32] = +{ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" +}; + +const char * const riscv_fpr_names_abi[32] = { + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11" +}; + +const char * const riscv_vec_gpr_names[32] = +{ + "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7", + "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15", + "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23", + "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31" +}; + +const char * const riscv_vec_fpr_names[32] = +{ + "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", + "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15", + "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23", + "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31" +}; + +/* The order of overloaded instructions matters. Label arguments and + register arguments look the same. Instructions that can have either + for arguments must apear in the correct order in this table for the + assembler to pick the right one. In other words, entries with + immediate operands must apear after the same instruction with + registers. + + Because of the lookup algorithm used, entries with the same opcode + name must be contiguous. */ + +#define WR_xd INSN_WRITE_GPR_D +#define WR_fd INSN_WRITE_FPR_D +#define RD_xs1 INSN_READ_GPR_S +#define RD_xs2 INSN_READ_GPR_T +#define RD_fs1 INSN_READ_FPR_S +#define RD_fs2 INSN_READ_FPR_T +#define RD_fs3 INSN_READ_FPR_R + +#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1) +#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2) +#define MASK_RD (OP_MASK_RD << OP_SH_RD) +#define MASK_IMM ENCODE_ITYPE_IMM(-1U) +#define MASK_UIMM ENCODE_UTYPE_IMM(-1U) +#define MASK_RM (OP_MASK_RM << OP_SH_RM) +#define MASK_PRED (OP_MASK_PRED << OP_SH_PRED) +#define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC) +#define MASK_AQ (OP_MASK_AQ << OP_SH_AQ) +#define MASK_RL (OP_MASK_RL << OP_SH_RL) +#define MASK_AQRL (MASK_AQ | MASK_RL) + +static int match_opcode(const struct riscv_opcode *op, insn_t insn) +{ + return (insn & op->mask) == op->match; +} + +static int match_never(const struct riscv_opcode *op ATTRIBUTE_UNUSED, + insn_t insn ATTRIBUTE_UNUSED) +{ + return 0; +} + +static int match_rs1_eq_rs2(const struct riscv_opcode *op, insn_t insn) +{ + return match_opcode(op, insn) && + ((insn & MASK_RS1) >> OP_SH_RS1) == ((insn & MASK_RS2) >> OP_SH_RS2); +} + +const struct riscv_opcode riscv_builtin_opcodes[] = +{ +/* These instructions appear first so that the disassembler will find + them first. The assemblers uses a hash table based on the + instruction name anyhow. */ +/* name, isa, operands, match, mask, pinfo */ +{"unimp", "I", "", 0, 0xffff, match_opcode, 0 }, +{"nop", "I", "", MATCH_ADDI, MASK_ADDI | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS }, +{"li", "I", "d,j", MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd }, /* addi */ +{"li", "I", "d,I", 0, (int) M_LI, match_never, INSN_MACRO }, +{"mv", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"move", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"andi", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, WR_xd|RD_xs1 }, +{"and", "I", "d,s,t", MATCH_AND, MASK_AND, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"and", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"beqz", "I", "s,p", MATCH_BEQ, MASK_BEQ | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 }, +{"beq", "I", "s,t,p", MATCH_BEQ, MASK_BEQ, match_opcode, RD_xs1|RD_xs2 }, +{"blez", "I", "t,p", MATCH_BGE, MASK_BGE | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 }, +{"bgez", "I", "s,p", MATCH_BGE, MASK_BGE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 }, +{"ble", "I", "t,s,p", MATCH_BGE, MASK_BGE, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 }, +{"bleu", "I", "t,s,p", MATCH_BGEU, MASK_BGEU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 }, +{"bge", "I", "s,t,p", MATCH_BGE, MASK_BGE, match_opcode, RD_xs1|RD_xs2 }, +{"bgeu", "I", "s,t,p", MATCH_BGEU, MASK_BGEU, match_opcode, RD_xs1|RD_xs2 }, +{"bltz", "I", "s,p", MATCH_BLT, MASK_BLT | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 }, +{"bgtz", "I", "t,p", MATCH_BLT, MASK_BLT | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 }, +{"blt", "I", "s,t,p", MATCH_BLT, MASK_BLT, match_opcode, RD_xs1|RD_xs2 }, +{"bltu", "I", "s,t,p", MATCH_BLTU, MASK_BLTU, match_opcode, RD_xs1|RD_xs2 }, +{"bgt", "I", "t,s,p", MATCH_BLT, MASK_BLT, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 }, +{"bgtu", "I", "t,s,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 }, +{"bnez", "I", "s,p", MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 }, +{"bne", "I", "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, RD_xs1|RD_xs2 }, +{"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, WR_xd|RD_xs1 }, +{"add", "I", "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"add", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"la", "I", "d,A", 0, (int) M_LA, match_never, INSN_MACRO }, +{"lla", "I", "d,A", 0, (int) M_LLA, match_never, INSN_MACRO }, +{"la.tls.gd", "I", "d,A", 0, (int) M_LA_TLS_GD, match_never, INSN_MACRO }, +{"la.tls.ie", "I", "d,A", 0, (int) M_LA_TLS_IE, match_never, INSN_MACRO }, +{"neg", "I", "d,t", MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */ +{"slli", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, WR_xd|RD_xs1 }, +{"sll", "I", "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"sll", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"srli", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, WR_xd|RD_xs1 }, +{"srl", "I", "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"srl", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"srai", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, WR_xd|RD_xs1 }, +{"sra", "I", "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"sra", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"sub", "I", "d,s,t", MATCH_SUB, MASK_SUB, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"ret", "I", "", MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"j", "I", "a", MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS }, +{"jal", "I", "a", MATCH_JAL | (X_RA << OP_SH_RD), MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS|WR_xd }, +{"jal", "I", "d,a", MATCH_JAL, MASK_JAL, match_opcode, WR_xd }, +{"call", "I", "c", (X_T0 << OP_SH_RS1) | (X_RA << OP_SH_RD), (int) M_CALL, match_never, INSN_MACRO }, +{"tail", "I", "c", (X_T0 << OP_SH_RS1), (int) M_CALL, match_never, INSN_MACRO }, +{"jump", "I", "c,s", 0, (int) M_CALL, match_never, INSN_MACRO }, +{"jr", "I", "s", MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"jr", "I", "s,j", MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"jalr", "I", "s", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"jalr", "I", "s,j", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"jalr", "I", "d,s", MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"jalr", "I", "d,s,j", MATCH_JALR, MASK_JALR, match_opcode, WR_xd|RD_xs1 }, +{"lb", "I", "d,o(s)", MATCH_LB, MASK_LB, match_opcode, WR_xd|RD_xs1 }, +{"lb", "I", "d,A", 0, (int) M_LB, match_never, INSN_MACRO }, +{"lbu", "I", "d,o(s)", MATCH_LBU, MASK_LBU, match_opcode, WR_xd|RD_xs1 }, +{"lbu", "I", "d,A", 0, (int) M_LBU, match_never, INSN_MACRO }, +{"lh", "I", "d,o(s)", MATCH_LH, MASK_LH, match_opcode, WR_xd|RD_xs1 }, +{"lh", "I", "d,A", 0, (int) M_LH, match_never, INSN_MACRO }, +{"lhu", "I", "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, WR_xd|RD_xs1 }, +{"lhu", "I", "d,A", 0, (int) M_LHU, match_never, INSN_MACRO }, +{"lw", "I", "d,o(s)", MATCH_LW, MASK_LW, match_opcode, WR_xd|RD_xs1 }, +{"lw", "I", "d,A", 0, (int) M_LW, match_never, INSN_MACRO }, +{"lui", "I", "d,u", MATCH_LUI, MASK_LUI, match_opcode, WR_xd }, +{"not", "I", "d,s", MATCH_XORI | MASK_IMM, MASK_XORI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"ori", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, WR_xd|RD_xs1 }, +{"or", "I", "d,s,t", MATCH_OR, MASK_OR, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"or", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"auipc", "I", "d,u", MATCH_AUIPC, MASK_AUIPC, match_opcode, WR_xd }, +{"seqz", "I", "d,s", MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"snez", "I", "d,t", MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, +{"sltz", "I", "d,s", MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"sgtz", "I", "d,t", MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, +{"slti", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"slt", "I", "d,s,t", MATCH_SLT, MASK_SLT, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"slt", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, WR_xd|RD_xs1 }, +{"sltiu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, WR_xd|RD_xs1 }, +{"sltu", "I", "d,s,t", MATCH_SLTU, MASK_SLTU, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"sltu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"sgt", "I", "d,t,s", MATCH_SLT, MASK_SLT, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 }, +{"sgtu", "I", "d,t,s", MATCH_SLTU, MASK_SLTU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 }, +{"sb", "I", "t,q(s)", MATCH_SB, MASK_SB, match_opcode, RD_xs1|RD_xs2 }, +{"sb", "I", "t,A,s", 0, (int) M_SB, match_never, INSN_MACRO }, +{"sh", "I", "t,q(s)", MATCH_SH, MASK_SH, match_opcode, RD_xs1|RD_xs2 }, +{"sh", "I", "t,A,s", 0, (int) M_SH, match_never, INSN_MACRO }, +{"sw", "I", "t,q(s)", MATCH_SW, MASK_SW, match_opcode, RD_xs1|RD_xs2 }, +{"sw", "I", "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO }, +{"fence", "I", "", MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS }, +{"fence", "I", "P,Q", MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 }, +{"fence.i", "I", "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 }, +{"rdcycle", "I", "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, WR_xd }, +{"rdinstret", "I", "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, WR_xd }, +{"rdtime", "I", "d", MATCH_RDTIME, MASK_RDTIME, match_opcode, WR_xd }, +{"rdcycleh", "32I", "d", MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, WR_xd }, +{"rdinstreth","32I", "d", MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, WR_xd }, +{"rdtimeh", "32I", "d", MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, WR_xd }, +{"sbreak", "I", "", MATCH_SBREAK, MASK_SBREAK, match_opcode, 0 }, +{"scall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 }, +{"ecall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 }, +{"xori", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, WR_xd|RD_xs1 }, +{"xor", "I", "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"xor", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"lwu", "64I", "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, WR_xd|RD_xs1 }, +{"lwu", "64I", "d,A", 0, (int) M_LWU, match_never, INSN_MACRO }, +{"ld", "64I", "d,o(s)", MATCH_LD, MASK_LD, match_opcode, WR_xd|RD_xs1 }, +{"ld", "64I", "d,A", 0, (int) M_LD, match_never, INSN_MACRO }, +{"sd", "64I", "t,q(s)", MATCH_SD, MASK_SD, match_opcode, RD_xs1|RD_xs2 }, +{"sd", "64I", "t,A,s", 0, (int) M_SD, match_never, INSN_MACRO }, +{"sext.w", "64I", "d,s", MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"addiw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, WR_xd|RD_xs1 }, +{"addw", "64I", "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"addw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"negw", "64I", "d,t", MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */ +{"slliw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, WR_xd|RD_xs1 }, +{"sllw", "64I", "d,s,t", MATCH_SLLW, MASK_SLLW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"sllw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"srliw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, WR_xd|RD_xs1 }, +{"srlw", "64I", "d,s,t", MATCH_SRLW, MASK_SRLW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"srlw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"sraiw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, WR_xd|RD_xs1 }, +{"sraw", "64I", "d,s,t", MATCH_SRAW, MASK_SRAW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"sraw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 }, +{"subw", "64I", "d,s,t", MATCH_SUBW, MASK_SUBW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, + +/* Atomic memory operation instruction subset */ +{"lr.w", "A", "d,0(s)", MATCH_LR_W, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.w", "A", "d,t,0(s)", MATCH_SC_W, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.w", "A", "d,t,0(s)", MATCH_AMOADD_W, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.w", "A", "d,t,0(s)", MATCH_AMOSWAP_W, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.w", "A", "d,t,0(s)", MATCH_AMOAND_W, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.w", "A", "d,t,0(s)", MATCH_AMOOR_W, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.w", "A", "d,t,0(s)", MATCH_AMOXOR_W, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.w", "A", "d,t,0(s)", MATCH_AMOMAX_W, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.w", "A", "d,t,0(s)", MATCH_AMOMAXU_W, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.w", "A", "d,t,0(s)", MATCH_AMOMIN_W, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.w", "A", "d,t,0(s)", MATCH_AMOMINU_W, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.w.aq", "A", "d,0(s)", MATCH_LR_W | MASK_AQ, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.w.aq", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQ, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.w.aq", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQ, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.w.aq", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQ, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.w.aq", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQ, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.w.aq", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQ, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.w.aq", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQ, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.w.aq", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQ, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.w.aq", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQ, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.w.aq", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQ, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.w.aq", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQ, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.w.rl", "A", "d,0(s)", MATCH_LR_W | MASK_RL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.w.rl", "A", "d,t,0(s)", MATCH_SC_W | MASK_RL, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.w.rl", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_RL, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.w.rl", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_RL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.w.rl", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_RL, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.w.rl", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_RL, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.w.rl", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_RL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.w.rl", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_RL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.w.rl", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.w.rl", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.w.rl", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.w.sc", "A", "d,0(s)", MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.w.sc", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.w.sc", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.w.sc", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.w.sc", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.w.sc", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.w.sc", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.w.sc", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.w.sc", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.w.sc", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.w.sc", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.d", "64A", "d,0(s)", MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.d", "64A", "d,t,0(s)", MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.d", "64A", "d,t,0(s)", MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.d", "64A", "d,t,0(s)", MATCH_AMOSWAP_D, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.d", "64A", "d,t,0(s)", MATCH_AMOAND_D, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.d", "64A", "d,t,0(s)", MATCH_AMOOR_D, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.d", "64A", "d,t,0(s)", MATCH_AMOXOR_D, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.d", "64A", "d,t,0(s)", MATCH_AMOMAX_D, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.d", "64A", "d,t,0(s)", MATCH_AMOMAXU_D, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.d", "64A", "d,t,0(s)", MATCH_AMOMIN_D, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.d", "64A", "d,t,0(s)", MATCH_AMOMINU_D, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.d.aq", "64A", "d,0(s)", MATCH_LR_D | MASK_AQ, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.d.aq", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQ, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.d.aq", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQ, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.d.aq", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQ, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.d.aq", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQ, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.d.aq", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQ, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.d.aq", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQ, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQ, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQ, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.d.aq", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQ, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQ, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.d.rl", "64A", "d,0(s)", MATCH_LR_D | MASK_RL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.d.rl", "64A", "d,t,0(s)", MATCH_SC_D | MASK_RL, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.d.rl", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_RL, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.d.rl", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_RL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.d.rl", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_RL, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.d.rl", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_RL, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.d.rl", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_RL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_RL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.d.rl", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"lr.d.sc", "64A", "d,0(s)", MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 }, +{"sc.d.sc", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoadd.d.sc", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoswap.d.sc", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoand.d.sc", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoor.d.sc", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amoxor.d.sc", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomax.d.sc", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomaxu.d.sc", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amomin.d.sc", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"amominu.d.sc", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, + +/* Multiply/Divide instruction subset */ +{"mul", "M", "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"mulh", "M", "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"mulhu", "M", "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"mulhsu", "M", "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"div", "M", "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"divu", "M", "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"rem", "M", "d,s,t", MATCH_REM, MASK_REM, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"remu", "M", "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"mulw", "64M", "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"divw", "64M", "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"divuw", "64M", "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"remw", "64M", "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, +{"remuw", "64M", "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, WR_xd|RD_xs1|RD_xs2 }, + +/* Single-precision floating-point instruction subset */ +{"frsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd }, +{"fssr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 }, +{"fssr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 }, +{"frcsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd }, +{"fscsr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 }, +{"fscsr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 }, +{"frrm", "F", "d", MATCH_FRRM, MASK_FRRM, match_opcode, WR_xd }, +{"fsrm", "F", "s", MATCH_FSRM, MASK_FSRM | MASK_RD, match_opcode, RD_xs1 }, +{"fsrm", "F", "d,s", MATCH_FSRM, MASK_FSRM, match_opcode, WR_xd|RD_xs1 }, +{"frflags", "F", "d", MATCH_FRFLAGS, MASK_FRFLAGS, match_opcode, WR_xd }, +{"fsflags", "F", "s", MATCH_FSFLAGS, MASK_FSFLAGS | MASK_RD, match_opcode, RD_xs1 }, +{"fsflags", "F", "d,s", MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, WR_xd|RD_xs1 }, +{"flw", "F", "D,o(s)", MATCH_FLW, MASK_FLW, match_opcode, WR_fd|RD_xs1 }, +{"flw", "F", "D,A,s", 0, (int) M_FLW, match_never, INSN_MACRO }, +{"fsw", "F", "T,q(s)", MATCH_FSW, MASK_FSW, match_opcode, RD_xs1|RD_fs2 }, +{"fsw", "F", "T,A,s", 0, (int) M_FSW, match_never, INSN_MACRO }, +{"fmv.x.s", "F", "d,S", MATCH_FMV_X_S, MASK_FMV_X_S, match_opcode, WR_xd|RD_fs1 }, +{"fmv.s.x", "F", "D,s", MATCH_FMV_S_X, MASK_FMV_S_X, match_opcode, WR_fd|RD_xs1 }, +{"fmv.s", "F", "D,U", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fneg.s", "F", "D,U", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fabs.s", "F", "D,U", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fsgnj.s", "F", "D,S,T", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjn.s", "F", "D,S,T", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjx.s", "F", "D,S,T", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.s", "F", "D,S,T", MATCH_FADD_S | MASK_RM, MASK_FADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.s", "F", "D,S,T,m", MATCH_FADD_S, MASK_FADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.s", "F", "D,S,T", MATCH_FSUB_S | MASK_RM, MASK_FSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.s", "F", "D,S,T,m", MATCH_FSUB_S, MASK_FSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.s", "F", "D,S,T", MATCH_FMUL_S | MASK_RM, MASK_FMUL_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.s", "F", "D,S,T,m", MATCH_FMUL_S, MASK_FMUL_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.s", "F", "D,S,T", MATCH_FDIV_S | MASK_RM, MASK_FDIV_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.s", "F", "D,S,T,m", MATCH_FDIV_S, MASK_FDIV_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsqrt.s", "F", "D,S", MATCH_FSQRT_S | MASK_RM, MASK_FSQRT_S | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fsqrt.s", "F", "D,S,m", MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, WR_fd|RD_fs1 }, +{"fmin.s", "F", "D,S,T", MATCH_FMIN_S, MASK_FMIN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmax.s", "F", "D,S,T", MATCH_FMAX_S, MASK_FMAX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmadd.s", "F", "D,S,T,R", MATCH_FMADD_S | MASK_RM, MASK_FMADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmadd.s", "F", "D,S,T,R,m", MATCH_FMADD_S, MASK_FMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.s", "F", "D,S,T,R", MATCH_FNMADD_S | MASK_RM, MASK_FNMADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.s", "F", "D,S,T,R,m", MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.s", "F", "D,S,T,R", MATCH_FMSUB_S | MASK_RM, MASK_FMSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.s", "F", "D,S,T,R,m", MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.s", "F", "D,S,T,R", MATCH_FNMSUB_S | MASK_RM, MASK_FNMSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.s", "F", "D,S,T,R,m", MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fcvt.w.s", "F", "d,S", MATCH_FCVT_W_S | MASK_RM, MASK_FCVT_W_S | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.w.s", "F", "d,S,m", MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.s", "F", "d,S", MATCH_FCVT_WU_S | MASK_RM, MASK_FCVT_WU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.s", "F", "d,S,m", MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.s.w", "F", "D,s", MATCH_FCVT_S_W | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.w", "F", "D,s,m", MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.wu", "F", "D,s", MATCH_FCVT_S_WU | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.wu", "F", "D,s,m", MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, WR_fd|RD_xs1 }, +{"fclass.s", "F", "d,S", MATCH_FCLASS_S, MASK_FCLASS_S, match_opcode, WR_xd|RD_fs1 }, +{"feq.s", "F", "d,S,T", MATCH_FEQ_S, MASK_FEQ_S, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"flt.s", "F", "d,S,T", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fle.s", "F", "d,S,T", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fgt.s", "F", "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fge.s", "F", "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fcvt.l.s", "64F", "d,S", MATCH_FCVT_L_S | MASK_RM, MASK_FCVT_L_S | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.l.s", "64F", "d,S,m", MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.s", "64F", "d,S", MATCH_FCVT_LU_S | MASK_RM, MASK_FCVT_LU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.s", "64F", "d,S,m", MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.s.l", "64F", "D,s", MATCH_FCVT_S_L | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.l", "64F", "D,s,m", MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.lu", "64F", "D,s", MATCH_FCVT_S_LU | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.s.lu", "64F", "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, WR_fd|RD_xs1 }, + +/* Double-precision floating-point instruction subset */ +{"fld", "D", "D,o(s)", MATCH_FLD, MASK_FLD, match_opcode, WR_fd|RD_xs1 }, +{"fld", "D", "D,A,s", 0, (int) M_FLD, match_never, INSN_MACRO }, +{"fsd", "D", "T,q(s)", MATCH_FSD, MASK_FSD, match_opcode, RD_xs1|RD_fs2 }, +{"fsd", "D", "T,A,s", 0, (int) M_FSD, match_never, INSN_MACRO }, +{"fmv.d", "D", "D,U", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fneg.d", "D", "D,U", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fabs.d", "D", "D,U", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 }, +{"fsgnj.d", "D", "D,S,T", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjn.d", "D", "D,S,T", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjx.d", "D", "D,S,T", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.d", "D", "D,S,T", MATCH_FADD_D | MASK_RM, MASK_FADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.d", "D", "D,S,T,m", MATCH_FADD_D, MASK_FADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.d", "D", "D,S,T", MATCH_FSUB_D | MASK_RM, MASK_FSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.d", "D", "D,S,T,m", MATCH_FSUB_D, MASK_FSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.d", "D", "D,S,T", MATCH_FMUL_D | MASK_RM, MASK_FMUL_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.d", "D", "D,S,T,m", MATCH_FMUL_D, MASK_FMUL_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.d", "D", "D,S,T", MATCH_FDIV_D | MASK_RM, MASK_FDIV_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.d", "D", "D,S,T,m", MATCH_FDIV_D, MASK_FDIV_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsqrt.d", "D", "D,S", MATCH_FSQRT_D | MASK_RM, MASK_FSQRT_D | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fsqrt.d", "D", "D,S,m", MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, WR_fd|RD_fs1 }, +{"fmin.d", "D", "D,S,T", MATCH_FMIN_D, MASK_FMIN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmax.d", "D", "D,S,T", MATCH_FMAX_D, MASK_FMAX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmadd.d", "D", "D,S,T,R", MATCH_FMADD_D | MASK_RM, MASK_FMADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmadd.d", "D", "D,S,T,R,m", MATCH_FMADD_D, MASK_FMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.d", "D", "D,S,T,R", MATCH_FNMADD_D | MASK_RM, MASK_FNMADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.d", "D", "D,S,T,R,m", MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.d", "D", "D,S,T,R", MATCH_FMSUB_D | MASK_RM, MASK_FMSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.d", "D", "D,S,T,R,m", MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.d", "D", "D,S,T,R", MATCH_FNMSUB_D | MASK_RM, MASK_FNMSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.d", "D", "D,S,T,R,m", MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fcvt.w.d", "D", "d,S", MATCH_FCVT_W_D | MASK_RM, MASK_FCVT_W_D | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.w.d", "D", "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.d", "D", "d,S", MATCH_FCVT_WU_D | MASK_RM, MASK_FCVT_WU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.d", "D", "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.d.w", "D", "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.d.wu", "D", "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.d.s", "D", "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.s.d", "D", "D,S", MATCH_FCVT_S_D | MASK_RM, MASK_FCVT_S_D | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.s.d", "D", "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, WR_fd|RD_fs1 }, +{"fclass.d", "D", "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, WR_xd|RD_fs1 }, +{"feq.d", "D", "d,S,T", MATCH_FEQ_D, MASK_FEQ_D, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"flt.d", "D", "d,S,T", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fle.d", "D", "d,S,T", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fgt.d", "D", "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fge.d", "D", "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fmv.x.d", "64D", "d,S", MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, WR_xd|RD_fs1 }, +{"fmv.d.x", "64D", "D,s", MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.l.d", "64D", "d,S", MATCH_FCVT_L_D | MASK_RM, MASK_FCVT_L_D | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.l.d", "64D", "d,S,m", MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.d", "64D", "d,S", MATCH_FCVT_LU_D | MASK_RM, MASK_FCVT_LU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.d", "64D", "d,S,m", MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.d.l", "64D", "D,s", MATCH_FCVT_D_L | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.d.l", "64D", "D,s,m", MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.d.lu", "64D", "D,s", MATCH_FCVT_D_LU | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.d.lu", "64D", "D,s,m", MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, WR_fd|RD_xs1 }, + +/* Supervisor instructions */ +{"csrr", "I", "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, WR_xd }, +{"csrwi", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrw", "I", "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, RD_xs1 }, +{"csrw", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrsi", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrs", "I", "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrs", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrci", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrc", "I", "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrc", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 }, +{"csrrw", "I", "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, WR_xd|RD_xs1 }, +{"csrrw", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 }, +{"csrrs", "I", "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, WR_xd|RD_xs1 }, +{"csrrs", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 }, +{"csrrc", "I", "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, WR_xd|RD_xs1 }, +{"csrrc", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 }, +{"csrrwi", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 }, +{"csrrsi", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 }, +{"csrrci", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 }, +{"sret", "I", "", MATCH_SRET, MASK_SRET, match_opcode, 0 }, +{"eret", "I", "", MATCH_SRET, MASK_SRET, match_opcode, 0 }, +{"mrts", "I", "", MATCH_MRTS, MASK_MRTS, match_opcode, 0 }, +{"sfence.vm", "I", "", MATCH_SFENCE_VM | MASK_RS1, MASK_SFENCE_VM | MASK_RS1, match_opcode, 0 }, +{"sfence.vm", "I", "s", MATCH_SFENCE_VM, MASK_SFENCE_VM, match_opcode, RD_xs1 }, + +/* Half-precision floating-point instruction subset */ +{"flh", "Xhwacha", "D,o(s)", MATCH_FLH, MASK_FLH, match_opcode, WR_fd|RD_xs1 }, +{"fsh", "Xhwacha", "T,q(s)", MATCH_FSH, MASK_FSH, match_opcode, RD_xs1|RD_fs2 }, +{"fsgnj.h", "Xhwacha", "D,S,T", MATCH_FSGNJ_H, MASK_FSGNJ_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjn.h", "Xhwacha", "D,S,T", MATCH_FSGNJN_H, MASK_FSGNJN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsgnjx.h", "Xhwacha", "D,S,T", MATCH_FSGNJX_H, MASK_FSGNJX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.h", "Xhwacha", "D,S,T", MATCH_FADD_H | MASK_RM, MASK_FADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fadd.h", "Xhwacha", "D,S,T,m", MATCH_FADD_H, MASK_FADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.h", "Xhwacha", "D,S,T", MATCH_FSUB_H | MASK_RM, MASK_FSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsub.h", "Xhwacha", "D,S,T,m", MATCH_FSUB_H, MASK_FSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.h", "Xhwacha", "D,S,T", MATCH_FMUL_H | MASK_RM, MASK_FMUL_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmul.h", "Xhwacha", "D,S,T,m", MATCH_FMUL_H, MASK_FMUL_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.h", "Xhwacha", "D,S,T", MATCH_FDIV_H | MASK_RM, MASK_FDIV_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fdiv.h", "Xhwacha", "D,S,T,m", MATCH_FDIV_H, MASK_FDIV_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fsqrt.h", "Xhwacha", "D,S", MATCH_FSQRT_H | MASK_RM, MASK_FSQRT_H | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fsqrt.h", "Xhwacha", "D,S,m", MATCH_FSQRT_H, MASK_FSQRT_H, match_opcode, WR_fd|RD_fs1 }, +{"fmin.h", "Xhwacha", "D,S,T", MATCH_FMIN_H, MASK_FMIN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmax.h", "Xhwacha", "D,S,T", MATCH_FMAX_H, MASK_FMAX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 }, +{"fmadd.h", "Xhwacha", "D,S,T,R", MATCH_FMADD_H | MASK_RM, MASK_FMADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FMADD_H, MASK_FMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.h", "Xhwacha", "D,S,T,R", MATCH_FNMADD_H | MASK_RM, MASK_FNMADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMADD_H, MASK_FNMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.h", "Xhwacha", "D,S,T,R", MATCH_FMSUB_H | MASK_RM, MASK_FMSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FMSUB_H, MASK_FMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.h", "Xhwacha", "D,S,T,R", MATCH_FNMSUB_H | MASK_RM, MASK_FNMSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fnmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMSUB_H, MASK_FNMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 }, +{"fcvt.s.h", "Xhwacha", "D,S", MATCH_FCVT_S_H, MASK_FCVT_S_H | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.h.s", "Xhwacha", "D,S", MATCH_FCVT_H_S | MASK_RM, MASK_FCVT_H_S | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.h.s", "Xhwacha", "D,S,m", MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.d.h", "Xhwacha", "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.h.d", "Xhwacha", "D,S", MATCH_FCVT_H_D | MASK_RM, MASK_FCVT_H_D | MASK_RM, match_opcode, WR_fd|RD_fs1 }, +{"fcvt.h.d", "Xhwacha", "D,S,m", MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, WR_fd|RD_fs1 }, +{"feq.h", "Xhwacha", "d,S,T", MATCH_FEQ_H, MASK_FEQ_H, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"flt.h", "Xhwacha", "d,S,T", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fle.h", "Xhwacha", "d,S,T", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fgt.h", "Xhwacha", "d,T,S", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fge.h", "Xhwacha", "d,T,S", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 }, +{"fmv.x.h", "Xhwacha", "d,S", MATCH_FMV_X_H, MASK_FMV_X_H, match_opcode, WR_xd|RD_fs1 }, +{"fmv.h.x", "Xhwacha", "D,s", MATCH_FMV_H_X, MASK_FMV_H_X, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.w.h", "Xhwacha", "d,S", MATCH_FCVT_W_H | MASK_RM, MASK_FCVT_W_H | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.w.h", "Xhwacha", "d,S,m", MATCH_FCVT_W_H, MASK_FCVT_W_H, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.h", "Xhwacha", "d,S", MATCH_FCVT_WU_H | MASK_RM, MASK_FCVT_WU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.wu.h", "Xhwacha", "d,S,m", MATCH_FCVT_WU_H, MASK_FCVT_WU_H, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.h.w", "Xhwacha", "D,s", MATCH_FCVT_H_W, MASK_FCVT_H_W | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.h.wu", "Xhwacha", "D,s", MATCH_FCVT_H_WU, MASK_FCVT_H_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.l.h", "Xhwacha", "d,S", MATCH_FCVT_L_H | MASK_RM, MASK_FCVT_L_H | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.l.h", "Xhwacha", "d,S,m", MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.h", "Xhwacha", "d,S", MATCH_FCVT_LU_H | MASK_RM, MASK_FCVT_LU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.lu.h", "Xhwacha", "d,S,m", MATCH_FCVT_LU_H, MASK_FCVT_LU_H, match_opcode, WR_xd|RD_fs1 }, +{"fcvt.h.l", "Xhwacha", "D,s", MATCH_FCVT_H_L | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.h.l", "Xhwacha", "D,s,m", MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.h.lu", "Xhwacha", "D,s", MATCH_FCVT_H_LU | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 }, +{"fcvt.h.lu", "Xhwacha", "D,s,m", MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, WR_fd|RD_xs1 }, + +/* Rocket Custom Coprocessor extension */ +{"custom0", "Xcustom", "d,s,t,^j", MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2, match_opcode, 0}, +{"custom0", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1, match_opcode, 0}, +{"custom0", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD, match_opcode, 0}, +{"custom0", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2, match_opcode, 0}, +{"custom0", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1, match_opcode, 0}, +{"custom0", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM0, MASK_CUSTOM0, match_opcode, 0}, +{"custom1", "Xcustom", "d,s,t,^j", MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2, match_opcode, 0}, +{"custom1", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1, match_opcode, 0}, +{"custom1", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD, match_opcode, 0}, +{"custom1", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2, match_opcode, 0}, +{"custom1", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1, match_opcode, 0}, +{"custom1", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM1, MASK_CUSTOM1, match_opcode, 0}, +{"custom2", "Xcustom", "d,s,t,^j", MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2, match_opcode, 0}, +{"custom2", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1, match_opcode, 0}, +{"custom2", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD, match_opcode, 0}, +{"custom2", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2, match_opcode, 0}, +{"custom2", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1, match_opcode, 0}, +{"custom2", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM2, MASK_CUSTOM2, match_opcode, 0}, +{"custom3", "Xcustom", "d,s,t,^j", MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2, match_opcode, 0}, +{"custom3", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1, match_opcode, 0}, +{"custom3", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD, match_opcode, 0}, +{"custom3", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2, match_opcode, 0}, +{"custom3", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1, match_opcode, 0}, +{"custom3", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM3, MASK_CUSTOM3, match_opcode, 0}, + +/* Xhwacha extension */ +{"stop", "Xhwacha", "", MATCH_STOP, MASK_STOP, match_opcode, 0}, +{"utidx", "Xhwacha", "d", MATCH_UTIDX, MASK_UTIDX, match_opcode, WR_xd}, +{"movz", "Xhwacha", "d,s,t", MATCH_MOVZ, MASK_MOVZ, match_opcode, WR_xd|RD_xs1|RD_xs2}, +{"movn", "Xhwacha", "d,s,t", MATCH_MOVN, MASK_MOVN, match_opcode, WR_xd|RD_xs1|RD_xs2}, +{"fmovz", "Xhwacha", "D,s,T", MATCH_FMOVZ, MASK_FMOVZ, match_opcode, WR_fd|RD_xs1|RD_fs2}, +{"fmovn", "Xhwacha", "D,s,T", MATCH_FMOVN, MASK_FMOVN, match_opcode, WR_fd|RD_xs1|RD_fs2}, + +/* unit stride */ +/* xloads */ +{"vld", "Xhwacha", "#d,s", MATCH_VLD, MASK_VLD, match_opcode, 0}, +{"vlw", "Xhwacha", "#d,s", MATCH_VLW, MASK_VLW, match_opcode, 0}, +{"vlwu", "Xhwacha", "#d,s", MATCH_VLWU, MASK_VLWU, match_opcode, 0}, +{"vlh", "Xhwacha", "#d,s", MATCH_VLH, MASK_VLH, match_opcode, 0}, +{"vlhu", "Xhwacha", "#d,s", MATCH_VLHU, MASK_VLHU, match_opcode, 0}, +{"vlb", "Xhwacha", "#d,s", MATCH_VLB, MASK_VLB, match_opcode, 0}, +{"vlbu", "Xhwacha", "#d,s", MATCH_VLBU, MASK_VLBU, match_opcode, 0}, +/* floads */ +{"vfld", "Xhwacha", "#D,s", MATCH_VFLD, MASK_VFLD, match_opcode, 0}, +{"vflw", "Xhwacha", "#D,s", MATCH_VFLW, MASK_VFLW, match_opcode, 0}, + +/* stride */ +/* xloads */ +{"vlstd", "Xhwacha", "#d,s,t", MATCH_VLSTD, MASK_VLSTD, match_opcode, 0}, +{"vlstw", "Xhwacha", "#d,s,t", MATCH_VLSTW, MASK_VLSTW, match_opcode, 0}, +{"vlstwu", "Xhwacha", "#d,s,t", MATCH_VLSTWU, MASK_VLSTWU, match_opcode, 0}, +{"vlsth", "Xhwacha", "#d,s,t", MATCH_VLSTH, MASK_VLSTH, match_opcode, 0}, +{"vlsthu", "Xhwacha", "#d,s,t", MATCH_VLSTHU, MASK_VLSTHU, match_opcode, 0}, +{"vlstb", "Xhwacha", "#d,s,t", MATCH_VLSTB, MASK_VLSTB, match_opcode, 0}, +{"vlstbu", "Xhwacha", "#d,s,t", MATCH_VLSTBU, MASK_VLSTBU, match_opcode, 0}, +/* floads */ +{"vflstd", "Xhwacha", "#D,s,t", MATCH_VFLSTD, MASK_VFLSTD, match_opcode, 0}, +{"vflstw", "Xhwacha", "#D,s,t", MATCH_VFLSTW, MASK_VFLSTW, match_opcode, 0}, + +/* segment */ +/* xloads */ +{"vlsegd", "Xhwacha", "#d,s,#n", MATCH_VLSEGD, MASK_VLSEGD, match_opcode, 0}, +{"vlsegw", "Xhwacha", "#d,s,#n", MATCH_VLSEGW, MASK_VLSEGW, match_opcode, 0}, +{"vlsegwu", "Xhwacha", "#d,s,#n", MATCH_VLSEGWU, MASK_VLSEGWU, match_opcode, 0}, +{"vlsegh", "Xhwacha", "#d,s,#n", MATCH_VLSEGH, MASK_VLSEGH, match_opcode, 0}, +{"vlseghu", "Xhwacha", "#d,s,#n", MATCH_VLSEGHU, MASK_VLSEGHU, match_opcode, 0}, +{"vlsegb", "Xhwacha", "#d,s,#n", MATCH_VLSEGB, MASK_VLSEGB, match_opcode, 0}, +{"vlsegbu", "Xhwacha", "#d,s,#n", MATCH_VLSEGBU, MASK_VLSEGBU, match_opcode, 0}, +/* floads */ +{"vflsegd", "Xhwacha", "#D,s,#n", MATCH_VFLSEGD, MASK_VFLSEGD, match_opcode, 0}, +{"vflsegw", "Xhwacha", "#D,s,#n", MATCH_VFLSEGW, MASK_VFLSEGW, match_opcode, 0}, + +/* stride segment */ +/* xloads */ +{"vlsegstd", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTD, MASK_VLSEGSTD, match_opcode, 0}, +{"vlsegstw", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTW, MASK_VLSEGSTW, match_opcode, 0}, +{"vlsegstwu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTWU, MASK_VLSEGSTWU, match_opcode, 0}, +{"vlsegsth", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTH, MASK_VLSEGSTH, match_opcode, 0}, +{"vlsegsthu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTHU, MASK_VLSEGSTHU, match_opcode, 0}, +{"vlsegstb", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTB, MASK_VLSEGSTB, match_opcode, 0}, +{"vlsegstbu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTBU, MASK_VLSEGSTBU, match_opcode, 0}, +/* floads */ +{"vflsegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTD, MASK_VFLSEGSTD, match_opcode, 0}, +{"vflsegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTW, MASK_VFLSEGSTW, match_opcode, 0}, + +/* unit stride */ +/* xstores */ +{"vsd", "Xhwacha", "#d,s", MATCH_VSD, MASK_VSD, match_opcode, 0}, +{"vsw", "Xhwacha", "#d,s", MATCH_VSW, MASK_VSW, match_opcode, 0}, +{"vsh", "Xhwacha", "#d,s", MATCH_VSH, MASK_VSH, match_opcode, 0}, +{"vsb", "Xhwacha", "#d,s", MATCH_VSB, MASK_VSB, match_opcode, 0}, +/* fstores */ +{"vfsd", "Xhwacha", "#D,s", MATCH_VFSD, MASK_VFSD, match_opcode, 0}, +{"vfsw", "Xhwacha", "#D,s", MATCH_VFSW, MASK_VFSW, match_opcode, 0}, + +/* stride */ +/* xstores */ +{"vsstd", "Xhwacha", "#d,s,t", MATCH_VSSTD, MASK_VSSTD, match_opcode, 0}, +{"vsstw", "Xhwacha", "#d,s,t", MATCH_VSSTW, MASK_VSSTW, match_opcode, 0}, +{"vssth", "Xhwacha", "#d,s,t", MATCH_VSSTH, MASK_VSSTH, match_opcode, 0}, +{"vsstb", "Xhwacha", "#d,s,t", MATCH_VSSTB, MASK_VSSTB, match_opcode, 0}, +/* fstores */ +{"vfsstd", "Xhwacha", "#D,s,t", MATCH_VFSSTD, MASK_VFSSTD, match_opcode, 0}, +{"vfsstw", "Xhwacha", "#D,s,t", MATCH_VFSSTW, MASK_VFSSTW, match_opcode, 0}, + +/* segment */ +/* xstores */ +{"vssegd", "Xhwacha", "#d,s,#n", MATCH_VSSEGD, MASK_VSSEGD, match_opcode, 0}, +{"vssegw", "Xhwacha", "#d,s,#n", MATCH_VSSEGW, MASK_VSSEGW, match_opcode, 0}, +{"vssegh", "Xhwacha", "#d,s,#n", MATCH_VSSEGH, MASK_VSSEGH, match_opcode, 0}, +{"vssegb", "Xhwacha", "#d,s,#n", MATCH_VSSEGB, MASK_VSSEGB, match_opcode, 0}, +/* fstores */ +{"vfssegd", "Xhwacha", "#D,s,#n", MATCH_VFSSEGD, MASK_VFSSEGD, match_opcode, 0}, +{"vfssegw", "Xhwacha", "#D,s,#n", MATCH_VFSSEGW, MASK_VFSSEGW, match_opcode, 0}, + +/* stride segment */ +/* xsegstores */ +{"vssegstd", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTD, MASK_VSSEGSTD, match_opcode, 0}, +{"vssegstw", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTW, MASK_VSSEGSTW, match_opcode, 0}, +{"vssegsth", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTH, MASK_VSSEGSTH, match_opcode, 0}, +{"vssegstb", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTB, MASK_VSSEGSTB, match_opcode, 0}, +/* fsegstores */ +{"vfssegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTD, MASK_VFSSEGSTD, match_opcode, 0}, +{"vfssegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTW, MASK_VFSSEGSTW, match_opcode, 0}, + +{"vsetcfg", "Xhwacha", "s", MATCH_VSETCFG, MASK_VSETCFG | MASK_IMM, match_opcode, 0}, +{"vsetcfg", "Xhwacha", "#g,#f", MATCH_VSETCFG, MASK_VSETCFG | MASK_RS1, match_opcode, 0}, +{"vsetcfg", "Xhwacha", "s,#g,#f", MATCH_VSETCFG, MASK_VSETCFG, match_opcode, 0}, +{"vsetucfg", "Xhwacha", "d,u", MATCH_LUI, MASK_LUI, match_opcode, INSN_ALIAS | WR_xd}, +{"vsetvl", "Xhwacha", "d,s", MATCH_VSETVL, MASK_VSETVL, match_opcode, 0}, +{"vgetcfg", "Xhwacha", "d", MATCH_VGETCFG, MASK_VGETCFG, match_opcode, 0}, +{"vgetvl", "Xhwacha", "d", MATCH_VGETVL, MASK_VGETVL, match_opcode, 0}, + +{"vmvv", "Xhwacha", "#d,#s", MATCH_VMVV, MASK_VMVV, match_opcode, 0}, +{"vmsv", "Xhwacha", "#d,s", MATCH_VMSV, MASK_VMSV, match_opcode, 0}, +{"vfmvv", "Xhwacha", "#D,#S", MATCH_VFMVV, MASK_VFMVV, match_opcode, 0}, +{"vfmsv.d", "Xhwacha", "#D,s", MATCH_VFMSV_D, MASK_VFMSV_D, match_opcode, 0}, +{"vfmsv.s", "Xhwacha", "#D,s", MATCH_VFMSV_S, MASK_VFMSV_S, match_opcode, 0}, + +{"vf", "Xhwacha", "q(s)", MATCH_VF, MASK_VF, match_opcode, 0}, +{"vf", "Xhwacha", "A,s", 0, (int) M_VF, match_never, INSN_MACRO }, + +{"vxcptcause", "Xhwacha", "d", MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE, match_opcode, 0}, +{"vxcptaux", "Xhwacha", "d", MATCH_VXCPTAUX, MASK_VXCPTAUX, match_opcode, 0}, + +{"vxcptsave", "Xhwacha", "s", MATCH_VXCPTSAVE, MASK_VXCPTSAVE, match_opcode, 0}, +{"vxcptrestore", "Xhwacha", "s", MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE, match_opcode, 0}, +{"vxcptkill", "Xhwacha", "", MATCH_VXCPTKILL, MASK_VXCPTKILL, match_opcode, 0}, + +{"vxcptevac", "Xhwacha", "s", MATCH_VXCPTEVAC, MASK_VXCPTEVAC, match_opcode, 0}, +{"vxcpthold", "Xhwacha", "s", MATCH_VXCPTHOLD, MASK_VXCPTHOLD, match_opcode, 0}, +{"venqcmd", "Xhwacha", "s,t", MATCH_VENQCMD, MASK_VENQCMD, match_opcode, 0}, +{"venqimm1", "Xhwacha", "s,t", MATCH_VENQIMM1, MASK_VENQIMM1, match_opcode, 0}, +{"venqimm2", "Xhwacha", "s,t", MATCH_VENQIMM2, MASK_VENQIMM2, match_opcode, 0}, +{"venqcnt", "Xhwacha", "s,t", MATCH_VENQCNT, MASK_VENQCNT, match_opcode, 0}, +}; + +#define RISCV_NUM_OPCODES \ + ((sizeof riscv_builtin_opcodes) / (sizeof (riscv_builtin_opcodes[0]))) +const int bfd_riscv_num_builtin_opcodes = RISCV_NUM_OPCODES; + +/* const removed from the following to allow for dynamic extensions to the + * built-in instruction set. */ +struct riscv_opcode *riscv_opcodes = + (struct riscv_opcode *) riscv_builtin_opcodes; +int bfd_riscv_num_opcodes = RISCV_NUM_OPCODES; +#undef RISCV_NUM_OPCODES