diff options
Diffstat (limited to 'meta-xilinx/meta-microblaze/recipes-devtools/binutils/binutils/0014-intial-commit-of-MB-64-bit.patch')
-rw-r--r-- | meta-xilinx/meta-microblaze/recipes-devtools/binutils/binutils/0014-intial-commit-of-MB-64-bit.patch | 4760 |
1 files changed, 0 insertions, 4760 deletions
diff --git a/meta-xilinx/meta-microblaze/recipes-devtools/binutils/binutils/0014-intial-commit-of-MB-64-bit.patch b/meta-xilinx/meta-microblaze/recipes-devtools/binutils/binutils/0014-intial-commit-of-MB-64-bit.patch deleted file mode 100644 index f0037e1f5..000000000 --- a/meta-xilinx/meta-microblaze/recipes-devtools/binutils/binutils/0014-intial-commit-of-MB-64-bit.patch +++ /dev/null @@ -1,4760 +0,0 @@ -From d25d934f076297615cb0287488449fb32b9c46e8 Mon Sep 17 00:00:00 2001 -From: Nagaraju Mekala <nmekala@xilix.com> -Date: Sun, 30 Sep 2018 16:28:28 +0530 -Subject: [PATCH 14/52] intial commit of MB 64-bit - -Conflicts: - bfd/configure - bfd/configure.ac - bfd/cpu-microblaze.c - ld/Makefile.am - ld/Makefile.in - opcodes/microblaze-dis.c ---- - bfd/Makefile.am | 2 + - bfd/Makefile.in | 3 + - bfd/config.bfd | 4 + - bfd/configure | 2 + - bfd/configure.ac | 2 + - bfd/cpu-microblaze.c | 53 +- - bfd/elf64-microblaze.c | 3610 ++++++++++++++++++++++++++++ - bfd/targets.c | 6 + - gas/config/tc-microblaze.c | 274 ++- - gas/config/tc-microblaze.h | 4 +- - include/elf/common.h | 1 + - ld/Makefile.am | 4 + - ld/Makefile.in | 6 + - ld/configure.tgt | 3 + - ld/emulparams/elf64microblaze.sh | 23 + - ld/emulparams/elf64microblazeel.sh | 23 + - opcodes/microblaze-dis.c | 35 +- - opcodes/microblaze-opc.h | 162 +- - opcodes/microblaze-opcm.h | 20 +- - 19 files changed, 4197 insertions(+), 40 deletions(-) - create mode 100644 bfd/elf64-microblaze.c - create mode 100644 ld/emulparams/elf64microblaze.sh - create mode 100644 ld/emulparams/elf64microblazeel.sh - -diff --git a/bfd/Makefile.am b/bfd/Makefile.am -index c88c448000..d86f1c5697 100644 ---- a/bfd/Makefile.am -+++ b/bfd/Makefile.am -@@ -562,6 +562,7 @@ BFD64_BACKENDS = \ - elf64-riscv.lo \ - elfxx-riscv.lo \ - elf64-s390.lo \ -+ elf64-microblaze.lo \ - elf64-sparc.lo \ - elf64-tilegx.lo \ - elf64-x86-64.lo \ -@@ -596,6 +597,7 @@ BFD64_BACKENDS_CFILES = \ - elf64-nfp.c \ - elf64-ppc.c \ - elf64-s390.c \ -+ elf64-microblaze.c \ - elf64-sparc.c \ - elf64-tilegx.c \ - elf64-x86-64.c \ -diff --git a/bfd/Makefile.in b/bfd/Makefile.in -index d0d14c6ab3..a54abeca48 100644 ---- a/bfd/Makefile.in -+++ b/bfd/Makefile.in -@@ -988,6 +988,7 @@ BFD64_BACKENDS = \ - elf64-riscv.lo \ - elfxx-riscv.lo \ - elf64-s390.lo \ -+ elf64-microblaze.lo \ - elf64-sparc.lo \ - elf64-tilegx.lo \ - elf64-x86-64.lo \ -@@ -1022,6 +1023,7 @@ BFD64_BACKENDS_CFILES = \ - elf64-nfp.c \ - elf64-ppc.c \ - elf64-s390.c \ -+ elf64-microblaze.c \ - elf64-sparc.c \ - elf64-tilegx.c \ - elf64-x86-64.c \ -@@ -1501,6 +1503,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-riscv.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-microblaze.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sparc.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-tilegx.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-x86-64.Plo@am__quote@ -diff --git a/bfd/config.bfd b/bfd/config.bfd -index 14523caf0c..437c03bb9d 100644 ---- a/bfd/config.bfd -+++ b/bfd/config.bfd -@@ -825,11 +825,15 @@ case "${targ}" in - microblazeel*-*) - targ_defvec=microblaze_elf32_le_vec - targ_selvecs=microblaze_elf32_vec -+ targ64_selvecs=microblaze_elf64_vec -+ targ64_selvecs=microblaze_elf64_le_vec - ;; - - microblaze*-*) - targ_defvec=microblaze_elf32_vec - targ_selvecs=microblaze_elf32_le_vec -+ targ64_selvecs=microblaze_elf64_vec -+ targ64_selvecs=microblaze_elf64_le_vec - ;; - - #ifdef BFD64 -diff --git a/bfd/configure b/bfd/configure -index 0340ed541b..ff5ae4706c 100755 ---- a/bfd/configure -+++ b/bfd/configure -@@ -14903,6 +14903,8 @@ do - s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;; - score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;; - score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;; -+ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;; -+ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;; - sh_coff_vec) tb="$tb coff-sh.lo $coff" ;; - sh_coff_le_vec) tb="$tb coff-sh.lo $coff" ;; - sh_coff_small_vec) tb="$tb coff-sh.lo $coff" ;; -diff --git a/bfd/configure.ac b/bfd/configure.ac -index 8e86f8399c..408092d3be 100644 ---- a/bfd/configure.ac -+++ b/bfd/configure.ac -@@ -639,6 +639,8 @@ do - s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;; - score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;; - score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;; -+ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;; -+ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;; - sh_coff_vec) tb="$tb coff-sh.lo $coff" ;; - sh_coff_le_vec) tb="$tb coff-sh.lo $coff" ;; - sh_coff_small_vec) tb="$tb coff-sh.lo $coff" ;; -diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c -index 05a3f767e2..194920b20b 100644 ---- a/bfd/cpu-microblaze.c -+++ b/bfd/cpu-microblaze.c -@@ -23,7 +23,24 @@ - #include "bfd.h" - #include "libbfd.h" - --const bfd_arch_info_type bfd_microblaze_arch = -+const bfd_arch_info_type bfd_microblaze_arch[] = -+{ -+#if BFD_DEFAULT_TARGET_SIZE == 64 -+{ -+ 64, /* 32 bits in a word. */ -+ 64, /* 32 bits in an address. */ -+ 8, /* 8 bits in a byte. */ -+ bfd_arch_microblaze, /* Architecture. */ -+ 0, /* Machine number - 0 for now. */ -+ "microblaze", /* Architecture name. */ -+ "MicroBlaze", /* Printable name. */ -+ 3, /* Section align power. */ -+ FALSE, /* Is this the default architecture ? */ -+ bfd_default_compatible, /* Architecture comparison function. */ -+ bfd_default_scan, /* String to architecture conversion. */ -+ bfd_arch_default_fill, /* Default fill. */ -+ &bfd_microblaze_arch[1] /* Next in list. */ -+}, - { - 32, /* Bits in a word. */ - 32, /* Bits in an address. */ -@@ -39,4 +56,38 @@ const bfd_arch_info_type bfd_microblaze_arch = - bfd_arch_default_fill, /* Default fill. */ - NULL, /* Next in list. */ - 0 /* Maximum offset of a reloc from the start of an insn. */ -+} -+#else -+{ -+ 32, /* 32 bits in a word. */ -+ 32, /* 32 bits in an address. */ -+ 8, /* 8 bits in a byte. */ -+ bfd_arch_microblaze, /* Architecture. */ -+ 0, /* Machine number - 0 for now. */ -+ "microblaze", /* Architecture name. */ -+ "MicroBlaze", /* Printable name. */ -+ 3, /* Section align power. */ -+ TRUE, /* Is this the default architecture ? */ -+ bfd_default_compatible, /* Architecture comparison function. */ -+ bfd_default_scan, /* String to architecture conversion. */ -+ bfd_arch_default_fill, /* Default fill. */ -+ &bfd_microblaze_arch[1] /* Next in list. */ -+}, -+{ -+ 64, /* 32 bits in a word. */ -+ 64, /* 32 bits in an address. */ -+ 8, /* 8 bits in a byte. */ -+ bfd_arch_microblaze, /* Architecture. */ -+ 0, /* Machine number - 0 for now. */ -+ "microblaze", /* Architecture name. */ -+ "MicroBlaze", /* Printable name. */ -+ 3, /* Section align power. */ -+ FALSE, /* Is this the default architecture ? */ -+ bfd_default_compatible, /* Architecture comparison function. */ -+ bfd_default_scan, /* String to architecture conversion. */ -+ bfd_arch_default_fill, /* Default fill. */ -+ NULL, /* Next in list. */ -+ 0 /* Maximum offset of a reloc from the start of an insn. */ -+} -+#endif - }; -diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c -new file mode 100644 -index 0000000000..a357388115 ---- /dev/null -+++ b/bfd/elf64-microblaze.c -@@ -0,0 +1,3610 @@ -+/* Xilinx MicroBlaze-specific support for 32-bit ELF -+ -+ Copyright (C) 2009-2016 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. */ -+ -+ -+int dbg1 = 0; -+ -+#include "sysdep.h" -+#include "bfd.h" -+#include "bfdlink.h" -+#include "libbfd.h" -+#include "elf-bfd.h" -+#include "elf/microblaze.h" -+#include <assert.h> -+ -+#define USE_RELA /* Only USE_REL is actually significant, but this is -+ here are a reminder... */ -+#define INST_WORD_SIZE 4 -+ -+static int ro_small_data_pointer = 0; -+static int rw_small_data_pointer = 0; -+ -+static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max]; -+ -+static reloc_howto_type microblaze_elf_howto_raw[] = -+{ -+ /* This reloc does nothing. */ -+ HOWTO (R_MICROBLAZE_NONE, /* Type. */ -+ 0, /* Rightshift. */ -+ 3, /* Size (0 = byte, 1 = short, 2 = long). */ -+ 0, /* Bitsize. */ -+ FALSE, /* PC_relative. */ -+ 0, /* Bitpos. */ -+ complain_overflow_dont, /* Complain on overflow. */ -+ NULL, /* Special Function. */ -+ "R_MICROBLAZE_NONE", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* A standard 32 bit relocation. */ -+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_32", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0xffffffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* A standard PCREL 32 bit relocation. */ -+ HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */ -+ 0, /* Rightshift. */ -+ 2, /* Size (0 = byte, 1 = short, 2 = long). */ -+ 32, /* Bitsize. */ -+ TRUE, /* PC_relative. */ -+ 0, /* Bitpos. */ -+ complain_overflow_bitfield, /* Complain on overflow. */ -+ bfd_elf_generic_reloc,/* Special Function. */ -+ "R_MICROBLAZE_32_PCREL", /* Name. */ -+ TRUE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0xffffffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* A 64 bit PCREL relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */ -+ 0, /* Rightshift. */ -+ 4, /* 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_MICROBLAZE_64_PCREL", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* The low half of a PCREL 32 bit relocation. */ -+ HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */ -+ 0, /* Rightshift. */ -+ 2, /* 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_MICROBLAZE_32_PCREL_LO", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* A 64 bit relocation. Table entry not really used. */ -+ HOWTO (R_MICROBLAZE_64, /* 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_MICROBLAZE_64", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* The low half of a 32 bit relocation. */ -+ HOWTO (R_MICROBLAZE_32_LO, /* 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_MICROBLAZE_32_LO", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* Read-only small data section relocation. */ -+ HOWTO (R_MICROBLAZE_SRO32, /* Type. */ -+ 0, /* Rightshift. */ -+ 2, /* 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_MICROBLAZE_SRO32", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* Read-write small data area relocation. */ -+ HOWTO (R_MICROBLAZE_SRW32, /* Type. */ -+ 0, /* Rightshift. */ -+ 2, /* 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_MICROBLAZE_SRW32", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */ -+ 0, /* Rightshift. */ -+ 2, /* Size (0 = byte, 1 = short, 2 = long). */ -+ 32, /* Bitsize. */ -+ TRUE, /* PC_relative. */ -+ 0, /* Bitpos. */ -+ complain_overflow_bitfield, /* Complain on overflow. */ -+ NULL, /* Special Function. */ -+ "R_MICROBLAZE_32_NONE",/* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* This reloc does nothing. Used for relaxation. */ -+ HOWTO (R_MICROBLAZE_64_NONE, /* Type. */ -+ 0, /* Rightshift. */ -+ 3, /* Size (0 = byte, 1 = short, 2 = long). */ -+ 0, /* Bitsize. */ -+ TRUE, /* PC_relative. */ -+ 0, /* Bitpos. */ -+ complain_overflow_dont, /* Complain on overflow. */ -+ NULL, /* Special Function. */ -+ "R_MICROBLAZE_64_NONE",/* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* Symbol Op Symbol relocation. */ -+ HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* 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_MICROBLAZE_32_SYM_OP_SYM", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0xffffffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* GNU extension to record C++ vtable hierarchy. */ -+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_GNU_VTINHERIT", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* GNU extension to record C++ vtable member usage. */ -+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_GNU_VTENTRY", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* A 64 bit GOTPC relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_GOTPC_64, /* 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_MICROBLAZE_GOTPC_64", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* A 64 bit GOT relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_GOT_64, /* 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_MICROBLAZE_GOT_64",/* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* A 64 bit PLT relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_PLT_64, /* 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_MICROBLAZE_PLT_64",/* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_REL, /* 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_MICROBLAZE_REL", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_JUMP_SLOT,/* 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_MICROBLAZE_JUMP_SLOT", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_GLOB_DAT,/* 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_MICROBLAZE_GLOB_DAT", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ TRUE), /* PC relative offset? */ -+ -+ /* A 64 bit GOT relative relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_GOTOFF_64, /* 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_MICROBLAZE_GOTOFF_64", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* A 32 bit GOT relative relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_GOTOFF_32, /* 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_MICROBLAZE_GOTOFF_32", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* COPY relocation. Table-entry not really used. */ -+ HOWTO (R_MICROBLAZE_COPY, /* 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_MICROBLAZE_COPY", /* Name. */ -+ FALSE, /* Partial Inplace. */ -+ 0, /* Source Mask. */ -+ 0x0000ffff, /* Dest Mask. */ -+ FALSE), /* PC relative offset? */ -+ -+ /* Marker relocs for TLS. */ -+ HOWTO (R_MICROBLAZE_TLS, -+ 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_MICROBLAZE_TLS", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ HOWTO (R_MICROBLAZE_TLSGD, -+ 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_MICROBLAZE_TLSGD", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ HOWTO (R_MICROBLAZE_TLSLD, -+ 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_MICROBLAZE_TLSLD", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ /* Computes the load module index of the load module that contains the -+ definition of its TLS sym. */ -+ HOWTO (R_MICROBLAZE_TLSDTPMOD32, -+ 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_MICROBLAZE_TLSDTPMOD32", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ /* Computes a dtv-relative displacement, the difference between the value -+ of sym+add and the base address of the thread-local storage block that -+ contains the definition of sym, minus 0x8000. Used for initializing GOT */ -+ HOWTO (R_MICROBLAZE_TLSDTPREL32, -+ 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_MICROBLAZE_TLSDTPREL32", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ /* Computes a dtv-relative displacement, the difference between the value -+ of sym+add and the base address of the thread-local storage block that -+ contains the definition of sym, minus 0x8000. */ -+ HOWTO (R_MICROBLAZE_TLSDTPREL64, -+ 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_MICROBLAZE_TLSDTPREL64", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ /* Computes a tp-relative displacement, the difference between the value of -+ sym+add and the value of the thread pointer (r13). */ -+ HOWTO (R_MICROBLAZE_TLSGOTTPREL32, -+ 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_MICROBLAZE_TLSGOTTPREL32", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+ /* Computes a tp-relative displacement, the difference between the value of -+ sym+add and the value of the thread pointer (r13). */ -+ HOWTO (R_MICROBLAZE_TLSTPREL32, -+ 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_MICROBLAZE_TLSTPREL32", /* name */ -+ FALSE, /* partial_inplace */ -+ 0, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ -+}; -+ -+#ifndef NUM_ELEM -+#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) -+#endif -+ -+/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */ -+ -+static void -+microblaze_elf_howto_init (void) -+{ -+ unsigned int i; -+ -+ for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;) -+ { -+ unsigned int type; -+ -+ type = microblaze_elf_howto_raw[i].type; -+ -+ BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table)); -+ -+ microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i]; -+ } -+} -+ -+static reloc_howto_type * -+microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, -+ bfd_reloc_code_real_type code) -+{ -+ enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE; -+ -+ switch (code) -+ { -+ case BFD_RELOC_NONE: -+ microblaze_reloc = R_MICROBLAZE_NONE; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_NONE: -+ microblaze_reloc = R_MICROBLAZE_32_NONE; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_NONE: -+ microblaze_reloc = R_MICROBLAZE_64_NONE; -+ break; -+ case BFD_RELOC_32: -+ microblaze_reloc = R_MICROBLAZE_32; -+ break; -+ /* RVA is treated the same as 32 */ -+ case BFD_RELOC_RVA: -+ microblaze_reloc = R_MICROBLAZE_32; -+ break; -+ case BFD_RELOC_32_PCREL: -+ microblaze_reloc = R_MICROBLAZE_32_PCREL; -+ break; -+ case BFD_RELOC_64_PCREL: -+ microblaze_reloc = R_MICROBLAZE_64_PCREL; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_LO_PCREL: -+ microblaze_reloc = R_MICROBLAZE_32_PCREL_LO; -+ break; -+ case BFD_RELOC_64: -+ microblaze_reloc = R_MICROBLAZE_64; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_LO: -+ microblaze_reloc = R_MICROBLAZE_32_LO; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_ROSDA: -+ microblaze_reloc = R_MICROBLAZE_SRO32; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_RWSDA: -+ microblaze_reloc = R_MICROBLAZE_SRW32; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: -+ microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM; -+ break; -+ case BFD_RELOC_VTABLE_INHERIT: -+ microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT; -+ break; -+ case BFD_RELOC_VTABLE_ENTRY: -+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_GOTPC: -+ microblaze_reloc = R_MICROBLAZE_GOTPC_64; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_GOT: -+ microblaze_reloc = R_MICROBLAZE_GOT_64; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_PLT: -+ microblaze_reloc = R_MICROBLAZE_PLT_64; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_GOTOFF: -+ microblaze_reloc = R_MICROBLAZE_GOTOFF_64; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_GOTOFF: -+ microblaze_reloc = R_MICROBLAZE_GOTOFF_32; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_TLSGD: -+ microblaze_reloc = R_MICROBLAZE_TLSGD; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_TLSLD: -+ microblaze_reloc = R_MICROBLAZE_TLSLD; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL: -+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: -+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64; -+ break; -+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: -+ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: -+ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32; -+ break; -+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL: -+ microblaze_reloc = R_MICROBLAZE_TLSTPREL32; -+ break; -+ case BFD_RELOC_MICROBLAZE_COPY: -+ microblaze_reloc = R_MICROBLAZE_COPY; -+ break; -+ default: -+ return (reloc_howto_type *) NULL; -+ } -+ -+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32]) -+ /* Initialize howto table if needed. */ -+ microblaze_elf_howto_init (); -+ -+ return microblaze_elf_howto_table [(int) microblaze_reloc]; -+}; -+ -+static reloc_howto_type * -+microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, -+ const char *r_name) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++) -+ if (microblaze_elf_howto_raw[i].name != NULL -+ && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0) -+ return µblaze_elf_howto_raw[i]; -+ -+ return NULL; -+} -+ -+/* Set the howto pointer for a RCE ELF reloc. */ -+ -+static bfd_boolean -+microblaze_elf_info_to_howto (bfd * abfd, -+ arelent * cache_ptr, -+ Elf_Internal_Rela * dst) -+{ -+ unsigned int r_type; -+ -+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32]) -+ /* Initialize howto table if needed. */ -+ microblaze_elf_howto_init (); -+ -+ r_type = ELF64_R_TYPE (dst->r_info); -+ if (r_type >= R_MICROBLAZE_max) -+ { -+ /* xgettext:c-format */ -+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), -+ abfd, r_type); -+ bfd_set_error (bfd_error_bad_value); -+ return FALSE; -+ } -+ -+ cache_ptr->howto = microblaze_elf_howto_table [r_type]; -+ return TRUE; -+} -+ -+/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */ -+ -+static bfd_boolean -+microblaze_elf_is_local_label_name (bfd *abfd, const char *name) -+{ -+ if (name[0] == 'L' && name[1] == '.') -+ return TRUE; -+ -+ if (name[0] == '$' && name[1] == 'L') -+ return TRUE; -+ -+ /* With gcc, the labels go back to starting with '.', so we accept -+ the generic ELF local label syntax as well. */ -+ return _bfd_elf_is_local_label_name (abfd, name); -+} -+ -+/* The microblaze linker (like many others) 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 elf64_mb_dyn_relocs -+{ -+ struct elf64_mb_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; -+}; -+ -+/* ELF linker hash entry. */ -+ -+struct elf64_mb_link_hash_entry -+{ -+ struct elf_link_hash_entry elf; -+ -+ /* Track dynamic relocs copied for this symbol. */ -+ struct elf64_mb_dyn_relocs *dyn_relocs; -+ -+ /* TLS Reference Types for the symbol; Updated by check_relocs */ -+#define TLS_GD 1 /* GD reloc. */ -+#define TLS_LD 2 /* LD reloc. */ -+#define TLS_TPREL 4 /* TPREL reloc, => IE. */ -+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */ -+#define TLS_TLS 16 /* Any TLS reloc. */ -+ unsigned char tls_mask; -+ -+}; -+ -+#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD)) -+#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD)) -+#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL)) -+#define IS_TLS_NONE(x) (x == 0) -+ -+#define elf64_mb_hash_entry(ent) ((struct elf64_mb_link_hash_entry *)(ent)) -+ -+/* ELF linker hash table. */ -+ -+struct elf64_mb_link_hash_table -+{ -+ struct elf_link_hash_table elf; -+ -+ /* 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; -+ -+ /* TLS Local Dynamic GOT Entry */ -+ union { -+ bfd_signed_vma refcount; -+ bfd_vma offset; -+ } tlsld_got; -+}; -+ -+/* Nonzero if this section has TLS related relocations. */ -+#define has_tls_reloc sec_flg0 -+ -+/* Get the ELF linker hash table from a link_info structure. */ -+ -+#define elf64_mb_hash_table(p) \ -+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ -+ == MICROBLAZE_ELF_DATA ? ((struct elf64_mb_link_hash_table *) ((p)->hash)) : NULL) -+ -+/* Create an entry in a microblaze 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 elf64_mb_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 elf64_mb_link_hash_entry *eh; -+ -+ eh = (struct elf64_mb_link_hash_entry *) entry; -+ eh->tls_mask = 0; -+ } -+ -+ return entry; -+} -+ -+/* Create a mb ELF linker hash table. */ -+ -+static struct bfd_link_hash_table * -+microblaze_elf_link_hash_table_create (bfd *abfd) -+{ -+ struct elf64_mb_link_hash_table *ret; -+ size_t amt = sizeof (struct elf64_mb_link_hash_table); -+ -+ ret = (struct elf64_mb_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 elf64_mb_link_hash_entry), -+ MICROBLAZE_ELF_DATA)) -+ { -+ free (ret); -+ return NULL; -+ } -+ -+ return &ret->elf.root; -+} -+ -+/* Set the values of the small data pointers. */ -+ -+static void -+microblaze_elf_final_sdp (struct bfd_link_info *info) -+{ -+ struct bfd_link_hash_entry *h; -+ -+ h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE); -+ if (h != (struct bfd_link_hash_entry *) NULL -+ && h->type == bfd_link_hash_defined) -+ ro_small_data_pointer = (h->u.def.value -+ + h->u.def.section->output_section->vma -+ + h->u.def.section->output_offset); -+ -+ h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE); -+ if (h != (struct bfd_link_hash_entry *) NULL -+ && h->type == bfd_link_hash_defined) -+ rw_small_data_pointer = (h->u.def.value -+ + h->u.def.section->output_section->vma -+ + h->u.def.section->output_offset); -+} -+ -+static bfd_vma -+dtprel_base (struct bfd_link_info *info) -+{ -+ /* If tls_sec is NULL, we should have signalled an error already. */ -+ if (elf_hash_table (info)->tls_sec == NULL) -+ return 0; -+ return elf_hash_table (info)->tls_sec->vma; -+} -+ -+/* The size of the thread control block. */ -+#define TCB_SIZE 8 -+ -+/* Output a simple dynamic relocation into SRELOC. */ -+ -+static void -+microblaze_elf_output_dynamic_relocation (bfd *output_bfd, -+ asection *sreloc, -+ unsigned long reloc_index, -+ unsigned long indx, -+ int r_type, -+ bfd_vma offset, -+ bfd_vma addend) -+{ -+ -+ Elf_Internal_Rela rel; -+ -+ rel.r_info = ELF64_R_INFO (indx, r_type); -+ rel.r_offset = offset; -+ rel.r_addend = addend; -+ -+ bfd_elf64_swap_reloca_out (output_bfd, &rel, -+ (sreloc->contents + reloc_index * sizeof (Elf64_External_Rela))); -+} -+ -+/* This code is taken from elf64-m32r.c -+ There is some attempt to make this function usable for many architectures, -+ both USE_REL and USE_RELA ['twould be nice if such a critter existed], -+ if only to serve as a learning tool. -+ -+ 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 adjust 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 -+microblaze_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) -+{ -+ struct elf64_mb_link_hash_table *htab; -+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; -+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); -+ Elf_Internal_Rela *rel, *relend; -+ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2; -+ /* Assume success. */ -+ bfd_boolean ret = TRUE; -+ asection *sreloc; -+ bfd_vma *local_got_offsets; -+ unsigned int tls_type; -+ -+ if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1]) -+ microblaze_elf_howto_init (); -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ local_got_offsets = elf_local_got_offsets (input_bfd); -+ -+ sreloc = elf_section_data (input_section)->sreloc; -+ -+ rel = relocs; -+ relend = relocs + input_section->reloc_count; -+ for (; rel < relend; rel++) -+ { -+ int r_type; -+ reloc_howto_type *howto; -+ unsigned long r_symndx; -+ bfd_vma addend = rel->r_addend; -+ bfd_vma offset = rel->r_offset; -+ struct elf_link_hash_entry *h; -+ Elf_Internal_Sym *sym; -+ asection *sec; -+ const char *sym_name; -+ bfd_reloc_status_type r = bfd_reloc_ok; -+ const char *errmsg = NULL; -+ bfd_boolean unresolved_reloc = FALSE; -+ -+ h = NULL; -+ r_type = ELF64_R_TYPE (rel->r_info); -+ tls_type = 0; -+ -+ if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max) -+ { -+ (*_bfd_error_handler) (_("%s: unknown relocation type %d"), -+ bfd_get_filename (input_bfd), (int) r_type); -+ bfd_set_error (bfd_error_bad_value); -+ ret = FALSE; -+ continue; -+ } -+ -+ howto = microblaze_elf_howto_table[r_type]; -+ r_symndx = ELF64_R_SYM (rel->r_info); -+ -+ if (bfd_link_relocatable (info)) -+ { -+ /* This is a relocatable link. We don't have to change -+ anything, unless the reloc is against a section symbol, -+ in which case we have to adjust according to where the -+ section symbol winds up in the output section. */ -+ sec = NULL; -+ if (r_symndx >= symtab_hdr->sh_info) -+ /* External symbol. */ -+ continue; -+ -+ /* Local symbol. */ -+ sym = local_syms + r_symndx; -+ sym_name = "<local symbol>"; -+ /* STT_SECTION: symbol is associated with a section. */ -+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) -+ /* Symbol isn't associated with a section. Nothing to do. */ -+ continue; -+ -+ sec = local_sections[r_symndx]; -+ addend += sec->output_offset + sym->st_value; -+#ifndef USE_REL -+ /* This can't be done for USE_REL because it doesn't mean anything -+ and elf_link_input_bfd asserts this stays zero. */ -+ /* rel->r_addend = addend; */ -+#endif -+ -+#ifndef USE_REL -+ /* Addends are stored with relocs. We're done. */ -+ continue; -+#else /* USE_REL */ -+ /* If partial_inplace, we need to store any additional addend -+ back in the section. */ -+ if (!howto->partial_inplace) -+ continue; -+ /* ??? Here is a nice place to call a special_function like handler. */ -+ r = _bfd_relocate_contents (howto, input_bfd, addend, -+ contents + offset); -+#endif /* USE_REL */ -+ } -+ else -+ { -+ bfd_vma relocation; -+ bfd_boolean resolved_to_zero; -+ -+ /* This is a final link. */ -+ sym = NULL; -+ sec = NULL; -+ unresolved_reloc = FALSE; -+ -+ if (r_symndx < symtab_hdr->sh_info) -+ { -+ /* Local symbol. */ -+ sym = local_syms + r_symndx; -+ sec = local_sections[r_symndx]; -+ if (sec == 0) -+ continue; -+ sym_name = "<local symbol>"; -+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); -+ /* r_addend may have changed if the reference section was -+ a merge section. */ -+ addend = rel->r_addend; -+ } -+ else -+ { -+ /* External symbol. */ -+ bfd_boolean warned ATTRIBUTE_UNUSED; -+ bfd_boolean ignored ATTRIBUTE_UNUSED; -+ -+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, -+ r_symndx, symtab_hdr, sym_hashes, -+ h, sec, relocation, -+ unresolved_reloc, warned, ignored); -+ sym_name = h->root.root.string; -+ } -+ -+ /* Sanity check the address. */ -+ if (offset > bfd_get_section_limit (input_bfd, input_section)) -+ { -+ r = bfd_reloc_outofrange; -+ goto check_reloc; -+ } -+ -+ resolved_to_zero = (h != NULL -+ && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); -+ -+ switch ((int) r_type) -+ { -+ case (int) R_MICROBLAZE_SRO32 : -+ { -+ const char *name; -+ -+ /* Only relocate if the symbol is defined. */ -+ if (sec) -+ { -+ name = bfd_section_name (sec); -+ -+ if (strcmp (name, ".sdata2") == 0 -+ || strcmp (name, ".sbss2") == 0) -+ { -+ if (ro_small_data_pointer == 0) -+ microblaze_elf_final_sdp (info); -+ if (ro_small_data_pointer == 0) -+ { -+ ret = FALSE; -+ r = bfd_reloc_undefined; -+ goto check_reloc; -+ } -+ -+ /* At this point `relocation' contains the object's -+ address. */ -+ relocation -= ro_small_data_pointer; -+ /* Now it contains the offset from _SDA2_BASE_. */ -+ r = _bfd_final_link_relocate (howto, input_bfd, -+ input_section, -+ contents, offset, -+ relocation, addend); -+ } -+ else -+ { -+ _bfd_error_handler -+ /* xgettext:c-format */ -+ (_("%pB: the target (%s) of an %s relocation" -+ " is in the wrong section (%pA)"), -+ input_bfd, -+ sym_name, -+ microblaze_elf_howto_table[(int) r_type]->name, -+ sec); -+ /*bfd_set_error (bfd_error_bad_value); ??? why? */ -+ ret = FALSE; -+ continue; -+ } -+ } -+ } -+ break; -+ -+ case (int) R_MICROBLAZE_SRW32 : -+ { -+ const char *name; -+ -+ /* Only relocate if the symbol is defined. */ -+ if (sec) -+ { -+ name = bfd_section_name (sec); -+ -+ if (strcmp (name, ".sdata") == 0 -+ || strcmp (name, ".sbss") == 0) -+ { -+ if (rw_small_data_pointer == 0) -+ microblaze_elf_final_sdp (info); -+ if (rw_small_data_pointer == 0) -+ { -+ ret = FALSE; -+ r = bfd_reloc_undefined; -+ goto check_reloc; -+ } -+ -+ /* At this point `relocation' contains the object's -+ address. */ -+ relocation -= rw_small_data_pointer; -+ /* Now it contains the offset from _SDA_BASE_. */ -+ r = _bfd_final_link_relocate (howto, input_bfd, -+ input_section, -+ contents, offset, -+ relocation, addend); -+ } -+ else -+ { -+ _bfd_error_handler -+ /* xgettext:c-format */ -+ (_("%pB: the target (%s) of an %s relocation" -+ " is in the wrong section (%pA)"), -+ input_bfd, -+ sym_name, -+ microblaze_elf_howto_table[(int) r_type]->name, -+ sec); -+ /*bfd_set_error (bfd_error_bad_value); ??? why? */ -+ ret = FALSE; -+ continue; -+ } -+ } -+ } -+ break; -+ -+ case (int) R_MICROBLAZE_32_SYM_OP_SYM: -+ break; /* Do nothing. */ -+ -+ case (int) R_MICROBLAZE_GOTPC_64: -+ relocation = htab->sgotplt->output_section->vma -+ + htab->sgotplt->output_offset; -+ relocation -= (input_section->output_section->vma -+ + input_section->output_offset -+ + offset + INST_WORD_SIZE); -+ relocation += addend; -+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, relocation & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ break; -+ -+ case (int) R_MICROBLAZE_PLT_64: -+ { -+ bfd_vma immediate; -+ 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); -+ unresolved_reloc = FALSE; -+ immediate = relocation - (input_section->output_section->vma -+ + input_section->output_offset -+ + offset + INST_WORD_SIZE); -+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, immediate & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ } -+ else -+ { -+ relocation -= (input_section->output_section->vma -+ + input_section->output_offset -+ + offset + INST_WORD_SIZE); -+ immediate = relocation; -+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, immediate & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ } -+ break; -+ } -+ -+ case (int) R_MICROBLAZE_TLSGD: -+ tls_type = (TLS_TLS | TLS_GD); -+ goto dogot; -+ case (int) R_MICROBLAZE_TLSLD: -+ tls_type = (TLS_TLS | TLS_LD); -+ dogot: -+ case (int) R_MICROBLAZE_GOT_64: -+ { -+ bfd_vma *offp; -+ bfd_vma off, off2; -+ unsigned long indx; -+ bfd_vma static_value; -+ -+ bfd_boolean need_relocs = FALSE; -+ if (htab->sgot == NULL) -+ abort (); -+ -+ indx = 0; -+ offp = NULL; -+ -+ /* 1. Identify GOT Offset; -+ 2. Compute Static Values -+ 3. Process Module Id, Process Offset -+ 4. Fixup Relocation with GOT offset value. */ -+ -+ /* 1. Determine GOT Offset to use : TLS_LD, global, local */ -+ if (IS_TLS_LD (tls_type)) -+ offp = &htab->tlsld_got.offset; -+ else if (h != NULL) -+ { -+ if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1) -+ offp = &h->got.offset; -+ else -+ abort (); -+ } -+ else -+ { -+ if (local_got_offsets == NULL) -+ abort (); -+ offp = &local_got_offsets[r_symndx]; -+ } -+ -+ if (!offp) -+ abort (); -+ -+ off = (*offp) & ~1; -+ off2 = off; -+ -+ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type)) -+ off2 = off + 4; -+ -+ /* Symbol index to use for relocs */ -+ if (h != NULL) -+ { -+ bfd_boolean dyn = -+ elf_hash_table (info)->dynamic_sections_created; -+ -+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, -+ bfd_link_pic (info), -+ h) -+ && (!bfd_link_pic (info) -+ || !SYMBOL_REFERENCES_LOCAL (info, h))) -+ indx = h->dynindx; -+ } -+ -+ /* Need to generate relocs ? */ -+ if ((bfd_link_pic (info) || indx != 0) -+ && (h == NULL -+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT -+ && !resolved_to_zero) -+ || h->root.type != bfd_link_hash_undefweak)) -+ need_relocs = TRUE; -+ -+ /* 2. Compute/Emit Static value of r-expression */ -+ static_value = relocation + addend; -+ -+ /* 3. Process module-id and offset */ -+ if (! ((*offp) & 1) ) -+ { -+ bfd_vma got_offset; -+ -+ got_offset = (htab->sgot->output_section->vma -+ + htab->sgot->output_offset -+ + off); -+ -+ /* Process module-id */ -+ if (IS_TLS_LD(tls_type)) -+ { -+ if (! bfd_link_pic (info)) -+ { -+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off); -+ } -+ else -+ { -+ microblaze_elf_output_dynamic_relocation (output_bfd, -+ htab->srelgot, htab->srelgot->reloc_count++, -+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32, -+ got_offset, 0); -+ } -+ } -+ else if (IS_TLS_GD(tls_type)) -+ { -+ if (! need_relocs) -+ { -+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off); -+ } -+ else -+ { -+ microblaze_elf_output_dynamic_relocation (output_bfd, -+ htab->srelgot, -+ htab->srelgot->reloc_count++, -+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32, -+ got_offset, indx ? 0 : static_value); -+ } -+ } -+ -+ /* Process Offset */ -+ if (htab->srelgot == NULL) -+ abort (); -+ -+ got_offset = (htab->sgot->output_section->vma -+ + htab->sgot->output_offset -+ + off2); -+ if (IS_TLS_LD(tls_type)) -+ { -+ /* For LD, offset should be 0 */ -+ *offp |= 1; -+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2); -+ } -+ else if (IS_TLS_GD(tls_type)) -+ { -+ *offp |= 1; -+ static_value -= dtprel_base(info); -+ if (need_relocs) -+ microblaze_elf_output_dynamic_relocation -+ (output_bfd, -+ htab->elf.srelgot, -+ htab->elf.srelgot->reloc_count++, -+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32, -+ got_offset, indx ? 0 : static_value); -+ else -+ bfd_put_32 (output_bfd, static_value, -+ htab->elf.sgot->contents + off2); -+ } -+ else -+ { -+ bfd_put_32 (output_bfd, static_value, -+ htab->elf.sgot->contents + off2); -+ -+ /* Relocs for dyn symbols generated by -+ finish_dynamic_symbols */ -+ if (bfd_link_pic (info) && h == NULL) -+ { -+ *offp |= 1; -+ microblaze_elf_output_dynamic_relocation -+ (output_bfd, -+ htab->elf.srelgot, -+ htab->elf.srelgot->reloc_count++, -+ /* symindex= */ indx, R_MICROBLAZE_REL, -+ got_offset, static_value); -+ } -+ } -+ } -+ -+ /* 4. Fixup Relocation with GOT offset value -+ Compute relative address of GOT entry for applying -+ the current relocation */ -+ relocation = htab->elf.sgot->output_section->vma -+ + htab->elf.sgot->output_offset -+ + off -+ - htab->elf.sgotplt->output_section->vma -+ - htab->elf.sgotplt->output_offset; -+ -+ /* Apply Current Relocation */ -+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, relocation & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ -+ unresolved_reloc = FALSE; -+ break; -+ } -+ -+ case (int) R_MICROBLAZE_GOTOFF_64: -+ { -+ bfd_vma immediate; -+ unsigned short lo, high; -+ relocation += addend; -+ relocation -= (htab->elf.sgotplt->output_section->vma -+ + htab->elf.sgotplt->output_offset); -+ /* Write this value into correct location. */ -+ immediate = relocation; -+ lo = immediate & 0x0000ffff; -+ high = (immediate >> 16) & 0x0000ffff; -+ bfd_put_16 (input_bfd, high, contents + offset + endian); -+ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian); -+ break; -+ } -+ -+ case (int) R_MICROBLAZE_GOTOFF_32: -+ { -+ relocation += addend; -+ relocation -= (htab->elf.sgotplt->output_section->vma -+ + htab->elf.sgotplt->output_offset); -+ /* Write this value into correct location. */ -+ bfd_put_32 (input_bfd, relocation, contents + offset); -+ break; -+ } -+ -+ case (int) R_MICROBLAZE_TLSDTPREL64: -+ relocation += addend; -+ relocation -= dtprel_base(info); -+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, relocation & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ break; -+ case (int) R_MICROBLAZE_64_PCREL : -+ case (int) R_MICROBLAZE_64: -+ case (int) R_MICROBLAZE_32: -+ { -+ /* 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) -+ { -+ relocation += addend; -+ if (r_type == R_MICROBLAZE_32) -+ bfd_put_32 (input_bfd, relocation, contents + offset); -+ else -+ { -+ if (r_type == R_MICROBLAZE_64_PCREL) -+ relocation -= (input_section->output_section->vma -+ + input_section->output_offset -+ + offset + INST_WORD_SIZE); -+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, relocation & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ } -+ break; -+ } -+ -+ if ((bfd_link_pic (info) -+ && (h == NULL -+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT -+ && !resolved_to_zero) -+ || h->root.type != bfd_link_hash_undefweak) -+ && (!howto->pc_relative -+ || (h != NULL -+ && h->dynindx != -1 -+ && (!info->symbolic -+ || !h->def_regular)))) -+ || (!bfd_link_pic (info) -+ && 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 = ELF64_R_INFO (h->dynindx, r_type); -+ outrel.r_addend = addend; -+ } -+ else -+ { -+ if (r_type == R_MICROBLAZE_32) -+ { -+ outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL); -+ outrel.r_addend = relocation + 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 (Elf64_External_Rela); -+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); -+ break; -+ } -+ else -+ { -+ relocation += addend; -+ if (r_type == R_MICROBLAZE_32) -+ bfd_put_32 (input_bfd, relocation, contents + offset); -+ else -+ { -+ if (r_type == R_MICROBLAZE_64_PCREL) -+ relocation -= (input_section->output_section->vma -+ + input_section->output_offset -+ + offset + INST_WORD_SIZE); -+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, -+ contents + offset + endian); -+ bfd_put_16 (input_bfd, relocation & 0xffff, -+ contents + offset + endian + INST_WORD_SIZE); -+ } -+ break; -+ } -+ } -+ -+ default : -+ r = _bfd_final_link_relocate (howto, input_bfd, input_section, -+ contents, offset, -+ relocation, addend); -+ break; -+ } -+ } -+ -+ check_reloc: -+ -+ if (r != bfd_reloc_ok) -+ { -+ /* FIXME: This should be generic enough to go in a utility. */ -+ const char *name; -+ -+ 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 (sec); -+ } -+ -+ if (errmsg != NULL) -+ goto common_error; -+ -+ switch (r) -+ { -+ case bfd_reloc_overflow: -+ (*info->callbacks->reloc_overflow) -+ (info, (h ? &h->root : NULL), name, howto->name, -+ (bfd_vma) 0, input_bfd, input_section, offset); -+ break; -+ -+ case bfd_reloc_undefined: -+ (*info->callbacks->undefined_symbol) -+ (info, name, input_bfd, input_section, offset, TRUE); -+ break; -+ -+ case bfd_reloc_outofrange: -+ errmsg = _("internal error: out of range error"); -+ goto common_error; -+ -+ case bfd_reloc_notsupported: -+ errmsg = _("internal error: unsupported relocation error"); -+ goto common_error; -+ -+ case bfd_reloc_dangerous: -+ errmsg = _("internal error: dangerous error"); -+ goto common_error; -+ -+ default: -+ errmsg = _("internal error: unknown error"); -+ /* Fall through. */ -+ common_error: -+ (*info->callbacks->warning) (info, errmsg, name, input_bfd, -+ input_section, offset); -+ break; -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+/* Merge backend specific data from an object file to the output -+ object file when linking. -+ -+ Note: We only use this hook to catch endian mismatches. */ -+static bfd_boolean -+microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) -+{ -+ /* Check if we have the same endianess. */ -+ if (! _bfd_generic_verify_endian_match (ibfd, obfd)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+ -+/* Calculate fixup value for reference. */ -+ -+static int -+calc_fixup (bfd_vma start, bfd_vma size, asection *sec) -+{ -+ bfd_vma end = start + size; -+ int i, fixup = 0; -+ -+ if (sec == NULL || sec->relax == NULL) -+ return 0; -+ -+ /* Look for addr in relax table, total fixup value. */ -+ for (i = 0; i < sec->relax_count; i++) -+ { -+ if (end <= sec->relax[i].addr) -+ break; -+ if ((end != start) && (start > sec->relax[i].addr)) -+ continue; -+ fixup += sec->relax[i].size; -+ } -+ return fixup; -+} -+ -+/* Read-modify-write into the bfd, an immediate value into appropriate fields of -+ a 32-bit instruction. */ -+static void -+microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) -+{ -+ unsigned long instr = bfd_get_32 (abfd, bfd_addr); -+ instr &= ~0x0000ffff; -+ instr |= (val & 0x0000ffff); -+ bfd_put_32 (abfd, instr, bfd_addr); -+} -+ -+/* Read-modify-write into the bfd, an immediate value into appropriate fields of -+ two consecutive 32-bit instructions. */ -+static void -+microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) -+{ -+ unsigned long instr_hi; -+ unsigned long instr_lo; -+ -+ instr_hi = bfd_get_32 (abfd, bfd_addr); -+ instr_hi &= ~0x0000ffff; -+ instr_hi |= ((val >> 16) & 0x0000ffff); -+ bfd_put_32 (abfd, instr_hi, bfd_addr); -+ -+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE); -+ instr_lo &= ~0x0000ffff; -+ instr_lo |= (val & 0x0000ffff); -+ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE); -+} -+ -+static bfd_boolean -+microblaze_elf_relax_section (bfd *abfd, -+ asection *sec, -+ struct bfd_link_info *link_info, -+ bfd_boolean *again) -+{ -+ Elf_Internal_Shdr *symtab_hdr; -+ Elf_Internal_Rela *internal_relocs; -+ Elf_Internal_Rela *free_relocs = NULL; -+ Elf_Internal_Rela *irel, *irelend; -+ bfd_byte *contents = NULL; -+ bfd_byte *free_contents = NULL; -+ int rel_count; -+ unsigned int shndx; -+ int i, sym_index; -+ asection *o; -+ struct elf_link_hash_entry *sym_hash; -+ Elf_Internal_Sym *isymbuf, *isymend; -+ Elf_Internal_Sym *isym; -+ int symcount; -+ int offset; -+ bfd_vma src, dest; -+ -+ /* We only do this once per section. We may be able to delete some code -+ by running multiple passes, but it is not worth it. */ -+ *again = FALSE; -+ -+ /* Only do this for a text section. */ -+ if (bfd_link_relocatable (link_info) -+ || (sec->flags & SEC_RELOC) == 0 -+ || (sec->reloc_count == 0) -+ || (sec->flags & SEC_CODE) == 0) -+ return TRUE; -+ -+ BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0)); -+ -+ /* If this is the first time we have been called for this section, -+ initialize the cooked size. */ -+ if (sec->size == 0) -+ sec->size = sec->rawsize; -+ -+ /* Get symbols for this section. */ -+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; -+ symcount = symtab_hdr->sh_size / sizeof (Elf64_External_Sym); -+ if (isymbuf == NULL) -+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount, -+ 0, NULL, NULL, NULL); -+ BFD_ASSERT (isymbuf != NULL); -+ -+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory); -+ if (internal_relocs == NULL) -+ goto error_return; -+ if (! link_info->keep_memory) -+ free_relocs = internal_relocs; -+ -+ sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1) -+ * sizeof (struct relax_table)); -+ if (sec->relax == NULL) -+ goto error_return; -+ sec->relax_count = 0; -+ -+ irelend = internal_relocs + sec->reloc_count; -+ rel_count = 0; -+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++) -+ { -+ bfd_vma symval; -+ if ((ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL) -+ && (ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 )) -+ continue; /* Can't delete this reloc. */ -+ -+ /* Get the section contents. */ -+ if (contents == NULL) -+ { -+ if (elf_section_data (sec)->this_hdr.contents != NULL) -+ contents = elf_section_data (sec)->this_hdr.contents; -+ else -+ { -+ contents = (bfd_byte *) bfd_malloc (sec->size); -+ if (contents == NULL) -+ goto error_return; -+ free_contents = contents; -+ -+ if (!bfd_get_section_contents (abfd, sec, contents, -+ (file_ptr) 0, sec->size)) -+ goto error_return; -+ elf_section_data (sec)->this_hdr.contents = contents; -+ } -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info) -+ { -+ /* A local symbol. */ -+ asection *sym_sec; -+ -+ isym = isymbuf + ELF64_R_SYM (irel->r_info); -+ if (isym->st_shndx == SHN_UNDEF) -+ sym_sec = bfd_und_section_ptr; -+ else if (isym->st_shndx == SHN_ABS) -+ sym_sec = bfd_abs_section_ptr; -+ else if (isym->st_shndx == SHN_COMMON) -+ sym_sec = bfd_com_section_ptr; -+ else -+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); -+ -+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel); -+ } -+ else -+ { -+ unsigned long indx; -+ struct elf_link_hash_entry *h; -+ -+ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info; -+ h = elf_sym_hashes (abfd)[indx]; -+ BFD_ASSERT (h != NULL); -+ -+ if (h->root.type != bfd_link_hash_defined -+ && h->root.type != bfd_link_hash_defweak) -+ /* This appears to be a reference to an undefined -+ symbol. Just ignore it--it will be caught by the -+ regular reloc processing. */ -+ continue; -+ -+ symval = (h->root.u.def.value -+ + h->root.u.def.section->output_section->vma -+ + h->root.u.def.section->output_offset); -+ } -+ -+ /* If this is a PC-relative reloc, subtract the instr offset from -+ the symbol value. */ -+ if (ELF64_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL) -+ { -+ symval = symval + irel->r_addend -+ - (irel->r_offset -+ + sec->output_section->vma -+ + sec->output_offset); -+ } -+ else -+ symval += irel->r_addend; -+ -+ if ((symval & 0xffff8000) == 0) -+ { -+ /* We can delete this instruction. */ -+ sec->relax[sec->relax_count].addr = irel->r_offset; -+ sec->relax[sec->relax_count].size = INST_WORD_SIZE; -+ sec->relax_count++; -+ -+ /* Rewrite relocation type. */ -+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info)) -+ { -+ case R_MICROBLAZE_64_PCREL: -+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), -+ (int) R_MICROBLAZE_32_PCREL_LO); -+ break; -+ case R_MICROBLAZE_64: -+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), -+ (int) R_MICROBLAZE_32_LO); -+ break; -+ default: -+ /* Cannot happen. */ -+ BFD_ASSERT (FALSE); -+ } -+ } -+ } /* Loop through all relocations. */ -+ -+ /* Loop through the relocs again, and see if anything needs to change. */ -+ if (sec->relax_count > 0) -+ { -+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec); -+ rel_count = 0; -+ sec->relax[sec->relax_count].addr = sec->size; -+ -+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++) -+ { -+ bfd_vma nraddr; -+ -+ /* Get the new reloc address. */ -+ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec); -+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info)) -+ { -+ default: -+ break; -+ case R_MICROBLAZE_64_PCREL: -+ break; -+ case R_MICROBLAZE_64: -+ case R_MICROBLAZE_32_LO: -+ /* If this reloc is against a symbol defined in this -+ section, we must check the addend to see it will put the value in -+ range to be adjusted, and hence must be changed. */ -+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info) -+ { -+ isym = isymbuf + ELF64_R_SYM (irel->r_info); -+ /* Only handle relocs against .text. */ -+ if (isym->st_shndx == shndx -+ && ELF64_ST_TYPE (isym->st_info) == STT_SECTION) -+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec); -+ } -+ break; -+ case R_MICROBLAZE_NONE: -+ case R_MICROBLAZE_32_NONE: -+ { -+ /* This was a PC-relative instruction that was -+ completely resolved. */ -+ int sfix, efix; -+ unsigned int val; -+ bfd_vma target_address; -+ target_address = irel->r_addend + irel->r_offset; -+ sfix = calc_fixup (irel->r_offset, 0, sec); -+ efix = calc_fixup (target_address, 0, sec); -+ -+ /* Validate the in-band val. */ -+ val = bfd_get_32 (abfd, contents + irel->r_offset); -+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) { -+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend); -+ } -+ irel->r_addend -= (efix - sfix); -+ /* Should use HOWTO. */ -+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset, -+ irel->r_addend); -+ } -+ break; -+ case R_MICROBLAZE_64_NONE: -+ { -+ /* This was a PC-relative 64-bit instruction that was -+ completely resolved. */ -+ int sfix, efix; -+ bfd_vma target_address; -+ target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE; -+ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec); -+ efix = calc_fixup (target_address, 0, sec); -+ irel->r_addend -= (efix - sfix); -+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset -+ + INST_WORD_SIZE, irel->r_addend); -+ } -+ break; -+ } -+ irel->r_offset = nraddr; -+ } /* Change all relocs in this section. */ -+ -+ /* Look through all other sections. */ -+ for (o = abfd->sections; o != NULL; o = o->next) -+ { -+ Elf_Internal_Rela *irelocs; -+ Elf_Internal_Rela *irelscan, *irelscanend; -+ bfd_byte *ocontents; -+ -+ if (o == sec -+ || (o->flags & SEC_RELOC) == 0 -+ || o->reloc_count == 0) -+ continue; -+ -+ /* We always cache the relocs. Perhaps, if info->keep_memory is -+ FALSE, we should free them, if we are permitted to. */ -+ -+ irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE); -+ if (irelocs == NULL) -+ goto error_return; -+ -+ ocontents = NULL; -+ irelscanend = irelocs + o->reloc_count; -+ for (irelscan = irelocs; irelscan < irelscanend; irelscan++) -+ { -+ if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE) -+ { -+ unsigned int val; -+ -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* hax: We only do the following fixup for debug location lists. */ -+ if (strcmp(".debug_loc", o->name)) -+ continue; -+ -+ /* This was a PC-relative instruction that was completely resolved. */ -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ } -+ -+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset); -+ if (val != irelscan->r_addend) { -+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend); -+ } -+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec); -+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, -+ irelscan->r_addend); -+ } -+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32) -+ { -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* Look at the reloc only if the value has been resolved. */ -+ if (isym->st_shndx == shndx -+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION)) -+ { -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ -+ } -+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec); -+ } -+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM) -+ { -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* Look at the reloc only if the value has been resolved. */ -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ } -+ irelscan->r_addend -= calc_fixup (irelscan->r_addend -+ + isym->st_value, -+ 0, -+ sec); -+ } -+ } -+ else if ((ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO) -+ || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO)) -+ { -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* Look at the reloc only if the value has been resolved. */ -+ if (isym->st_shndx == shndx -+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION)) -+ { -+ bfd_vma immediate; -+ bfd_vma target_address; -+ -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ } -+ -+ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset); -+ immediate = instr & 0x0000ffff; -+ target_address = immediate; -+ offset = calc_fixup (target_address, 0, sec); -+ immediate -= offset; -+ irelscan->r_addend -= offset; -+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, -+ irelscan->r_addend); -+ } -+ } -+ -+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64) -+ { -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* Look at the reloc only if the value has been resolved. */ -+ if (isym->st_shndx == shndx -+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION)) -+ { -+ bfd_vma immediate; -+ -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ } -+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents -+ + irelscan->r_offset); -+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents -+ + irelscan->r_offset -+ + INST_WORD_SIZE); -+ immediate = (instr_hi & 0x0000ffff) << 16; -+ immediate |= (instr_lo & 0x0000ffff); -+ offset = calc_fixup (irelscan->r_addend, 0, sec); -+ immediate -= offset; -+ irelscan->r_addend -= offset; -+ } -+ } -+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL) -+ { -+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info); -+ -+ /* Look at the reloc only if the value has been resolved. */ -+ if (isym->st_shndx == shndx -+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION)) -+ { -+ bfd_vma immediate; -+ bfd_vma target_address; -+ -+ if (ocontents == NULL) -+ { -+ if (elf_section_data (o)->this_hdr.contents != NULL) -+ ocontents = elf_section_data (o)->this_hdr.contents; -+ else -+ { -+ /* We always cache the section contents. -+ Perhaps, if info->keep_memory is FALSE, we -+ should free them, if we are permitted to. */ -+ if (o->rawsize == 0) -+ o->rawsize = o->size; -+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize); -+ if (ocontents == NULL) -+ goto error_return; -+ if (!bfd_get_section_contents (abfd, o, ocontents, -+ (file_ptr) 0, -+ o->rawsize)) -+ goto error_return; -+ elf_section_data (o)->this_hdr.contents = ocontents; -+ } -+ } -+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents -+ + irelscan->r_offset); -+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents -+ + irelscan->r_offset -+ + INST_WORD_SIZE); -+ immediate = (instr_hi & 0x0000ffff) << 16; -+ immediate |= (instr_lo & 0x0000ffff); -+ target_address = immediate; -+ offset = calc_fixup (target_address, 0, sec); -+ immediate -= offset; -+ irelscan->r_addend -= offset; -+ microblaze_bfd_write_imm_value_64 (abfd, ocontents -+ + irelscan->r_offset, immediate); -+ } -+ } -+ } -+ } -+ -+ /* Adjust the local symbols defined in this section. */ -+ isymend = isymbuf + symtab_hdr->sh_info; -+ for (isym = isymbuf; isym < isymend; isym++) -+ { -+ if (isym->st_shndx == shndx) -+ { -+ isym->st_value -= calc_fixup (isym->st_value, 0, sec); -+ if (isym->st_size) -+ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec); -+ } -+ } -+ -+ /* Now adjust the global symbols defined in this section. */ -+ isym = isymbuf + symtab_hdr->sh_info; -+ symcount = (symtab_hdr->sh_size / sizeof (Elf64_External_Sym)) - symtab_hdr->sh_info; -+ for (sym_index = 0; sym_index < symcount; sym_index++) -+ { -+ sym_hash = elf_sym_hashes (abfd)[sym_index]; -+ if ((sym_hash->root.type == bfd_link_hash_defined -+ || sym_hash->root.type == bfd_link_hash_defweak) -+ && sym_hash->root.u.def.section == sec) -+ { -+ sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value, -+ 0, sec); -+ if (sym_hash->size) -+ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value, -+ sym_hash->size, sec); -+ } -+ } -+ -+ /* Physically move the code and change the cooked size. */ -+ dest = sec->relax[0].addr; -+ for (i = 0; i < sec->relax_count; i++) -+ { -+ int len; -+ src = sec->relax[i].addr + sec->relax[i].size; -+ len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size; -+ -+ memmove (contents + dest, contents + src, len); -+ sec->size -= sec->relax[i].size; -+ dest += len; -+ } -+ -+ elf_section_data (sec)->relocs = internal_relocs; -+ free_relocs = NULL; -+ -+ elf_section_data (sec)->this_hdr.contents = contents; -+ free_contents = NULL; -+ -+ symtab_hdr->contents = (bfd_byte *) isymbuf; -+ } -+ -+ if (free_relocs != NULL) -+ { -+ free (free_relocs); -+ free_relocs = NULL; -+ } -+ -+ if (free_contents != NULL) -+ { -+ if (!link_info->keep_memory) -+ free (free_contents); -+ else -+ /* Cache the section contents for elf_link_input_bfd. */ -+ elf_section_data (sec)->this_hdr.contents = contents; -+ free_contents = NULL; -+ } -+ -+ if (sec->relax_count == 0) -+ { -+ *again = FALSE; -+ free (sec->relax); -+ sec->relax = NULL; -+ } -+ else -+ *again = TRUE; -+ return TRUE; -+ -+ error_return: -+ if (free_relocs != NULL) -+ free (free_relocs); -+ if (free_contents != NULL) -+ free (free_contents); -+ if (sec->relax != NULL) -+ { -+ free (sec->relax); -+ sec->relax = NULL; -+ sec->relax_count = 0; -+ } -+ return FALSE; -+} -+ -+/* Return the section that should be marked against GC for a given -+ relocation. */ -+ -+static asection * -+microblaze_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 (ELF64_R_TYPE (rel->r_info)) -+ { -+ case R_MICROBLAZE_GNU_VTINHERIT: -+ case R_MICROBLAZE_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 -+microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, -+ struct bfd_link_info * info ATTRIBUTE_UNUSED, -+ asection * sec ATTRIBUTE_UNUSED, -+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED) -+{ -+ return TRUE; -+} -+ -+/* PIC support. */ -+ -+#define PLT_ENTRY_SIZE 16 -+ -+#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */ -+#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */ -+#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */ -+#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */ -+#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */ -+ -+/* 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 elf64_mb_link_hash_table *htab; -+ -+ if (! _bfd_elf_create_got_section (dynobj, info)) -+ return FALSE; -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ htab->sgot = bfd_get_linker_section (dynobj, ".got"); -+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt"); -+ if (!htab->sgot || !htab->sgotplt) -+ return FALSE; -+ -+ if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL) -+ htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got"); -+ if (htab->srelgot == NULL -+ || ! bfd_set_section_flags (htab->srelgot, SEC_ALLOC -+ | SEC_LOAD -+ | SEC_HAS_CONTENTS -+ | SEC_IN_MEMORY -+ | SEC_LINKER_CREATED -+ | SEC_READONLY) -+ || ! bfd_set_section_alignment (htab->srelgot, 2)) -+ return FALSE; -+ return TRUE; -+} -+ -+static bfd_boolean -+update_local_sym_info (bfd *abfd, -+ Elf_Internal_Shdr *symtab_hdr, -+ unsigned long r_symndx, -+ unsigned int tls_type) -+{ -+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd); -+ unsigned char *local_got_tls_masks; -+ -+ if (local_got_refcounts == NULL) -+ { -+ bfd_size_type size = symtab_hdr->sh_info; -+ -+ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks)); -+ local_got_refcounts = bfd_zalloc (abfd, size); -+ if (local_got_refcounts == NULL) -+ return FALSE; -+ elf_local_got_refcounts (abfd) = local_got_refcounts; -+ } -+ -+ local_got_tls_masks = -+ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info); -+ local_got_tls_masks[r_symndx] |= tls_type; -+ local_got_refcounts[r_symndx] += 1; -+ -+ return TRUE; -+} -+/* Look through the relocs for a section during the first phase. */ -+ -+static bfd_boolean -+microblaze_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; -+ struct elf_link_hash_entry ** sym_hashes_end; -+ const Elf_Internal_Rela * rel; -+ const Elf_Internal_Rela * rel_end; -+ struct elf64_mb_link_hash_table *htab; -+ asection *sreloc = NULL; -+ -+ if (bfd_link_relocatable (info)) -+ return TRUE; -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr; -+ sym_hashes = elf_sym_hashes (abfd); -+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf64_External_Sym); -+ if (!elf_bad_symtab (abfd)) -+ sym_hashes_end -= symtab_hdr->sh_info; -+ -+ rel_end = relocs + sec->reloc_count; -+ -+ for (rel = relocs; rel < rel_end; rel++) -+ { -+ unsigned int r_type; -+ struct elf_link_hash_entry * h; -+ unsigned long r_symndx; -+ unsigned char tls_type = 0; -+ -+ r_symndx = ELF64_R_SYM (rel->r_info); -+ r_type = ELF64_R_TYPE (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 (r_type) -+ { -+ /* This relocation describes the C++ object vtable hierarchy. -+ Reconstruct it for later use during GC. */ -+ case R_MICROBLAZE_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_MICROBLAZE_GNU_VTENTRY: -+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) -+ return FALSE; -+ break; -+ -+ /* This relocation requires .plt entry. */ -+ case R_MICROBLAZE_PLT_64: -+ if (h != NULL) -+ { -+ h->needs_plt = 1; -+ h->plt.refcount += 1; -+ } -+ break; -+ -+ /* This relocation requires .got entry. */ -+ case R_MICROBLAZE_TLSGD: -+ tls_type |= (TLS_TLS | TLS_GD); -+ goto dogottls; -+ case R_MICROBLAZE_TLSLD: -+ tls_type |= (TLS_TLS | TLS_LD); -+ dogottls: -+ sec->has_tls_reloc = 1; -+ case R_MICROBLAZE_GOT_64: -+ if (htab->sgot == NULL) -+ { -+ if (htab->elf.dynobj == NULL) -+ htab->elf.dynobj = abfd; -+ if (!create_got_section (htab->elf.dynobj, info)) -+ return FALSE; -+ } -+ if (h != NULL) -+ { -+ h->got.refcount += 1; -+ elf64_mb_hash_entry (h)->tls_mask |= tls_type; -+ } -+ else -+ { -+ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) ) -+ return FALSE; -+ } -+ break; -+ -+ case R_MICROBLAZE_64: -+ case R_MICROBLAZE_64_PCREL: -+ case R_MICROBLAZE_32: -+ { -+ if (h != NULL && !bfd_link_pic (info)) -+ { -+ /* we may need a copy reloc. */ -+ h->non_got_ref = 1; -+ -+ /* we may also need a .plt entry. */ -+ h->plt.refcount += 1; -+ if (ELF64_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL) -+ 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 ((bfd_link_pic (info) -+ && (sec->flags & SEC_ALLOC) != 0 -+ && (r_type != R_MICROBLAZE_64_PCREL -+ || (h != NULL -+ && (! info->symbolic -+ || h->root.type == bfd_link_hash_defweak -+ || !h->def_regular)))) -+ || (!bfd_link_pic (info) -+ && (sec->flags & SEC_ALLOC) != 0 -+ && h != NULL -+ && (h->root.type == bfd_link_hash_defweak -+ || !h->def_regular))) -+ { -+ struct elf64_mb_dyn_relocs *p; -+ struct elf64_mb_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) -+ { -+ bfd *dynobj; -+ -+ if (htab->elf.dynobj == NULL) -+ htab->elf.dynobj = abfd; -+ dynobj = htab->elf.dynobj; -+ -+ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj, -+ 2, abfd, 1); -+ 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 = &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 elf64_mb_dyn_relocs **) vpp; -+ } -+ -+ p = *head; -+ if (p == NULL || p->sec != sec) -+ { -+ size_t amt = sizeof *p; -+ p = ((struct elf64_mb_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; -+ if (r_type == R_MICROBLAZE_64_PCREL) -+ p->pc_count += 1; -+ } -+ } -+ break; -+ } -+ } -+ -+ return TRUE; -+} -+ -+static bfd_boolean -+microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) -+{ -+ struct elf64_mb_link_hash_table *htab; -+ -+ htab = elf64_mb_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_linker_section (dynobj, ".plt"); -+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt"); -+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); -+ if (!bfd_link_pic (info)) -+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss"); -+ -+ if (!htab->splt || !htab->srelplt || !htab->sdynbss -+ || (!bfd_link_pic (info) && !htab->srelbss)) -+ abort (); -+ -+ return TRUE; -+} -+ -+/* Copy the extra info we tack onto an elf_link_hash_entry. */ -+ -+static void -+microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info, -+ struct elf_link_hash_entry *dir, -+ struct elf_link_hash_entry *ind) -+{ -+ struct elf64_mb_link_hash_entry *edir, *eind; -+ -+ edir = (struct elf64_mb_link_hash_entry *) dir; -+ eind = (struct elf64_mb_link_hash_entry *) ind; -+ -+ if (eind->dyn_relocs != NULL) -+ { -+ if (edir->dyn_relocs != NULL) -+ { -+ struct elf64_mb_dyn_relocs **pp; -+ struct elf64_mb_dyn_relocs *p; -+ -+ if (ind->root.type == bfd_link_hash_indirect) -+ abort (); -+ -+ /* Add reloc counts against the weak sym to the strong sym -+ list. Merge any entries against the same section. */ -+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) -+ { -+ struct elf64_mb_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; -+ } -+ -+ edir->tls_mask |= eind->tls_mask; -+ -+ _bfd_elf_link_hash_copy_indirect (info, dir, ind); -+} -+ -+static bfd_boolean -+microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info, -+ struct elf_link_hash_entry *h) -+{ -+ struct elf64_mb_link_hash_table *htab; -+ struct elf64_mb_link_hash_entry * eh; -+ struct elf64_mb_dyn_relocs *p; -+ asection *sdynbss; -+ asection *s, *srel; -+ unsigned int power_of_two; -+ bfd *dynobj; -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ /* 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->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 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 procedure -+ linkage table, and we can just do a PC32 reloc instead. */ -+ h->plt.offset = (bfd_vma) -1; -+ h->needs_plt = 0; -+ } -+ -+ return TRUE; -+ } -+ else -+ /* It's possible that we incorrectly decided a .plt reloc was -+ needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in -+ check_relocs. We can't decide accurately between function and -+ non-function syms in check-relocs; Objects loaded later in -+ the link may change h->type. So fix it now. */ -+ 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->is_weakalias) -+ { -+ struct elf_link_hash_entry *def = weakdef (h); -+ BFD_ASSERT (def->root.type == bfd_link_hash_defined); -+ h->root.u.def.section = def->root.u.def.section; -+ h->root.u.def.value = def->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 (bfd_link_pic (info)) -+ 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 elf64_mb_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 (!_bfd_elf_readonly_dynrelocs (h)) -+ { -+ 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_MICROBLAZE_COPY reloc to tell the dynamic linker -+ to copy the initial value out of the dynamic object and into the -+ runtime process image. */ -+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0) -+ { -+ s = htab->elf.sdynrelro; -+ srel = htab->elf.sreldynrelro; -+ } -+ else -+ { -+ s = htab->elf.sdynbss; -+ srel = htab->elf.srelbss; -+ } -+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) -+ { -+ srel->size += sizeof (Elf64_External_Rela); -+ h->needs_copy = 1; -+ } -+ -+ /* We need to figure out the alignment required for this symbol. I -+ have no idea how ELF linkers handle this. */ -+ power_of_two = bfd_log2 (h->size); -+ if (power_of_two > 3) -+ power_of_two = 3; -+ -+ /* Apply the required alignment. */ -+ s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); -+ if (power_of_two > s->alignment_power) -+ { -+ if (!bfd_set_section_alignment (s, power_of_two)) -+ return FALSE; -+ } -+ -+ /* Define the symbol as being at this point in the section. */ -+ h->root.u.def.section = s; -+ h->root.u.def.value = s->size; -+ -+ /* Increment the section size to make room for the symbol. */ -+ s->size += h->size; -+ return TRUE; -+} -+ -+/* Allocate space in .plt, .got and associated reloc sections for -+ dynamic relocs. */ -+ -+static bfd_boolean -+allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat) -+{ -+ struct bfd_link_info *info; -+ struct elf64_mb_link_hash_table *htab; -+ struct elf64_mb_link_hash_entry *eh; -+ struct elf64_mb_dyn_relocs *p; -+ -+ if (h->root.type == bfd_link_hash_indirect) -+ return TRUE; -+ -+ info = (struct bfd_link_info *) dat; -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ 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, bfd_link_pic (info), h)) -+ { -+ asection *s = htab->splt; -+ -+ /* The first entry in .plt is reserved. */ -+ 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 (! bfd_link_pic (info) -+ && !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->elf.sgotplt->size += 4; -+ -+ /* We also need to make an entry in the .rel.plt section. */ -+ htab->elf.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; -+ } -+ -+ eh = (struct elf64_mb_link_hash_entry *) h; -+ if (h->got.refcount > 0) -+ { -+ unsigned int need; -+ asection *s; -+ -+ /* 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; -+ } -+ -+ need = 0; -+ if ((eh->tls_mask & TLS_TLS) != 0) -+ { -+ /* Handle TLS Symbol */ -+ if ((eh->tls_mask & TLS_LD) != 0) -+ { -+ if (!eh->elf.def_dynamic) -+ /* We'll just use htab->tlsld_got.offset. This should -+ always be the case. It's a little odd if we have -+ a local dynamic reloc against a non-local symbol. */ -+ htab->tlsld_got.refcount += 1; -+ else -+ need += 8; -+ } -+ if ((eh->tls_mask & TLS_GD) != 0) -+ need += 8; -+ } -+ else -+ { -+ /* Regular (non-TLS) symbol */ -+ need += 4; -+ } -+ if (need == 0) -+ { -+ h->got.offset = (bfd_vma) -1; -+ } -+ else -+ { -+ s = htab->elf.sgot; -+ h->got.offset = s->size; -+ s->size += need; -+ htab->elf.srelgot->size += need * (sizeof (Elf64_External_Rela) / 4); -+ } -+ } -+ else -+ h->got.offset = (bfd_vma) -1; -+ -+ if (h->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 (bfd_link_pic (info)) -+ { -+ if (h->def_regular -+ && (h->forced_local -+ || info->symbolic)) -+ { -+ struct elf64_mb_dyn_relocs **pp; -+ -+ for (pp = &h->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; -+ } -+ } -+ else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) -+ h->dyn_relocs = NULL; -+ } -+ 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; -+ } -+ -+ h->dyn_relocs = NULL; -+ -+ keep: ; -+ } -+ -+ /* Finally, allocate space. */ -+ for (p = h->dyn_relocs; p != NULL; p = p->next) -+ { -+ asection *sreloc = elf_section_data (p->sec)->sreloc; -+ sreloc->size += p->count * sizeof (Elf64_External_Rela); -+ } -+ -+ return TRUE; -+} -+ -+/* Set the sizes of the dynamic sections. */ -+ -+static bfd_boolean -+microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ struct bfd_link_info *info) -+{ -+ struct elf64_mb_link_hash_table *htab; -+ bfd *dynobj; -+ asection *s; -+ bfd *ibfd; -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ dynobj = htab->elf.dynobj; -+ BFD_ASSERT (dynobj != NULL); -+ -+ /* 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 *lgot_masks; -+ asection *srel; -+ -+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) -+ continue; -+ -+ for (s = ibfd->sections; s != NULL; s = s->next) -+ { -+ struct elf64_mb_dyn_relocs *p; -+ -+ for (p = ((struct elf64_mb_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 (Elf64_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; -+ lgot_masks = (unsigned char *) end_local_got; -+ s = htab->elf.sgot; -+ srel = htab->elf.srelgot; -+ -+ for (; local_got < end_local_got; ++local_got, ++lgot_masks) -+ { -+ if (*local_got > 0) -+ { -+ unsigned int need = 0; -+ if ((*lgot_masks & TLS_TLS) != 0) -+ { -+ if ((*lgot_masks & TLS_GD) != 0) -+ need += 8; -+ if ((*lgot_masks & TLS_LD) != 0) -+ htab->tlsld_got.refcount += 1; -+ } -+ else -+ need += 4; -+ -+ if (need == 0) -+ { -+ *local_got = (bfd_vma) -1; -+ } -+ else -+ { -+ *local_got = s->size; -+ s->size += need; -+ if (bfd_link_pic (info)) -+ srel->size += need * (sizeof (Elf64_External_Rela) / 4); -+ } -+ } -+ else -+ *local_got = (bfd_vma) -1; -+ } -+ } -+ -+ /* Allocate global sym .plt and .got entries, and space for global -+ sym dynamic relocs. */ -+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info); -+ -+ if (htab->tlsld_got.refcount > 0) -+ { -+ htab->tlsld_got.offset = htab->elf.sgot->size; -+ htab->elf.sgot->size += 8; -+ if (bfd_link_pic (info)) -+ htab->elf.srelgot->size += sizeof (Elf64_External_Rela); -+ } -+ else -+ htab->tlsld_got.offset = (bfd_vma) -1; -+ -+ if (elf_hash_table (info)->dynamic_sections_created) -+ { -+ /* Make space for the trailing nop in .plt. */ -+ if (htab->elf.splt->size > 0) -+ htab->elf.splt->size += 4; -+ } -+ -+ /* 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) -+ { -+ const char *name; -+ bfd_boolean strip = FALSE; -+ -+ if ((s->flags & SEC_LINKER_CREATED) == 0) -+ continue; -+ -+ /* It's OK to base decisions on the section name, because none -+ of the dynobj section names depend upon the input files. */ -+ name = bfd_section_name (s); -+ -+ if (strncmp (name, ".rela", 5) == 0) -+ { -+ if (s->size == 0) -+ { -+ /* If we don't need this section, strip it from the -+ output file. This is to handle .rela.bss and -+ .rela.plt. We must create it in -+ create_dynamic_sections, because it 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. */ -+ strip = TRUE; -+ } -+ else -+ { -+ /* We use the reloc_count field as a counter if we need -+ to copy relocs into the output file. */ -+ s->reloc_count = 0; -+ } -+ } -+ else if (s != htab->elf.splt -+ && s != htab->elf.sgot -+ && s != htab->elf.sgotplt -+ && s != htab->elf.sdynbss -+ && s != htab->elf.sdynrelro) -+ { -+ /* It's not one of our sections, so don't allocate space. */ -+ continue; -+ } -+ -+ if (strip) -+ { -+ s->flags |= SEC_EXCLUDE; -+ continue; -+ } -+ -+ /* Allocate memory for the section contents. */ -+ /* 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 && s->size != 0) -+ return FALSE; -+ } -+ -+ if (elf_hash_table (info)->dynamic_sections_created) -+ { -+ /* Add some entries to the .dynamic section. We fill in the -+ values later, in microblaze_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 (bfd_link_executable (info)) -+ { -+ if (!add_dynamic_entry (DT_DEBUG, 0)) -+ return FALSE; -+ } -+ -+ if (!add_dynamic_entry (DT_RELA, 0) -+ || !add_dynamic_entry (DT_RELASZ, 0) -+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) -+ 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) -+ || !add_dynamic_entry (DT_BIND_NOW, 1)) -+ return FALSE; -+ } -+ -+ if (info->flags & DF_TEXTREL) -+ { -+ if (!add_dynamic_entry (DT_TEXTREL, 0)) -+ return FALSE; -+ } -+ } -+#undef add_dynamic_entry -+ return TRUE; -+} -+ -+/* Finish up dynamic symbol handling. We set the contents of various -+ dynamic sections here. */ -+ -+static bfd_boolean -+microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, -+ struct bfd_link_info *info, -+ struct elf_link_hash_entry *h, -+ Elf_Internal_Sym *sym) -+{ -+ struct elf64_mb_link_hash_table *htab; -+ struct elf64_mb_link_hash_entry *eh = elf64_mb_hash_entry(h); -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ if (h->plt.offset != (bfd_vma) -1) -+ { -+ asection *splt; -+ asection *srela; -+ asection *sgotplt; -+ Elf_Internal_Rela rela; -+ bfd_byte *loc; -+ bfd_vma plt_index; -+ bfd_vma got_offset; -+ bfd_vma got_addr; -+ -+ /* This symbol has an entry in the procedure linkage table. Set -+ it up. */ -+ BFD_ASSERT (h->dynindx != -1); -+ -+ splt = htab->splt; -+ srela = htab->srelplt; -+ sgotplt = htab->sgotplt; -+ BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL); -+ -+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */ -+ got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */ -+ got_addr = got_offset; -+ -+ /* For non-PIC objects we need absolute address of the GOT entry. */ -+ if (!bfd_link_pic (info)) -+ got_addr += sgotplt->output_section->vma + sgotplt->output_offset; -+ -+ /* Fill in the entry in the procedure linkage table. */ -+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff), -+ splt->contents + h->plt.offset); -+ if (bfd_link_pic (info)) -+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff), -+ splt->contents + h->plt.offset + 4); -+ else -+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff), -+ splt->contents + h->plt.offset + 4); -+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2, -+ splt->contents + h->plt.offset + 8); -+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3, -+ splt->contents + h->plt.offset + 12); -+ -+ /* Any additions to the .got section??? */ -+ /* bfd_put_32 (output_bfd, -+ splt->output_section->vma + splt->output_offset + h->plt.offset + 4, -+ sgotplt->contents + got_offset); */ -+ -+ /* Fill in the entry in the .rela.plt section. */ -+ rela.r_offset = (sgotplt->output_section->vma -+ + sgotplt->output_offset -+ + got_offset); -+ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT); -+ rela.r_addend = 0; -+ loc = srela->contents; -+ loc += plt_index * sizeof (Elf64_External_Rela); -+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); -+ -+ if (!h->def_regular) -+ { -+ /* Mark the symbol as undefined, rather than as defined in -+ the .plt section. Zero the value. */ -+ sym->st_shndx = SHN_UNDEF; -+ sym->st_value = 0; -+ } -+ } -+ -+ /* h->got.refcount to be checked ? */ -+ if (h->got.offset != (bfd_vma) -1 && -+ ! ((h->got.offset & 1) || -+ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask))) -+ { -+ asection *sgot; -+ asection *srela; -+ bfd_vma offset; -+ -+ /* This symbol has an entry in the global offset table. Set it -+ up. */ -+ -+ sgot = htab->elf.sgot; -+ srela = htab->elf.srelgot; -+ BFD_ASSERT (sgot != NULL && srela != NULL); -+ -+ offset = (sgot->output_section->vma + sgot->output_offset -+ + (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 (bfd_link_pic (info) -+ && ((info->symbolic && h->def_regular) -+ || h->dynindx == -1)) -+ { -+ asection *sec = h->root.u.def.section; -+ microblaze_elf_output_dynamic_relocation (output_bfd, -+ srela, srela->reloc_count++, -+ /* symindex= */ 0, -+ R_MICROBLAZE_REL, offset, -+ h->root.u.def.value -+ + sec->output_section->vma -+ + sec->output_offset); -+ } -+ else -+ { -+ microblaze_elf_output_dynamic_relocation (output_bfd, -+ srela, srela->reloc_count++, -+ h->dynindx, -+ R_MICROBLAZE_GLOB_DAT, -+ offset, 0); -+ } -+ -+ bfd_put_32 (output_bfd, (bfd_vma) 0, -+ sgot->contents + (h->got.offset &~ (bfd_vma) 1)); -+ } -+ -+ if (h->needs_copy) -+ { -+ asection *s; -+ Elf_Internal_Rela rela; -+ bfd_byte *loc; -+ -+ /* This symbols needs a copy reloc. Set it up. */ -+ -+ BFD_ASSERT (h->dynindx != -1); -+ -+ s = bfd_get_linker_section (htab->elf.dynobj, ".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 = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_COPY); -+ rela.r_addend = 0; -+ loc = s->contents + s->reloc_count++ * sizeof (Elf64_External_Rela); -+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); -+ } -+ -+ /* Mark some specially defined symbols as absolute. */ -+ if (h == htab->elf.hdynamic -+ || h == htab->elf.hgot -+ || h == htab->elf.hplt) -+ sym->st_shndx = SHN_ABS; -+ -+ return TRUE; -+} -+ -+ -+/* Finish up the dynamic sections. */ -+ -+static bfd_boolean -+microblaze_elf_finish_dynamic_sections (bfd *output_bfd, -+ struct bfd_link_info *info) -+{ -+ bfd *dynobj; -+ asection *sdyn, *sgot; -+ struct elf64_mb_link_hash_table *htab; -+ -+ htab = elf64_mb_hash_table (info); -+ if (htab == NULL) -+ return FALSE; -+ -+ dynobj = htab->elf.dynobj; -+ -+ sdyn = bfd_get_linker_section (dynobj, ".dynamic"); -+ -+ if (htab->elf.dynamic_sections_created) -+ { -+ asection *splt; -+ Elf64_External_Dyn *dyncon, *dynconend; -+ -+ splt = bfd_get_linker_section (dynobj, ".plt"); -+ BFD_ASSERT (splt != NULL && sdyn != NULL); -+ -+ dyncon = (Elf64_External_Dyn *) sdyn->contents; -+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); -+ for (; dyncon < dynconend; dyncon++) -+ { -+ Elf_Internal_Dyn dyn; -+ const char *name; -+ bfd_boolean size; -+ -+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); -+ -+ switch (dyn.d_tag) -+ { -+ case DT_PLTGOT: name = ".got.plt"; size = FALSE; break; -+ case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break; -+ case DT_JMPREL: name = ".rela.plt"; size = FALSE; break; -+ case DT_RELA: name = ".rela.dyn"; size = FALSE; break; -+ case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break; -+ default: name = NULL; size = FALSE; break; -+ } -+ -+ if (name != NULL) -+ { -+ asection *s; -+ -+ s = bfd_get_section_by_name (output_bfd, name); -+ if (s == NULL) -+ dyn.d_un.d_val = 0; -+ else -+ { -+ if (! size) -+ dyn.d_un.d_ptr = s->vma; -+ else -+ dyn.d_un.d_val = s->size; -+ } -+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); -+ } -+ } -+ -+ /* Clear the first entry in the procedure linkage table, -+ and put a nop in the last four bytes. */ -+ if (splt->size > 0) -+ { -+ memset (splt->contents, 0, PLT_ENTRY_SIZE); -+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */, -+ splt->contents + splt->size - 4); -+ } -+ -+ 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. */ -+ sgot = htab->elf.sgotplt; -+ 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->elf.sgot && htab->elf.sgot->size > 0) -+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4; -+ -+ return TRUE; -+} -+ -+/* Hook called by the linker routine which adds symbols from an object -+ file. We use it to put .comm items in .sbss, and not .bss. */ -+ -+static bfd_boolean -+microblaze_elf_add_symbol_hook (bfd *abfd, -+ struct bfd_link_info *info, -+ Elf_Internal_Sym *sym, -+ const char **namep ATTRIBUTE_UNUSED, -+ flagword *flagsp ATTRIBUTE_UNUSED, -+ asection **secp, -+ bfd_vma *valp) -+{ -+ if (sym->st_shndx == SHN_COMMON -+ && !bfd_link_relocatable (info) -+ && sym->st_size <= elf_gp_size (abfd)) -+ { -+ /* Common symbols less than or equal to -G nn bytes are automatically -+ put into .sbss. */ -+ *secp = bfd_make_section_old_way (abfd, ".sbss"); -+ if (*secp == NULL -+ || !bfd_set_section_flags (*secp, SEC_IS_COMMON)) -+ return FALSE; -+ -+ *valp = sym->st_size; -+ } -+ -+ return TRUE; -+} -+ -+#define TARGET_LITTLE_SYM microblaze_elf64_le_vec -+#define TARGET_LITTLE_NAME "elf64-microblazeel" -+ -+#define TARGET_BIG_SYM microblaze_elf64_vec -+#define TARGET_BIG_NAME "elf64-microblaze" -+ -+#define ELF_ARCH bfd_arch_microblaze -+#define ELF_TARGET_ID MICROBLAZE_ELF_DATA -+#define ELF_MACHINE_CODE EM_MICROBLAZE -+#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD -+#define ELF_MAXPAGESIZE 0x1000 -+#define elf_info_to_howto microblaze_elf_info_to_howto -+#define elf_info_to_howto_rel NULL -+ -+#define bfd_elf64_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup -+#define bfd_elf64_bfd_is_local_label_name microblaze_elf_is_local_label_name -+#define elf_backend_relocate_section microblaze_elf_relocate_section -+#define bfd_elf64_bfd_relax_section microblaze_elf_relax_section -+#define bfd_elf64_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data -+#define bfd_elf64_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup -+ -+#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook -+#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook -+#define elf_backend_check_relocs microblaze_elf_check_relocs -+#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol -+#define bfd_elf64_bfd_link_hash_table_create microblaze_elf_link_hash_table_create -+#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_got_header_size 12 -+#define elf_backend_rela_normal 1 -+ -+#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol -+#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections -+#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections -+#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol -+#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections -+#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook -+ -+#include "elf64-target.h" -diff --git a/bfd/targets.c b/bfd/targets.c -index 0732c5e429..1ec226b2f4 100644 ---- a/bfd/targets.c -+++ b/bfd/targets.c -@@ -782,6 +782,8 @@ extern const bfd_target mep_elf32_le_vec; - extern const bfd_target metag_elf32_vec; - extern const bfd_target microblaze_elf32_vec; - extern const bfd_target microblaze_elf32_le_vec; -+extern const bfd_target microblaze_elf64_vec; -+extern const bfd_target microblaze_elf64_le_vec; - extern const bfd_target mips_ecoff_be_vec; - extern const bfd_target mips_ecoff_le_vec; - extern const bfd_target mips_ecoff_bele_vec; -@@ -1150,6 +1152,10 @@ static const bfd_target * const _bfd_target_vector[] = - - &metag_elf32_vec, - -+#ifdef BFD64 -+ µblaze_elf64_vec, -+ µblaze_elf64_le_vec, -+#endif - µblaze_elf32_vec, - - &mips_ecoff_be_vec, -diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c -index 5810a74a5f..ffbb843d33 100644 ---- a/gas/config/tc-microblaze.c -+++ b/gas/config/tc-microblaze.c -@@ -35,10 +35,13 @@ - #define streq(a,b) (strcmp (a, b) == 0) - #endif - -+static int microblaze_arch_size = 0; -+ - #define OPTION_EB (OPTION_MD_BASE + 0) - #define OPTION_EL (OPTION_MD_BASE + 1) - #define OPTION_LITTLE (OPTION_MD_BASE + 2) - #define OPTION_BIG (OPTION_MD_BASE + 3) -+#define OPTION_M64 (OPTION_MD_BASE + 4) - - void microblaze_generate_symbol (char *sym); - static bfd_boolean check_spl_reg (unsigned *); -@@ -773,6 +776,74 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max) - return new_pointer; - } - -+ static char * -+parse_imml (char * s, expressionS * e, long min, long max) -+{ -+ char *new_pointer; -+ char *atp; -+ int itype, ilen; -+ -+ ilen = 0; -+ -+ /* Find the start of "@GOT" or "@PLT" suffix (if any) */ -+ for (atp = s; *atp != '@'; atp++) -+ if (is_end_of_line[(unsigned char) *atp]) -+ break; -+ -+ if (*atp == '@') -+ { -+ itype = match_imm (atp + 1, &ilen); -+ if (itype != 0) -+ { -+ *atp = 0; -+ e->X_md = itype; -+ } -+ else -+ { -+ atp = NULL; -+ e->X_md = 0; -+ ilen = 0; -+ } -+ *atp = 0; -+ } -+ else -+ { -+ atp = NULL; -+ e->X_md = 0; -+ } -+ -+ if (atp && !GOT_symbol) -+ { -+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); -+ } -+ -+ new_pointer = parse_exp (s, e); -+ -+ if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20)) -+ { -+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); -+ } -+ -+ if (e->X_op == O_absent) -+ ; /* An error message has already been emitted. */ -+ else if ((e->X_op != O_constant && e->X_op != O_symbol) ) -+ as_fatal (_("operand must be a constant or a label")); -+ else if ((e->X_op == O_constant) && ((long) e->X_add_number < min -+ || (long) e->X_add_number > max)) -+ { -+ as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"), -+ min, max, (long) e->X_add_number); -+ } -+ -+ if (atp) -+ { -+ *atp = '@'; /* restore back (needed?) */ -+ if (new_pointer >= atp) -+ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */ -+ } -+ return new_pointer; -+} -+ - static char * - check_got (int * got_type, int * got_len) - { -@@ -920,6 +991,7 @@ md_assemble (char * str) - unsigned int immed, immed2, temp; - expressionS exp; - char name[20]; -+ long immedl; - - /* Drop leading whitespace. */ - while (ISSPACE (* str)) -@@ -1129,7 +1201,7 @@ md_assemble (char * str) - } - break; - -- case INST_TYPE_RD_R1_IMM5: -+ case INST_TYPE_RD_R1_IMMS: - if (strcmp (op_end, "")) - op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ - else -@@ -1163,16 +1235,22 @@ md_assemble (char * str) - immed = exp.X_add_number; - } - -- if (immed != (immed % 32)) -+ if ((immed != (immed % 32)) && -+ (opcode->instr == bslli || opcode->instr == bsrai || opcode->instr == bsrli)) - { - as_warn (_("Shift value > 32. using <value %% 32>")); - immed = immed % 32; - } -+ else if (immed != (immed % 64)) -+ { -+ as_warn (_("Shift value > 64. using <value %% 64>")); -+ immed = immed % 64; -+ } - inst |= (reg1 << RD_LOW) & RD_MASK; - inst |= (reg2 << RA_LOW) & RA_MASK; -- inst |= (immed << IMM_LOW) & IMM5_MASK; -+ inst |= (immed << IMM_LOW) & IMM6_MASK; - break; -- case INST_TYPE_RD_R1_IMM5_IMM5: -+ case INST_TYPE_RD_R1_IMMW_IMMS: - if (strcmp (op_end, "")) - op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ - else -@@ -1196,7 +1274,7 @@ md_assemble (char * str) - - /* Width immediate value. */ - if (strcmp (op_end, "")) -- op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH); -+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM); - else - as_fatal (_("Error in statement syntax")); - if (exp.X_op != O_constant) -@@ -1208,6 +1286,8 @@ md_assemble (char * str) - immed = exp.X_add_number; - if (opcode->instr == bsefi && immed > 31) - as_fatal (_("Width value must be less than 32")); -+ else if (opcode->instr == bslefi && immed > 63) -+ as_fatal (_("Width value must be less than 64")); - - /* Shift immediate value. */ - if (strcmp (op_end, "")) -@@ -1215,32 +1295,40 @@ md_assemble (char * str) - else - as_fatal (_("Error in statement syntax")); - if (exp.X_op != O_constant) -- { -+ { - as_warn (_("Symbol used as immediate shift value for bit field instruction")); - immed2 = 0; - } - else -- { -+ { - output = frag_more (isize); - immed2 = exp.X_add_number; -- } -- if (immed2 != (immed2 % 32)) -- { -- as_warn (_("Shift value greater than 32. using <value %% 32>")); -+ } -+ if ((immed2 != (immed2 % 32)) && (opcode->instr == bsefi || opcode->instr == bsifi)) -+ { -+ -+ as_warn (_("Shift value greater than 32. using <value %% 32>")); - immed2 = immed2 % 32; - } -+ else if (immed2 != (immed2 % 64)) -+ { -+ as_warn (_("Shift value greater than 64. using <value %% 64>")); -+ immed2 = immed2 % 64; -+ } - - /* Check combined value. */ -- if (immed + immed2 > 32) -+ if ((immed + immed2 > 32) && (opcode->instr == bsefi || opcode->instr == bsifi)) - as_fatal (_("Width value + shift value must not be greater than 32")); - -+ else if (immed + immed2 > 64) -+ as_fatal (_("Width value + shift value must not be greater than 64")); - inst |= (reg1 << RD_LOW) & RD_MASK; - inst |= (reg2 << RA_LOW) & RA_MASK; -- if (opcode->instr == bsefi) -- inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */ -+ if (opcode->instr == bsefi || opcode->instr == bslefi) -+ inst |= (immed & IMM6_MASK) << IMM_WIDTH_LOW; /* bsefi or bslefi */ - else -- inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */ -- inst |= (immed2 << IMM_LOW) & IMM5_MASK; -+ inst |= ((immed + immed2 - 1) & IMM6_MASK) << IMM_WIDTH_LOW; /* bsifi or bslifi */ -+ inst |= (immed2 << IMM_LOW) & IMM6_MASK; - break; - case INST_TYPE_R1_R2: - if (strcmp (op_end, "")) -@@ -1808,6 +1896,142 @@ md_assemble (char * str) - } - inst |= (immed << IMM_MBAR); - break; -+ /* For 64-bit instructions */ -+ case INST_TYPE_RD_R1_IMML: -+ if (strcmp (op_end, "")) -+ op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ -+ else -+ { -+ as_fatal (_("Error in statement syntax")); -+ reg1 = 0; -+ } -+ if (strcmp (op_end, "")) -+ op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ -+ else -+ { -+ as_fatal (_("Error in statement syntax")); -+ reg2 = 0; -+ } -+ if (strcmp (op_end, "")) -+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML); -+ else -+ as_fatal (_("Error in statement syntax")); -+ -+ /* Check for spl registers. */ -+ if (check_spl_reg (& reg1)) -+ as_fatal (_("Cannot use special register with this instruction")); -+ if (check_spl_reg (& reg2)) -+ as_fatal (_("Cannot use special register with this instruction")); -+ -+ if (exp.X_op != O_constant) -+ { -+ char *opc = NULL; -+ relax_substateT subtype; -+ -+ if (exp.X_md != 0) -+ subtype = get_imm_otype(exp.X_md); -+ else -+ subtype = opcode->inst_offset_type; -+ -+ output = frag_var (rs_machine_dependent, -+ isize * 2, /* maxm of 2 words. */ -+ isize * 2, /* minm of 2 words. */ -+ subtype, /* PC-relative or not. */ -+ exp.X_add_symbol, -+ exp.X_add_number, -+ opc); -+ immedl = 0L; -+ } -+ else -+ { -+ output = frag_more (isize); -+ immedl = exp.X_add_number; -+ -+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); -+ if (opcode1 == NULL) -+ { -+ as_bad (_("unknown opcode \"%s\""), "imml"); -+ return; -+ } -+ -+ inst1 = opcode1->bit_sequence; -+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; -+ output[0] = INST_BYTE0 (inst1); -+ output[1] = INST_BYTE1 (inst1); -+ output[2] = INST_BYTE2 (inst1); -+ output[3] = INST_BYTE3 (inst1); -+ output = frag_more (isize); -+ } -+ -+ inst |= (reg1 << RD_LOW) & RD_MASK; -+ inst |= (reg2 << RA_LOW) & RA_MASK; -+ inst |= (immedl << IMM_LOW) & IMM_MASK; -+ break; -+ -+ case INST_TYPE_R1_IMML: -+ if (strcmp (op_end, "")) -+ op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ -+ else -+ { -+ as_fatal (_("Error in statement syntax")); -+ reg1 = 0; -+ } -+ if (strcmp (op_end, "")) -+ op_end = parse_imml (op_end + 1, & exp, MIN_IMM, MAX_IMM); -+ else -+ as_fatal (_("Error in statement syntax")); -+ -+ /* Check for spl registers. */ -+ if (check_spl_reg (®1)) -+ as_fatal (_("Cannot use special register with this instruction")); -+ -+ if (exp.X_op != O_constant) -+ { -+ char *opc = NULL; -+ relax_substateT subtype; -+ -+ if (exp.X_md != 0) -+ subtype = get_imm_otype(exp.X_md); -+ else -+ subtype = opcode->inst_offset_type; -+ -+ output = frag_var (rs_machine_dependent, -+ isize * 2, /* maxm of 2 words. */ -+ isize * 2, /* minm of 2 words. */ -+ subtype, /* PC-relative or not. */ -+ exp.X_add_symbol, -+ exp.X_add_number, -+ opc); -+ immedl = 0L; -+ } -+ else -+ { -+ output = frag_more (isize); -+ immedl = exp.X_add_number; -+ -+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); -+ if (opcode1 == NULL) -+ { -+ as_bad (_("unknown opcode \"%s\""), "imml"); -+ return; -+ } -+ -+ inst1 = opcode1->bit_sequence; -+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; -+ output[0] = INST_BYTE0 (inst1); -+ output[1] = INST_BYTE1 (inst1); -+ output[2] = INST_BYTE2 (inst1); -+ output[3] = INST_BYTE3 (inst1); -+ output = frag_more (isize); -+ } -+ -+ inst |= (reg1 << RA_LOW) & RA_MASK; -+ inst |= (immedl << IMM_LOW) & IMM_MASK; -+ break; -+ -+ case INST_TYPE_IMML: -+ as_fatal (_("An IMML instruction should not be present in the .s file")); -+ break; - - default: - as_fatal (_("unimplemented opcode \"%s\""), name); -@@ -1915,6 +2139,7 @@ struct option md_longopts[] = - {"EL", no_argument, NULL, OPTION_EL}, - {"mlittle-endian", no_argument, NULL, OPTION_LITTLE}, - {"mbig-endian", no_argument, NULL, OPTION_BIG}, -+ {"m64", no_argument, NULL, OPTION_M64}, - { NULL, no_argument, NULL, 0} - }; - -@@ -2565,6 +2790,18 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) - return rel; - } - -+/* Called by TARGET_FORMAT. */ -+const char * -+microblaze_target_format (void) -+{ -+ -+ if (microblaze_arch_size == 64) -+ return "elf64-microblazeel"; -+ else -+ return target_big_endian ? "elf32-microblaze" : "elf32-microblazeel"; -+} -+ -+ - int - md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) - { -@@ -2578,6 +2815,10 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) - case OPTION_LITTLE: - target_big_endian = 0; - break; -+ case OPTION_M64: -+ //if (arg != NULL && strcmp (arg, "64") == 0) -+ microblaze_arch_size = 64; -+ break; - default: - return 0; - } -@@ -2593,6 +2834,7 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED) - fprintf (stream, _(" MicroBlaze specific assembler options:\n")); - fprintf (stream, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu")); - fprintf (stream, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu")); -+ fprintf (stream, " -%-23s%s\n", "m64", N_("generate 64-bit elf")); - } - - -diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h -index 01cb3e894f..7435a70ef5 100644 ---- a/gas/config/tc-microblaze.h -+++ b/gas/config/tc-microblaze.h -@@ -78,7 +78,9 @@ extern const struct relax_type md_relax_table[]; - - #ifdef OBJ_ELF - --#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel") -+#define TARGET_FORMAT microblaze_target_format() -+extern const char *microblaze_target_format (void); -+//#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel") - - #define ELF_TC_SPECIAL_SECTIONS \ - { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \ -diff --git a/include/elf/common.h b/include/elf/common.h -index 4d94c4fd5b..f709a01816 100644 ---- a/include/elf/common.h -+++ b/include/elf/common.h -@@ -340,6 +340,7 @@ - #define EM_RISCV 243 /* RISC-V */ - #define EM_LANAI 244 /* Lanai 32-bit processor. */ - #define EM_BPF 247 /* Linux BPF – in-kernel virtual machine. */ -+#define EM_MB_64 248 /* Xilinx MicroBlaze 32-bit RISC soft processor core */ - #define EM_NFP 250 /* Netronome Flow Processor. */ - #define EM_CSKY 252 /* C-SKY processor family. */ - -diff --git a/ld/Makefile.am b/ld/Makefile.am -index 02c4fc1639..d063e2d32c 100644 ---- a/ld/Makefile.am -+++ b/ld/Makefile.am -@@ -416,6 +416,8 @@ ALL_64_EMULATION_SOURCES = \ - eelf32ltsmipn32.c \ - eelf32ltsmipn32_fbsd.c \ - eelf32mipswindiss.c \ -+ eelf64microblazeel.c \ -+ eelf64microblaze.c \ - eelf64_aix.c \ - eelf64bpf.c \ - eelf64_ia64.c \ -@@ -898,6 +900,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Pc@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblazeel.Pc@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblaze.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Pc@am__quote@ -diff --git a/ld/Makefile.in b/ld/Makefile.in -index 2fe12e14f6..797212859f 100644 ---- a/ld/Makefile.in -+++ b/ld/Makefile.in -@@ -898,6 +898,8 @@ ALL_64_EMULATION_SOURCES = \ - eelf32ltsmipn32.c \ - eelf32ltsmipn32_fbsd.c \ - eelf32mipswindiss.c \ -+ eelf64microblazeel.c \ -+ eelf64microblaze.c \ - eelf64_aix.c \ - eelf64bpf.c \ - eelf64_ia64.c \ -@@ -1338,6 +1340,8 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblazeel.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblaze.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@ -@@ -2493,6 +2497,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Pc@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblazeel.Pc@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblaze.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Pc@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Pc@am__quote@ -diff --git a/ld/configure.tgt b/ld/configure.tgt -index 87c7d9a4ca..801d27c9e3 100644 ---- a/ld/configure.tgt -+++ b/ld/configure.tgt -@@ -469,6 +469,9 @@ microblaze*-linux*) targ_emul="elf32mb_linux" - microblazeel*) targ_emul=elf32microblazeel - targ_extra_emuls=elf32microblaze - ;; -+microblazeel64*) targ_emul=elf64microblazeel -+ targ_extra_emuls=elf64microblaze -+ ;; - microblaze*) targ_emul=elf32microblaze - targ_extra_emuls=elf32microblazeel - ;; -diff --git a/ld/emulparams/elf64microblaze.sh b/ld/emulparams/elf64microblaze.sh -new file mode 100644 -index 0000000000..9c7b0eb708 ---- /dev/null -+++ b/ld/emulparams/elf64microblaze.sh -@@ -0,0 +1,23 @@ -+SCRIPT_NAME=elfmicroblaze -+OUTPUT_FORMAT="elf64-microblazeel" -+#BIG_OUTPUT_FORMAT="elf64-microblaze" -+LITTLE_OUTPUT_FORMAT="elf64-microblazeel" -+#TEXT_START_ADDR=0 -+NONPAGED_TEXT_START_ADDR=0x28 -+ALIGNMENT=4 -+MAXPAGESIZE=4 -+ARCH=microblaze -+EMBEDDED=yes -+ -+NOP=0x80000000 -+ -+# Hmmm, there's got to be a better way. This sets the stack to the -+# top of the simulator memory (2^19 bytes). -+#PAGE_SIZE=0x1000 -+#DATA_ADDR=0x10000 -+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }' -+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@} -+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);' -+ -+TEMPLATE_NAME=elf32 -+#GENERATE_SHLIB_SCRIPT=yes -diff --git a/ld/emulparams/elf64microblazeel.sh b/ld/emulparams/elf64microblazeel.sh -new file mode 100644 -index 0000000000..9c7b0eb708 ---- /dev/null -+++ b/ld/emulparams/elf64microblazeel.sh -@@ -0,0 +1,23 @@ -+SCRIPT_NAME=elfmicroblaze -+OUTPUT_FORMAT="elf64-microblazeel" -+#BIG_OUTPUT_FORMAT="elf64-microblaze" -+LITTLE_OUTPUT_FORMAT="elf64-microblazeel" -+#TEXT_START_ADDR=0 -+NONPAGED_TEXT_START_ADDR=0x28 -+ALIGNMENT=4 -+MAXPAGESIZE=4 -+ARCH=microblaze -+EMBEDDED=yes -+ -+NOP=0x80000000 -+ -+# Hmmm, there's got to be a better way. This sets the stack to the -+# top of the simulator memory (2^19 bytes). -+#PAGE_SIZE=0x1000 -+#DATA_ADDR=0x10000 -+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }' -+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@} -+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);' -+ -+TEMPLATE_NAME=elf32 -+#GENERATE_SHLIB_SCRIPT=yes -diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c -index 315c6e9350..f643f2600d 100644 ---- a/opcodes/microblaze-dis.c -+++ b/opcodes/microblaze-dis.c -@@ -33,6 +33,7 @@ - #define get_field_r1(buf, instr) get_field (buf, instr, RA_MASK, RA_LOW) - #define get_field_r2(buf, instr) get_field (buf, instr, RB_MASK, RB_LOW) - #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW) -+#define get_int_field_imml(instr) ((instr & IMML_MASK) >> IMM_LOW) - #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW) - - #define NUM_STRBUFS 3 -@@ -73,11 +74,19 @@ get_field_imm (struct string_buf *buf, long instr) - } - - static char * --get_field_imm5 (struct string_buf *buf, long instr) -+get_field_imml (struct string_buf *buf, long instr) - { - char *p = strbuf (buf); -+ sprintf (p, "%d", (short)((instr & IMML_MASK) >> IMM_LOW)); -+ return p; -+} - -- sprintf (p, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW)); -+static char * -+get_field_imms (struct string_buf *buf, long instr) -+{ -+ char *p = strbuf (buf); -+ -+ sprintf (p, "%d", (short)((instr & IMM6_MASK) >> IMM_LOW)); - return p; - } - -@@ -91,14 +100,14 @@ get_field_imm5_mbar (struct string_buf *buf, long instr) - } - - static char * --get_field_imm5width (struct string_buf *buf, long instr) -+get_field_immw (struct string_buf *buf, long instr) - { - char *p = strbuf (buf); - - if (instr & 0x00004000) -- sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */ -+ sprintf (p, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */ - else -- sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >> IMM_LOW) + 1)); /* bsifi */ -+ sprintf (p, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM6_MASK) >> IMM_LOW) + 1)); /* bsifi */ - return p; - } - -@@ -308,9 +317,13 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info) - } - } - break; -- case INST_TYPE_RD_R1_IMM5: -+ case INST_TYPE_RD_R1_IMML: -+ print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst), -+ get_field_r1 (&buf, inst), get_field_imm (&buf, inst)); -+ /* TODO: Also print symbol */ -+ case INST_TYPE_RD_R1_IMMS: - print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst), -- get_field_r1 (&buf, inst), get_field_imm5 (&buf, inst)); -+ get_field_r1(&buf, inst), get_field_imms (&buf, inst)); - break; - case INST_TYPE_RD_RFSL: - print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), -@@ -417,6 +430,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info) - case INST_TYPE_RD_R2: - print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), - get_field_r2 (&buf, inst)); -+ break; -+ case INST_TYPE_IMML: -+ print_func (stream, "\t%s", get_field_imml (&buf, inst)); -+ /* TODO: Also print symbol */ - break; - case INST_TYPE_R2: - print_func (stream, "\t%s", get_field_r2 (&buf, inst)); -@@ -440,8 +457,8 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info) - case INST_TYPE_NONE: - break; - /* For bit field insns. */ -- case INST_TYPE_RD_R1_IMM5_IMM5: -- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_imm5width (&buf, inst), get_field_imm5 (&buf, inst)); -+ case INST_TYPE_RD_R1_IMMW_IMMS: -+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_immw (&buf, inst), get_field_imms (&buf, inst)); - break; - /* For tuqula instruction */ - case INST_TYPE_RD: -diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h -index f61f4ef66d..61eaa39b3e 100644 ---- a/opcodes/microblaze-opc.h -+++ b/opcodes/microblaze-opc.h -@@ -40,7 +40,7 @@ - #define INST_TYPE_RD_SPECIAL 11 - #define INST_TYPE_R1 12 - /* New instn type for barrel shift imms. */ --#define INST_TYPE_RD_R1_IMM5 13 -+#define INST_TYPE_RD_R1_IMMS 13 - #define INST_TYPE_RD_RFSL 14 - #define INST_TYPE_R1_RFSL 15 - -@@ -60,7 +60,13 @@ - #define INST_TYPE_IMM5 20 - - /* For bsefi and bsifi */ --#define INST_TYPE_RD_R1_IMM5_IMM5 21 -+#define INST_TYPE_RD_R1_IMMW_IMMS 21 -+ -+/* For 64-bit instructions */ -+#define INST_TYPE_IMML 22 -+#define INST_TYPE_RD_R1_IMML 23 -+#define INST_TYPE_R1_IMML 24 -+#define INST_TYPE_RD_R1_IMMW_IMMS 21 - - #define INST_TYPE_NONE 25 - -@@ -91,13 +97,14 @@ - #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits. */ - #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits. */ - #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits. */ --#define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */ --#define OPCODE_MASK_H3B 0xFC00C600 /* High 6 bits and bits 16, 17, 21, 22. */ -+#define OPCODE_MASK_H3 0xFC000700 /* High 6 bits and bits 21, 22, 23. */ -+#define OPCODE_MASK_H3B 0xFC00E600 /* High 6 bits and bits 16, 17, 18, 21, 22. */ - #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */ --#define OPCODE_MASK_H32B 0xFC00C000 /* High 6 bits and bit 16, 17. */ -+#define OPCODE_MASK_H32B 0xFC00E000 /* High 6 bits and bit 16, 17, 18. */ - #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */ - #define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */ - #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */ -+#define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */ - - /* New Mask for msrset, msrclr insns. */ - #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */ -@@ -107,7 +114,7 @@ - #define DELAY_SLOT 1 - #define NO_DELAY_SLOT 0 - --#define MAX_OPCODES 301 -+#define MAX_OPCODES 412 - - struct op_code_struct - { -@@ -125,6 +132,7 @@ struct op_code_struct - /* More info about output format here. */ - } opcodes[MAX_OPCODES] = - { -+ /* 32-bit instructions */ - {"add", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst }, - {"rsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst }, - {"addc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst }, -@@ -161,11 +169,11 @@ struct op_code_struct - {"ncget", INST_TYPE_RD_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst }, - {"ncput", INST_TYPE_R1_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst }, - {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst }, -- {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst }, -- {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst }, -- {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst }, -- {"bsefi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst }, -- {"bsifi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst }, -+ {"bslli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst }, -+ {"bsrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst }, -+ {"bsrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst }, -+ {"bsefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst }, -+ {"bsifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst }, - {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst }, - {"and", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, microblaze_and, logical_inst }, - {"xor", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, microblaze_xor, logical_inst }, -@@ -425,6 +433,129 @@ struct op_code_struct - {"suspend", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBB020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 24. */ - {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst }, - {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst }, -+ -+ /* 64-bit instructions */ -+ {"addl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000100, OPCODE_MASK_H4, addl, arithmetic_inst }, -+ {"rsubl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000100, OPCODE_MASK_H4, rsubl, arithmetic_inst }, -+ {"addlc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000100, OPCODE_MASK_H4, addlc, arithmetic_inst }, -+ {"rsublc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000100, OPCODE_MASK_H4, rsublc, arithmetic_inst }, -+ {"addlk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000100, OPCODE_MASK_H4, addlk, arithmetic_inst }, -+ {"rsublk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000100, OPCODE_MASK_H4, rsublk, arithmetic_inst }, -+ {"addlkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000100, OPCODE_MASK_H4, addlkc, arithmetic_inst }, -+ {"rsublkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000100, OPCODE_MASK_H4, rsublkc, arithmetic_inst }, -+ {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst }, -+ {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst }, -+ {"addli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"rsubli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"addlic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"rsublic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"addlik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"rsublik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"addlikc", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"rsublikc",INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */ -+ {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst }, -+ {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst }, -+ {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst }, -+ {"bslrl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000100, OPCODE_MASK_H3, bslrl, barrel_shift_inst }, -+ {"bsllli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002400, OPCODE_MASK_H3B, bsllli, barrel_shift_inst }, -+ {"bslrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002200, OPCODE_MASK_H3B, bslrai, barrel_shift_inst }, -+ {"bslrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002000, OPCODE_MASK_H3B, bslrli, barrel_shift_inst }, -+ {"bslefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64006000, OPCODE_MASK_H32B, bslefi, barrel_shift_inst }, -+ {"bslifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6400a000, OPCODE_MASK_H32B, bslifi, barrel_shift_inst }, -+ {"orl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000100, OPCODE_MASK_H4, orl, logical_inst }, -+ {"andl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000100, OPCODE_MASK_H4, andl, logical_inst }, -+ {"xorl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000100, OPCODE_MASK_H4, xorl, logical_inst }, -+ {"andnl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000100, OPCODE_MASK_H4, andnl, logical_inst }, -+ {"pcmplbf", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000500, OPCODE_MASK_H4, pcmplbf, logical_inst }, -+ {"pcmpleq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000500, OPCODE_MASK_H4, pcmpleq, logical_inst }, -+ {"pcmplne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000500, OPCODE_MASK_H4, pcmplne, logical_inst }, -+ {"srla", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000101, OPCODE_MASK_H34, srla, logical_inst }, -+ {"srlc", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000121, OPCODE_MASK_H34, srlc, logical_inst }, -+ {"srll", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000141, OPCODE_MASK_H34, srll, logical_inst }, -+ {"sextl8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000160, OPCODE_MASK_H34, sextl8, logical_inst }, -+ {"sextl16", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000161, OPCODE_MASK_H34, sextl16, logical_inst }, -+ {"sextl32", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000162, OPCODE_MASK_H34, sextl32, logical_inst }, -+ {"brea", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98010000, OPCODE_MASK_H124, brea, branch_inst }, -+ {"bread", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98110000, OPCODE_MASK_H124, bread, branch_inst }, -+ {"breald", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98150000, OPCODE_MASK_H24, breald, branch_inst }, -+ {"beaeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000000, OPCODE_MASK_H14, beaeq, branch_inst }, -+ {"bealeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000100, OPCODE_MASK_H14, bealeq, branch_inst }, -+ {"beaeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000000, OPCODE_MASK_H14, beaeqd, branch_inst }, -+ {"bealeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000100, OPCODE_MASK_H14, bealeqd, branch_inst }, -+ {"beane", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200000, OPCODE_MASK_H14, beane, branch_inst }, -+ {"bealne", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200100, OPCODE_MASK_H14, bealne, branch_inst }, -+ {"beaned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200000, OPCODE_MASK_H14, beaned, branch_inst }, -+ {"bealned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200100, OPCODE_MASK_H14, bealned, branch_inst }, -+ {"bealt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400000, OPCODE_MASK_H14, bealt, branch_inst }, -+ {"beallt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400100, OPCODE_MASK_H14, beallt, branch_inst }, -+ {"bealtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400000, OPCODE_MASK_H14, bealtd, branch_inst }, -+ {"bealltd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400100, OPCODE_MASK_H14, bealltd, branch_inst }, -+ {"beale", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600000, OPCODE_MASK_H14, beale, branch_inst }, -+ {"bealle", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600100, OPCODE_MASK_H14, bealle, branch_inst }, -+ {"bealed", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600000, OPCODE_MASK_H14, bealed, branch_inst }, -+ {"bealled", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600100, OPCODE_MASK_H14, bealled, branch_inst }, -+ {"beagt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800000, OPCODE_MASK_H14, beagt, branch_inst }, -+ {"bealgt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800100, OPCODE_MASK_H14, bealgt, branch_inst }, -+ {"beagtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800000, OPCODE_MASK_H14, beagtd, branch_inst }, -+ {"bealgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800100, OPCODE_MASK_H14, bealgtd, branch_inst }, -+ {"beage", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00000, OPCODE_MASK_H14, beage, branch_inst }, -+ {"bealge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00100, OPCODE_MASK_H14, bealge, branch_inst }, -+ {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst }, -+ {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst }, -+ {"orli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */ -+ {"andli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */ -+ {"xorli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */ -+ {"andnli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */ -+ {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst }, -+ {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst }, -+ {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst }, -+ {"brealid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8150000, OPCODE_MASK_H2, brealid, branch_inst }, -+ {"beaeqi", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, beaeqi, branch_inst }, -+ {"bealeqi", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqi */ -+ {"beaeqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, beaeqid, branch_inst }, -+ {"bealeqid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqid */ -+ {"beanei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, beanei, branch_inst }, -+ {"bealnei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beanei */ -+ {"beaneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, beaneid, branch_inst }, -+ {"bealneid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaneid */ -+ {"bealti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, bealti, branch_inst }, -+ {"beallti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealti */ -+ {"bealtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, bealtid, branch_inst }, -+ {"bealltid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealtid */ -+ {"bealei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, bealei, branch_inst }, -+ {"beallei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealei */ -+ {"bealeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, bealeid, branch_inst }, -+ {"bealleid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealeid */ -+ {"beagti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, beagti, branch_inst }, -+ {"bealgti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagti */ -+ {"beagtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, beagtid, branch_inst }, -+ {"bealgtid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagtid */ -+ {"beagei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, beagei, branch_inst }, -+ {"bealgei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagei */ -+ {"beageid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, beageid, branch_inst }, -+ {"bealgeid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beageid */ -+ {"ll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000100, OPCODE_MASK_H4, ll, memory_load_inst }, -+ {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst }, -+ {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst }, -+ {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst }, -+ {"lli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */ -+ {"sli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */ -+ {"lla", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* lla translates to addlik */ -+ {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst }, -+ {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst }, -+ {"dmul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000500, OPCODE_MASK_H4, dmul, arithmetic_inst }, -+ {"ddiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000580, OPCODE_MASK_H4, ddiv, arithmetic_inst }, -+ {"dcmp.lt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000610, OPCODE_MASK_H4, dcmp_lt, arithmetic_inst }, -+ {"dcmp.eq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000620, OPCODE_MASK_H4, dcmp_eq, arithmetic_inst }, -+ {"dcmp.le", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000630, OPCODE_MASK_H4, dcmp_le, arithmetic_inst }, -+ {"dcmp.gt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000640, OPCODE_MASK_H4, dcmp_gt, arithmetic_inst }, -+ {"dcmp.ne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000650, OPCODE_MASK_H4, dcmp_ne, arithmetic_inst }, -+ {"dcmp.ge", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000660, OPCODE_MASK_H4, dcmp_ge, arithmetic_inst }, -+ {"dcmp.un", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000600, OPCODE_MASK_H4, dcmp_un, arithmetic_inst }, -+ {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst }, -+ {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst }, -+ {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst }, -+ - {"", 0, 0, 0, 0, 0, 0, 0, 0}, - }; - -@@ -445,8 +576,17 @@ char pvr_register_prefix[] = "rpvr"; - #define MIN_IMM5 ((int) 0x00000000) - #define MAX_IMM5 ((int) 0x0000001f) - -+#define MIN_IMM6 ((int) 0x00000000) -+#define MAX_IMM6 ((int) 0x0000003f) -+ - #define MIN_IMM_WIDTH ((int) 0x00000001) - #define MAX_IMM_WIDTH ((int) 0x00000020) - -+#define MIN_IMM6_WIDTH ((int) 0x00000001) -+#define MAX_IMM6_WIDTH ((int) 0x00000040) -+ -+#define MIN_IMML ((long) 0xffffff8000000000L) -+#define MAX_IMML ((long) 0x0000007fffffffffL) -+ - #endif /* MICROBLAZE_OPC */ - -diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h -index fa921c90c9..1dcd3dca3d 100644 ---- a/opcodes/microblaze-opcm.h -+++ b/opcodes/microblaze-opcm.h -@@ -25,6 +25,7 @@ - - enum microblaze_instr - { -+ /* 32-bit instructions */ - add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu, - addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul, - mulh, mulhu, mulhsu,swapb,swaph, -@@ -58,6 +59,18 @@ enum microblaze_instr - aputd, taputd, caputd, tcaputd, naputd, tnaputd, ncaputd, tncaputd, - eagetd, teagetd, ecagetd, tecagetd, neagetd, tneagetd, necagetd, tnecagetd, - eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd, -+ -+ /* 64-bit instructions */ -+ addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull, -+ bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl, -+ andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32, -+ brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned, -+ bealned, bealt, beallt, bealtd, bealltd, beale, bealle, bealed, bealled, beagt, -+ bealgt, beagtd, bealgtd, beage, bealge, beaged, bealged, breai, breaid, brealid, -+ beaeqi, beaeqid, beanei, beaneid, bealti, bealtid, bealei, bealeid, beagti, -+ beagtid, beagei, beageid, imml, ll, llr, sl, slr, -+ dadd, drsub, dmul, ddiv, dcmp_lt, dcmp_eq, dcmp_le, dcmp_gt, dcmp_ne, dcmp_ge, -+ dcmp_un, dbl, dlong, dsqrt, - invalid_inst - }; - -@@ -135,15 +148,18 @@ enum microblaze_instr_type - #define RA_MASK 0x001F0000 - #define RB_MASK 0x0000F800 - #define IMM_MASK 0x0000FFFF -+#define IMML_MASK 0x00FFFFFF - --/* Imm mask for barrel shifts. */ -+/* Imm masks for barrel shifts. */ - #define IMM5_MASK 0x0000001F -+#define IMM6_MASK 0x0000003F - - /* Imm mask for mbar. */ - #define IMM5_MBAR_MASK 0x03E00000 - --/* Imm mask for extract/insert width. */ -+/* Imm masks for extract/insert width. */ - #define IMM5_WIDTH_MASK 0x000007C0 -+#define IMM6_WIDTH_MASK 0x00000FC0 - - /* FSL imm mask for get, put instructions. */ - #define RFSL_MASK 0x000000F --- -2.17.1 - |