Also update patches as necessary. Change-Id: I1e8074954d5d7a4eff590abb7439e9be7d3762aa Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: https://review.coreboot.org/25997 Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
25741 lines
861 KiB
Diff
25741 lines
861 KiB
Diff
diff --git binutils-2.30/bfd/bfd-in2.h binutils-2.30-nds32/bfd/bfd-in2.h
|
||
index f4b3720b4b..49ac0a3a18 100644
|
||
--- binutils-2.30/bfd/bfd-in2.h
|
||
+++ binutils-2.30-nds32/bfd/bfd-in2.h
|
||
@@ -4137,6 +4137,9 @@ and shift left by 1 for use in lhi.gp, shi.gp... */
|
||
and shift left by 0 for use in lbi.gp, sbi.gp... */
|
||
BFD_RELOC_NDS32_SDA19S0,
|
||
|
||
+/* This is a 24-bit reloc for security check sum. */
|
||
+ BFD_RELOC_NDS32_SECURITY_16,
|
||
+
|
||
/* for PIC */
|
||
BFD_RELOC_NDS32_GOT20,
|
||
BFD_RELOC_NDS32_9_PLTREL,
|
||
@@ -4248,18 +4251,43 @@ This is a 5 bit absolute address. */
|
||
|
||
/* For TLS. */
|
||
BFD_RELOC_NDS32_TPOFF,
|
||
+ BFD_RELOC_NDS32_GOTTPOFF,
|
||
BFD_RELOC_NDS32_TLS_LE_HI20,
|
||
BFD_RELOC_NDS32_TLS_LE_LO12,
|
||
- BFD_RELOC_NDS32_TLS_LE_ADD,
|
||
- BFD_RELOC_NDS32_TLS_LE_LS,
|
||
- BFD_RELOC_NDS32_GOTTPOFF,
|
||
- BFD_RELOC_NDS32_TLS_IE_HI20,
|
||
- BFD_RELOC_NDS32_TLS_IE_LO12S2,
|
||
- BFD_RELOC_NDS32_TLS_TPOFF,
|
||
BFD_RELOC_NDS32_TLS_LE_20,
|
||
BFD_RELOC_NDS32_TLS_LE_15S0,
|
||
BFD_RELOC_NDS32_TLS_LE_15S1,
|
||
BFD_RELOC_NDS32_TLS_LE_15S2,
|
||
+ BFD_RELOC_NDS32_TLS_LE_ADD,
|
||
+ BFD_RELOC_NDS32_TLS_LE_LS,
|
||
+ BFD_RELOC_NDS32_TLS_IE_HI20,
|
||
+ BFD_RELOC_NDS32_TLS_IE_LO12,
|
||
+ BFD_RELOC_NDS32_TLS_IE_LO12S2,
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_HI20,
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LO12,
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LO12S2,
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LW,
|
||
+ BFD_RELOC_NDS32_TLS_DESC,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_HI20,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_LO12,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_20,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_SDA17S2,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_ADD,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_FUNC,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_CALL,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_MEM,
|
||
+ BFD_RELOC_NDS32_REMOVE,
|
||
+ BFD_RELOC_NDS32_GROUP,
|
||
+
|
||
+/* Jump-patch table relative relocations. */
|
||
+ BFD_RELOC_NDS32_ICT,
|
||
+ BFD_RELOC_NDS32_ICT_HI20,
|
||
+ BFD_RELOC_NDS32_ICT_LO12,
|
||
+ BFD_RELOC_NDS32_ICT_25PC,
|
||
+ BFD_RELOC_NDS32_ICT_LO12S2,
|
||
+
|
||
+/* For bug 12566. */
|
||
+ BFD_RELOC_NDS32_LSI,
|
||
|
||
/* This is a 9-bit reloc */
|
||
BFD_RELOC_V850_9_PCREL,
|
||
diff --git binutils-2.30/bfd/config.bfd binutils-2.30-nds32/bfd/config.bfd
|
||
index f04a993f06..9aa2fc63a8 100644
|
||
--- binutils-2.30/bfd/config.bfd
|
||
+++ binutils-2.30-nds32/bfd/config.bfd
|
||
@@ -1260,11 +1260,13 @@ case "${targ}" in
|
||
nds32*le-*-linux*)
|
||
targ_defvec=nds32_elf32_linux_le_vec
|
||
targ_selvecs=nds32_elf32_linux_be_vec
|
||
+ targ_cflags=-DNDS32_LINUX_TOOLCHAIN
|
||
;;
|
||
|
||
nds32*be-*-linux*)
|
||
targ_defvec=nds32_elf32_linux_be_vec
|
||
targ_selvecs=nds32_elf32_linux_le_vec
|
||
+ targ_cflags=-DNDS32_LINUX_TOOLCHAIN
|
||
;;
|
||
|
||
nds32*le-*-*)
|
||
diff --git binutils-2.30/bfd/elf32-nds32.c binutils-2.30-nds32/bfd/elf32-nds32.c
|
||
index 5ceb0a0b26..06be7a24bd 100644
|
||
--- binutils-2.30/bfd/elf32-nds32.c
|
||
+++ binutils-2.30-nds32/bfd/elf32-nds32.c
|
||
@@ -20,6 +20,8 @@
|
||
02110-1301, USA. */
|
||
|
||
|
||
+#pragma GCC diagnostic ignored "-Wstack-usage="
|
||
+
|
||
#include "sysdep.h"
|
||
#include "bfd.h"
|
||
#include "bfd_stdint.h"
|
||
@@ -33,6 +35,7 @@
|
||
#include "elf32-nds32.h"
|
||
#include "opcode/cgen.h"
|
||
#include "../opcodes/nds32-opc.h"
|
||
+#include <dlfcn.h>
|
||
|
||
/* Relocation HOWTO functions. */
|
||
static bfd_reloc_status_type nds32_elf_ignore_reloc
|
||
@@ -56,36 +59,72 @@ static bfd_reloc_status_type nds32_elf_sda15_reloc
|
||
static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc
|
||
(bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
|
||
asection *, bfd_vma, bfd_vma);
|
||
+static void nds32_elf_relocate_hi20
|
||
+ (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
|
||
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup
|
||
+ (enum elf_nds32_reloc_type);
|
||
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||
+ (bfd *, bfd_reloc_code_real_type);
|
||
+
|
||
+/* Target hooks. */
|
||
+static void nds32_info_to_howto_rel
|
||
+ (bfd *, arelent *, Elf_Internal_Rela *);
|
||
+static void nds32_info_to_howto
|
||
+ (bfd *, arelent *, Elf_Internal_Rela *);
|
||
+static bfd_boolean nds32_elf_add_symbol_hook
|
||
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
|
||
+ flagword *, asection **, bfd_vma *);
|
||
+static bfd_boolean nds32_elf_relocate_section
|
||
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
|
||
+static bfd_boolean nds32_elf_object_p (bfd *);
|
||
+static void nds32_elf_final_write_processing (bfd *, bfd_boolean);
|
||
+static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword);
|
||
+static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, struct bfd_link_info *);
|
||
+static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *);
|
||
+static bfd_boolean nds32_elf_check_relocs
|
||
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
|
||
+static asection *nds32_elf_gc_mark_hook
|
||
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
|
||
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
|
||
+static bfd_boolean nds32_elf_adjust_dynamic_symbol
|
||
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
|
||
+static bfd_boolean nds32_elf_size_dynamic_sections
|
||
+ (bfd *, struct bfd_link_info *);
|
||
+static bfd_boolean nds32_elf_create_dynamic_sections
|
||
+ (bfd *, struct bfd_link_info *);
|
||
+static bfd_boolean nds32_elf_finish_dynamic_sections
|
||
+ (bfd *, struct bfd_link_info *info);
|
||
+static bfd_boolean nds32_elf_finish_dynamic_symbol
|
||
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
|
||
+ Elf_Internal_Sym *);
|
||
+static bfd_boolean nds32_elf_mkobject (bfd *);
|
||
|
||
/* Nds32 helper functions. */
|
||
+static bfd_reloc_status_type nds32_elf_final_sda_base
|
||
+ (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean);
|
||
+static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *);
|
||
+static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *);
|
||
+static Elf_Internal_Rela *find_relocs_at_address
|
||
+ (Elf_Internal_Rela *, Elf_Internal_Rela *,
|
||
+ Elf_Internal_Rela *, enum elf_nds32_reloc_type);
|
||
static bfd_vma calculate_memory_address
|
||
-(bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
|
||
+ (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
|
||
static int nds32_get_section_contents (bfd *, asection *,
|
||
bfd_byte **, bfd_boolean);
|
||
-static bfd_boolean nds32_elf_ex9_build_hash_table
|
||
-(bfd *, asection *, struct bfd_link_info *);
|
||
-static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *);
|
||
-static void nds32_elf_ex9_import_table (struct bfd_link_info *);
|
||
-static void nds32_elf_ex9_finish (struct bfd_link_info *);
|
||
-static void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *);
|
||
-static void nds32_elf_get_insn_with_reg
|
||
- (Elf_Internal_Rela *, uint32_t, uint32_t *);
|
||
static int nds32_get_local_syms (bfd *, asection *ATTRIBUTE_UNUSED,
|
||
Elf_Internal_Sym **);
|
||
-static bfd_boolean nds32_elf_ex9_replace_instruction
|
||
- (struct bfd_link_info *, bfd *, asection *);
|
||
-static bfd_boolean nds32_elf_ifc_calc (struct bfd_link_info *, bfd *,
|
||
- asection *);
|
||
-static bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *);
|
||
-static bfd_boolean nds32_elf_ifc_replace (struct bfd_link_info *);
|
||
-static bfd_boolean nds32_elf_ifc_reloc (void);
|
||
-static bfd_boolean nds32_relax_fp_as_gp
|
||
- (struct bfd_link_info *link_info, bfd *abfd, asection *sec,
|
||
- Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend,
|
||
- Elf_Internal_Sym *isymbuf);
|
||
+static bfd_boolean nds32_relax_fp_as_gp
|
||
+ (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
|
||
+ Elf_Internal_Rela *, Elf_Internal_Sym *);
|
||
static bfd_boolean nds32_fag_remove_unused_fpbase
|
||
- (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs,
|
||
- Elf_Internal_Rela *irelend);
|
||
+ (bfd *, asection *, Elf_Internal_Rela *, Elf_Internal_Rela *);
|
||
+static bfd_byte *nds32_elf_get_relocated_section_contents
|
||
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
|
||
+ bfd_boolean, asymbol **);
|
||
+static void nds32_elf_ict_hash_init (void);
|
||
+static void nds32_elf_ict_relocate (bfd *, struct bfd_link_info *);
|
||
+static asection* nds32_elf_get_target_section (struct bfd_link_info *, char *);
|
||
|
||
enum
|
||
{
|
||
@@ -95,13 +134,24 @@ enum
|
||
MACH_V3M = bfd_mach_n1h_v3m
|
||
};
|
||
|
||
+/* If ABI is set by the option --mabi, without
|
||
+ checking the ABI compatible. */
|
||
+static char *output_abi;
|
||
+
|
||
#define MIN(a, b) ((a) > (b) ? (b) : (a))
|
||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||
|
||
+/* True if insn is 4byte. */
|
||
+#define INSN_32BIT(insn) ((((insn) & 0x80000000) == 0 ? (TRUE) : (FALSE)))
|
||
+
|
||
/* The name of the dynamic interpreter. This is put in the .interp
|
||
section. */
|
||
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
|
||
|
||
+#define NDS32_GUARD_SEC_P(flags) ((flags) & SEC_ALLOC \
|
||
+ && (flags) & SEC_LOAD \
|
||
+ && (flags) & SEC_READONLY)
|
||
+
|
||
/* The nop opcode we use. */
|
||
#define NDS32_NOP32 0x40000009
|
||
#define NDS32_NOP16 0x9200
|
||
@@ -113,32 +163,32 @@ enum
|
||
/* The first entry in a procedure linkage table are reserved,
|
||
and the initial contents are unimportant (we zero them out).
|
||
Subsequent entries look like this. */
|
||
-#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */
|
||
-#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */
|
||
-#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */
|
||
-#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */
|
||
-#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */
|
||
+#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */
|
||
+#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */
|
||
+#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */
|
||
+#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */
|
||
+#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */
|
||
|
||
/* $ta is change to $r15 (from $r25). */
|
||
#define PLT0_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[1]@GOT) */
|
||
-#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */
|
||
-#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */
|
||
-#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */
|
||
-#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */
|
||
-#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */
|
||
-
|
||
-#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */
|
||
-#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */
|
||
-#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */
|
||
-#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */
|
||
-#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0. */
|
||
-
|
||
-#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */
|
||
-#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */
|
||
-#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */
|
||
-#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */
|
||
-#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */
|
||
-#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */
|
||
+#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */
|
||
+#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */
|
||
+#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */
|
||
+#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */
|
||
+#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */
|
||
+
|
||
+#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */
|
||
+#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */
|
||
+#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */
|
||
+#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */
|
||
+#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0 */
|
||
+
|
||
+#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */
|
||
+#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */
|
||
+#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */
|
||
+#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */
|
||
+#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */
|
||
+#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */
|
||
|
||
/* These are macros used to get the relocation accurate value. */
|
||
#define ACCURATE_8BIT_S1 (0x100)
|
||
@@ -160,10 +210,11 @@ enum
|
||
#define CONSERVATIVE_19BIT (0x40000 - 0x1000)
|
||
#define CONSERVATIVE_20BIT (0x80000 - 0x1000)
|
||
|
||
+#define NDS32_ICT_SECTION ".nds32.ict"
|
||
+
|
||
/* Size of small data/bss sections, used to calculate SDA_BASE. */
|
||
static long got_size = 0;
|
||
static int is_SDA_BASE_set = 0;
|
||
-static int is_ITB_BASE_set = 0;
|
||
|
||
/* Convert ELF-VER in eflags to string for debugging purpose. */
|
||
static const char *const nds32_elfver_strtab[] =
|
||
@@ -192,37 +243,108 @@ struct elf_nds32_pcrel_relocs_copied
|
||
bfd_size_type count;
|
||
};
|
||
|
||
+/* The sh linker needs to keep track of the number of relocs that it
|
||
+ decides to copy as dynamic relocs in check_relocs for each symbol.
|
||
+ This is so that it can later discard them if they are found to be
|
||
+ unnecessary. We store the information in a field extending the
|
||
+ regular ELF linker hash table. */
|
||
+
|
||
+struct elf_nds32_dyn_relocs
|
||
+{
|
||
+ struct elf_nds32_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;
|
||
+};
|
||
+
|
||
/* Nds32 ELF linker hash entry. */
|
||
|
||
+enum elf_nds32_tls_type
|
||
+{
|
||
+ GOT_UNKNOWN = (0),
|
||
+ GOT_NORMAL = (1 << 0),
|
||
+ GOT_TLS_LE = (1 << 1),
|
||
+ GOT_TLS_IE = (1 << 2),
|
||
+ GOT_TLS_IEGP = (1 << 3),
|
||
+ GOT_TLS_LD = (1 << 4),
|
||
+ GOT_TLS_GD = (1 << 5),
|
||
+ GOT_TLS_DESC = (1 << 6),
|
||
+};
|
||
+
|
||
struct elf_nds32_link_hash_entry
|
||
{
|
||
struct elf_link_hash_entry root;
|
||
|
||
/* Track dynamic relocs copied for this symbol. */
|
||
- struct elf_dyn_relocs *dyn_relocs;
|
||
+ struct elf_nds32_dyn_relocs *dyn_relocs;
|
||
|
||
/* For checking relocation type. */
|
||
-#define GOT_UNKNOWN 0
|
||
-#define GOT_NORMAL 1
|
||
-#define GOT_TLS_IE 2
|
||
- unsigned int tls_type;
|
||
+ enum elf_nds32_tls_type tls_type;
|
||
+
|
||
+ int offset_to_gp;
|
||
+
|
||
+ /* For saving function attribute indirect_call and entry address. */
|
||
+ bfd_boolean indirect_call;
|
||
};
|
||
|
||
/* Get the nds32 ELF linker hash table from a link_info structure. */
|
||
|
||
#define FP_BASE_NAME "_FP_BASE_"
|
||
static int check_start_export_sym = 0;
|
||
-static size_t ex9_relax_size = 0; /* Save ex9 predicted reducing size. */
|
||
+/* File for exporting indirect call table. */
|
||
+static FILE *ict_file = NULL;
|
||
+/* Save object ict model. */
|
||
+static unsigned int ict_model = 0;
|
||
+/* True if _INDIRECT_CALL_TABLE_BASE_ is defined. */
|
||
+static bfd_boolean ignore_indirect_call = FALSE;
|
||
+/* Be used to set ifc bit in elf header. */
|
||
+static bfd_boolean ifc_flag = FALSE;
|
||
+
|
||
+/* Rom-patch symbol hash table. */
|
||
+struct elf_nds32_ict_hash_entry
|
||
+{
|
||
+ struct bfd_hash_entry root;
|
||
+ struct elf_link_hash_entry *h;
|
||
+ unsigned int order;
|
||
+};
|
||
+
|
||
+/* Rom-patch hash table. */
|
||
+static struct bfd_hash_table indirect_call_table;
|
||
|
||
/* The offset for executable tls relaxation. */
|
||
#define TP_OFFSET 0x0
|
||
|
||
+typedef struct
|
||
+{
|
||
+ int min_id;
|
||
+ int max_id;
|
||
+ int count;
|
||
+ int bias;
|
||
+ int init;
|
||
+} elf32_nds32_relax_group_t;
|
||
+
|
||
struct elf_nds32_obj_tdata
|
||
{
|
||
struct elf_obj_tdata root;
|
||
|
||
/* tls_type for each local got entry. */
|
||
char *local_got_tls_type;
|
||
+
|
||
+ unsigned int hdr_size;
|
||
+
|
||
+ /* GOTPLT entries for TLS descriptors. */
|
||
+ bfd_vma *local_tlsdesc_gotent;
|
||
+
|
||
+ int* offset_to_gp;
|
||
+
|
||
+ /* for R_NDS32_RELAX_GROUP handling. */
|
||
+ elf32_nds32_relax_group_t relax_group;
|
||
};
|
||
|
||
#define elf_nds32_tdata(bfd) \
|
||
@@ -231,6 +353,12 @@ struct elf_nds32_obj_tdata
|
||
#define elf32_nds32_local_got_tls_type(bfd) \
|
||
(elf_nds32_tdata (bfd)->local_got_tls_type)
|
||
|
||
+#define elf32_nds32_local_gp_offset(bfd) \
|
||
+ (elf_nds32_tdata (bfd)->offset_to_gp)
|
||
+
|
||
+#define elf32_nds32_relax_group_ptr(bfd) \
|
||
+ &(elf_nds32_tdata (bfd)->relax_group)
|
||
+
|
||
#define elf32_nds32_hash_entry(ent) ((struct elf_nds32_link_hash_entry *)(ent))
|
||
|
||
static bfd_boolean
|
||
@@ -240,68 +368,75 @@ nds32_elf_mkobject (bfd *abfd)
|
||
NDS32_ELF_DATA);
|
||
}
|
||
|
||
+
|
||
/* Relocations used for relocation. */
|
||
-static reloc_howto_type nds32_elf_howto_table[] =
|
||
-{
|
||
+/* NOTE!
|
||
+ the index order must be the same with elf_nds32_reloc_type in
|
||
+ include/elf/nds32.h
|
||
+ */
|
||
+#define HOWTO2(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
||
+ [C] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC)
|
||
+
|
||
+static reloc_howto_type nds32_elf_howto_table[] = {
|
||
/* This reloc does nothing. */
|
||
- HOWTO (R_NDS32_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 */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_NONE", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0, /* src_mask */
|
||
- 0, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_NONE, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_NONE", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0, /* src_mask */
|
||
+ 0, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 16 bit absolute relocation. */
|
||
- HOWTO (R_NDS32_16, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- nds32_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_16", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_16, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ nds32_elf_generic_reloc,/* special_function */
|
||
+ "R_NDS32_16", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 32 bit absolute relocation. */
|
||
- HOWTO (R_NDS32_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 */
|
||
- nds32_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_32", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_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 */
|
||
+ nds32_elf_generic_reloc,/* special_function */
|
||
+ "R_NDS32_32", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 20 bit address. */
|
||
- HOWTO (R_NDS32_20, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_unsigned, /* complain_on_overflow */
|
||
- nds32_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_20, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_unsigned,/* complain_on_overflow */
|
||
+ nds32_elf_generic_reloc,/* special_function */
|
||
+ "R_NDS32_20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* An PC Relative 9-bit relocation, shifted by 2.
|
||
This reloc is complicated because relocations are relative to pc & -4.
|
||
@@ -311,1910 +446,2264 @@ static reloc_howto_type nds32_elf_howto_table[] =
|
||
Branch relaxing in the assembler can store the addend in the insn,
|
||
and if bfd_install_relocation gets called the addend may get added
|
||
again. */
|
||
- HOWTO (R_NDS32_9_PCREL, /* type */
|
||
- 1, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- nds32_elf_9_pcrel_reloc, /* special_function */
|
||
- "R_NDS32_9_PCREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xff, /* src_mask */
|
||
- 0xff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_9_PCREL, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ nds32_elf_9_pcrel_reloc,/* special_function */
|
||
+ "R_NDS32_9_PCREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xff, /* src_mask */
|
||
+ 0xff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 15 bit relocation, right shifted by 1. */
|
||
- HOWTO (R_NDS32_15_PCREL, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 14, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_15_PCREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x3fff, /* src_mask */
|
||
- 0x3fff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_15_PCREL, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 14, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_15_PCREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x3fff, /* src_mask */
|
||
+ 0x3fff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 17 bit relocation, right shifted by 1. */
|
||
- HOWTO (R_NDS32_17_PCREL, /* type */
|
||
- 1, /* 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_NDS32_17_PCREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_17_PCREL, /* type */
|
||
+ 1, /* 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_NDS32_17_PCREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 25 bit relocation, right shifted by 1. */
|
||
/* ??? It's not clear whether this should have partial_inplace set or not.
|
||
Branch relaxing in the assembler can store the addend in the insn,
|
||
and if bfd_install_relocation gets called the addend may get added
|
||
again. */
|
||
- HOWTO (R_NDS32_25_PCREL, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 24, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_25_PCREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffff, /* src_mask */
|
||
- 0xffffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_25_PCREL, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 24, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_25_PCREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffff, /* src_mask */
|
||
+ 0xffffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* High 20 bits of address when lower 12 is or'd in. */
|
||
- HOWTO (R_NDS32_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_hi20_reloc, /* special_function */
|
||
- "R_NDS32_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_hi20_reloc, /* special_function */
|
||
+ "R_NDS32_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S3, /* type */
|
||
- 3, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 9, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_lo12_reloc, /* special_function */
|
||
- "R_NDS32_LO12S3", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000001ff, /* src_mask */
|
||
- 0x000001ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S3, /* type */
|
||
+ 3, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 9, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_lo12_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S3", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000001ff, /* src_mask */
|
||
+ 0x000001ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S2, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 10, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_lo12_reloc, /* special_function */
|
||
- "R_NDS32_LO12S2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000003ff, /* src_mask */
|
||
- 0x000003ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S2, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_lo12_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S2", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S1, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 11, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_lo12_reloc, /* special_function */
|
||
- "R_NDS32_LO12S1", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000007ff, /* src_mask */
|
||
- 0x000007ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S1, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 11, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_lo12_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S1", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000007ff, /* src_mask */
|
||
+ 0x000007ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S0, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_lo12_reloc, /* special_function */
|
||
- "R_NDS32_LO12S0", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S0, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_lo12_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S0", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S3, /* type */
|
||
- 3, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- nds32_elf_sda15_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S3", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S3, /* type */
|
||
+ 3, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ nds32_elf_sda15_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S3", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S2, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- nds32_elf_sda15_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S2, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ nds32_elf_sda15_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S2", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S1, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- nds32_elf_sda15_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S1", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S1, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ nds32_elf_sda15_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S1", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S0, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- nds32_elf_sda15_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S0", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- /* GNU extension to record C++ vtable hierarchy */
|
||
- HOWTO (R_NDS32_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_NDS32_GNU_VTINHERIT", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0, /* src_mask */
|
||
- 0, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- /* GNU extension to record C++ vtable member usage */
|
||
- HOWTO (R_NDS32_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_NDS32_GNU_VTENTRY", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0, /* src_mask */
|
||
- 0, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S0, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ nds32_elf_sda15_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S0", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* GNU extension to record C++ vtable hierarchy */
|
||
+ HOWTO2 (R_NDS32_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_NDS32_GNU_VTINHERIT",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0, /* src_mask */
|
||
+ 0, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* GNU extension to record C++ vtable member usage */
|
||
+ HOWTO2 (R_NDS32_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_NDS32_GNU_VTENTRY", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0, /* src_mask */
|
||
+ 0, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 16 bit absolute relocation. */
|
||
- HOWTO (R_NDS32_16_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_16_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_16_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_16_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 32 bit absolute relocation. */
|
||
- HOWTO (R_NDS32_32_RELA, /* 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_NDS32_32_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_32_RELA, /* 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_NDS32_32_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A 20 bit address. */
|
||
- HOWTO (R_NDS32_20_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_20_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_9_PCREL_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_9_PCREL_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xff, /* src_mask */
|
||
- 0xff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_20_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_20_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_9_PCREL_RELA, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_9_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xff, /* src_mask */
|
||
+ 0xff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 15 bit relocation, right shifted by 1. */
|
||
- HOWTO (R_NDS32_15_PCREL_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 14, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_15_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x3fff, /* src_mask */
|
||
- 0x3fff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_15_PCREL_RELA,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 14, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_15_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x3fff, /* src_mask */
|
||
+ 0x3fff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 17 bit relocation, right shifted by 1. */
|
||
- HOWTO (R_NDS32_17_PCREL_RELA, /* type */
|
||
- 1, /* 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_NDS32_17_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_17_PCREL_RELA,/* type */
|
||
+ 1, /* 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_NDS32_17_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative 25 bit relocation, right shifted by 2. */
|
||
- HOWTO (R_NDS32_25_PCREL_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 24, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_25_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffff, /* src_mask */
|
||
- 0xffffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_25_PCREL_RELA,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 24, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_25_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffff, /* src_mask */
|
||
+ 0xffffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* High 20 bits of address when lower 16 is or'd in. */
|
||
- HOWTO (R_NDS32_HI20_RELA, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_HI20_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_HI20_RELA, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_HI20_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S3_RELA, /* type */
|
||
- 3, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 9, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S3_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000001ff, /* src_mask */
|
||
- 0x000001ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S3_RELA, /* type */
|
||
+ 3, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 9, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S3_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000001ff, /* src_mask */
|
||
+ 0x000001ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S2_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 10, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S2_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000003ff, /* src_mask */
|
||
- 0x000003ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S2_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S2_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S1_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 11, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S1_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000007ff, /* src_mask */
|
||
- 0x000007ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S1_RELA, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 11, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S1_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000007ff, /* src_mask */
|
||
+ 0x000007ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S0_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S0_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S0_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S0_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S3_RELA, /* type */
|
||
- 3, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S3_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S3_RELA, /* type */
|
||
+ 3, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S3_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA15S2_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S2_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_SDA15S1_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S1_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_SDA15S0_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA15S0_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- /* GNU extension to record C++ vtable hierarchy */
|
||
- HOWTO (R_NDS32_RELA_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_NDS32_RELA_GNU_VTINHERIT", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0, /* src_mask */
|
||
- 0, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- /* GNU extension to record C++ vtable member usage */
|
||
- HOWTO (R_NDS32_RELA_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_NDS32_RELA_GNU_VTENTRY", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0, /* src_mask */
|
||
- 0, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA15S2_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_SDA15S1_RELA, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S1_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_SDA15S0_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA15S0_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* GNU extension to record C++ vtable hierarchy */
|
||
+ HOWTO2 (R_NDS32_RELA_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_NDS32_RELA_GNU_VTINHERIT",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0, /* src_mask */
|
||
+ 0, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* GNU extension to record C++ vtable member usage */
|
||
+ HOWTO2 (R_NDS32_RELA_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_NDS32_RELA_GNU_VTENTRY",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0, /* src_mask */
|
||
+ 0, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Like R_NDS32_20, but referring to the GOT table entry for
|
||
the symbol. */
|
||
- HOWTO (R_NDS32_GOT20, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT20, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Like R_NDS32_PCREL, but referring to the procedure linkage table
|
||
entry for the symbol. */
|
||
- HOWTO (R_NDS32_25_PLTREL, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 24, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_25_PLTREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffff, /* src_mask */
|
||
- 0xffffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_25_PLTREL, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 24, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_25_PLTREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffff, /* src_mask */
|
||
+ 0xffffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* This is used only by the dynamic linker. The symbol should exist
|
||
both in the object being run and in some shared library. The
|
||
dynamic linker copies the data addressed by the symbol from the
|
||
shared library into the object, because the object being
|
||
run has to have the data at some particular address. */
|
||
- HOWTO (R_NDS32_COPY, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_COPY", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_COPY, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_COPY", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Like R_NDS32_20, but used when setting global offset table
|
||
entries. */
|
||
- HOWTO (R_NDS32_GLOB_DAT, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GLOB_DAT", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GLOB_DAT, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GLOB_DAT", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Marks a procedure linkage table entry for a symbol. */
|
||
- HOWTO (R_NDS32_JMP_SLOT, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_JMP_SLOT", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_JMP_SLOT, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_JMP_SLOT", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Used only by the dynamic linker. When the object is run, this
|
||
longword is set to the load address of the object, plus the
|
||
addend. */
|
||
- HOWTO (R_NDS32_RELATIVE, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_RELATIVE", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_GOTOFF, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTOFF", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_RELATIVE, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_RELATIVE", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_GOTOFF, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTOFF", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* An PC Relative 20-bit relocation used when setting PIC offset
|
||
table register. */
|
||
- HOWTO (R_NDS32_GOTPC20, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTPC20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTPC20, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTPC20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* Like R_NDS32_HI20, but referring to the GOT table entry for
|
||
the symbol. */
|
||
- HOWTO (R_NDS32_GOT_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOT_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* An PC Relative relocation used when setting PIC offset table register.
|
||
Like R_NDS32_HI20, but referring to the GOT table entry for
|
||
the symbol. */
|
||
- HOWTO (R_NDS32_GOTPC_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTPC_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOTPC_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTPC_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_GOTOFF_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTOFF_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOTOFF_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTOFF_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTPC_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTPC_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTPC_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTPC_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_GOTOFF_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTOFF_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTOFF_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTOFF_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Alignment hint for relaxable instruction. This is used with
|
||
R_NDS32_LABEL as a pair. Relax this instruction from 4 bytes to 2
|
||
in order to make next label aligned on word boundary. */
|
||
- HOWTO (R_NDS32_INSN16, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_INSN16", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_INSN16, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_INSN16", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Alignment hint for label. */
|
||
- HOWTO (R_NDS32_LABEL, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LABEL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LABEL, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LABEL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for unconditional call sequence */
|
||
- HOWTO (R_NDS32_LONGCALL1, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGCALL1", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL1, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL1", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional call sequence. */
|
||
- HOWTO (R_NDS32_LONGCALL2, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGCALL2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL2, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL2", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional call sequence. */
|
||
- HOWTO (R_NDS32_LONGCALL3, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGCALL3", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL3, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL3", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for unconditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP1, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGJUMP1", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP1, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP1", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP2, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGJUMP2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP2, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP2", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP3, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LONGJUMP3", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP3, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP3", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for load/store sequence. */
|
||
- HOWTO (R_NDS32_LOADSTORE, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_LOADSTORE", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LOADSTORE, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LOADSTORE", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for load/store sequence. */
|
||
- HOWTO (R_NDS32_9_FIXED_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_9_FIXED_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000000ff, /* src_mask */
|
||
- 0x000000ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_9_FIXED_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_9_FIXED_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000000ff, /* src_mask */
|
||
+ 0x000000ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for load/store sequence. */
|
||
- HOWTO (R_NDS32_15_FIXED_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_15_FIXED_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00003fff, /* src_mask */
|
||
- 0x00003fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_15_FIXED_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_15_FIXED_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00003fff, /* src_mask */
|
||
+ 0x00003fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for load/store sequence. */
|
||
- HOWTO (R_NDS32_17_FIXED_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_17_FIXED_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0000ffff, /* src_mask */
|
||
- 0x0000ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_17_FIXED_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_17_FIXED_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0000ffff, /* src_mask */
|
||
+ 0x0000ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for load/store sequence. */
|
||
- HOWTO (R_NDS32_25_FIXED_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_25_FIXED_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00ffffff, /* src_mask */
|
||
- 0x00ffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_25_FIXED_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_25_FIXED_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00ffffff, /* src_mask */
|
||
+ 0x00ffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* High 20 bits of PLT symbol offset relative to PC. */
|
||
- HOWTO (R_NDS32_PLTREL_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLTREL_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLTREL_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLTREL_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Low 12 bits of PLT symbol offset relative to PC. */
|
||
- HOWTO (R_NDS32_PLTREL_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLTREL_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLTREL_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLTREL_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* High 20 bits of PLT symbol offset relative to GOT (GP). */
|
||
- HOWTO (R_NDS32_PLT_GOTREL_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLT_GOTREL_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLT_GOTREL_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLT_GOTREL_HI20",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Low 12 bits of PLT symbol offset relative to GOT (GP). */
|
||
- HOWTO (R_NDS32_PLT_GOTREL_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLT_GOTREL_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLT_GOTREL_LO12,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLT_GOTREL_LO12",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 12 bits offset. */
|
||
- HOWTO (R_NDS32_SDA12S2_DP_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA12S2_DP_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA12S2_DP_RELA,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA12S2_DP_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 12 bits offset. */
|
||
- HOWTO (R_NDS32_SDA12S2_SP_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA12S2_SP_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA12S2_SP_RELA,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA12S2_SP_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* Lower 12 bits of address. */
|
||
|
||
- HOWTO (R_NDS32_LO12S2_DP_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 10, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S2_DP_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000003ff, /* src_mask */
|
||
- 0x000003ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S2_DP_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S2_DP_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Lower 12 bits of address. */
|
||
- HOWTO (R_NDS32_LO12S2_SP_RELA,/* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 10, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S2_SP_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000003ff, /* src_mask */
|
||
- 0x000003ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S2_SP_RELA,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S2_SP_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* Lower 12 bits of address. Special identity for or case. */
|
||
- HOWTO (R_NDS32_LO12S0_ORI_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_LO12S0_ORI_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LO12S0_ORI_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_LO12S0_ORI_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* Small data area 19 bits offset. */
|
||
- HOWTO (R_NDS32_SDA16S3_RELA, /* type */
|
||
- 3, /* 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_NDS32_SDA16S3_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0000ffff, /* src_mask */
|
||
- 0x0000ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA16S3_RELA, /* type */
|
||
+ 3, /* 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_NDS32_SDA16S3_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0000ffff, /* src_mask */
|
||
+ 0x0000ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Small data area 15 bits offset. */
|
||
- HOWTO (R_NDS32_SDA17S2_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 17, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA17S2_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0001ffff, /* src_mask */
|
||
- 0x0001ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_SDA18S1_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 18, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA18S1_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0003ffff, /* src_mask */
|
||
- 0x0003ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- HOWTO (R_NDS32_SDA19S0_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 19, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA19S0_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0007ffff, /* src_mask */
|
||
- 0x0007ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DWARF2_OP1_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DWARF2_OP1_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xff, /* src_mask */
|
||
- 0xff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DWARF2_OP2_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DWARF2_OP2_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DWARF2_LEB_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DWARF2_LEB_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_UPDATE_TA_RELA,/* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_UPDATE_TA_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA17S2_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 17, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA17S2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0001ffff, /* src_mask */
|
||
+ 0x0001ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_SDA18S1_RELA, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 18, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA18S1_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0003ffff, /* src_mask */
|
||
+ 0x0003ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_SDA19S0_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 19, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA19S0_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0007ffff, /* src_mask */
|
||
+ 0x0007ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_DWARF2_OP1_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DWARF2_OP1_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xff, /* src_mask */
|
||
+ 0xff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_DWARF2_OP2_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DWARF2_OP2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_DWARF2_LEB_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DWARF2_LEB_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_UPDATE_TA_RELA,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_UPDATE_TA_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* Like R_NDS32_PCREL, but referring to the procedure linkage table
|
||
entry for the symbol. */
|
||
- HOWTO (R_NDS32_9_PLTREL, /* type */
|
||
- 1, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_9_PLTREL", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xff, /* src_mask */
|
||
- 0xff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_9_PLTREL, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_9_PLTREL", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xff, /* src_mask */
|
||
+ 0xff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
/* Low 20 bits of PLT symbol offset relative to GOT (GP). */
|
||
- HOWTO (R_NDS32_PLT_GOTREL_LO20, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLT_GOTREL_LO20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- /* low 15 bits of PLT symbol offset relative to GOT (GP) */
|
||
- HOWTO (R_NDS32_PLT_GOTREL_LO15, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLT_GOTREL_LO15", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLT_GOTREL_LO20,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLT_GOTREL_LO20",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ /* low 15 bits of PLT symbol offset relative to GOT (GP) */
|
||
+ HOWTO2 (R_NDS32_PLT_GOTREL_LO15,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLT_GOTREL_LO15",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* Low 19 bits of PLT symbol offset relative to GOT (GP). */
|
||
- HOWTO (R_NDS32_PLT_GOTREL_LO19, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 19, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_PLT_GOTREL_LO19", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0007ffff, /* src_mask */
|
||
- 0x0007ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOT_LO15, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT_LO15", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOT_LO19, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 19, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT_LO19", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0007ffff, /* src_mask */
|
||
- 0x0007ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOTOFF_LO15, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTOFF_LO15", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOTOFF_LO19, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 19, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOTOFF_LO19", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0007ffff, /* src_mask */
|
||
- 0x0007ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_PLT_GOTREL_LO19,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 19, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_PLT_GOTREL_LO19",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0007ffff, /* src_mask */
|
||
+ 0x0007ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT_LO15, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT_LO15", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT_LO19, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 19, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT_LO19", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0007ffff, /* src_mask */
|
||
+ 0x0007ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTOFF_LO15, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTOFF_LO15", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOTOFF_LO19, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 19, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOTOFF_LO19", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0007ffff, /* src_mask */
|
||
+ 0x0007ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* GOT 15 bits offset. */
|
||
- HOWTO (R_NDS32_GOT15S2_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT15S2_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00007fff, /* src_mask */
|
||
- 0x00007fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT15S2_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT15S2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00007fff, /* src_mask */
|
||
+ 0x00007fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* GOT 17 bits offset. */
|
||
- HOWTO (R_NDS32_GOT17S2_RELA, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 17, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_GOT17S2_RELA",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0001ffff, /* src_mask */
|
||
- 0x0001ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_GOT17S2_RELA, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 17, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_GOT17S2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0001ffff, /* src_mask */
|
||
+ 0x0001ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
/* A 5 bit address. */
|
||
- HOWTO (R_NDS32_5_RELA, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 5, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_5_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x1f, /* src_mask */
|
||
- 0x1f, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_10_UPCREL_RELA,/* type */
|
||
- 1, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 9, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_unsigned, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_10_UPCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x1ff, /* src_mask */
|
||
- 0x1ff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_SDA_FP7U2_RELA,/* type */
|
||
- 2, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 7, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_unsigned, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_SDA_FP7U2_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0000007f, /* src_mask */
|
||
- 0x0000007f, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_WORD_9_PCREL_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_WORD_9_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xff, /* src_mask */
|
||
- 0xff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_25_ABS_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 24, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_25_ABS_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffff, /* src_mask */
|
||
- 0xffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_5_RELA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 5, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_5_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x1f, /* src_mask */
|
||
+ 0x1f, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_10_UPCREL_RELA,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 9, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_unsigned,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_10_UPCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x1ff, /* src_mask */
|
||
+ 0x1ff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_SDA_FP7U2_RELA,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 7, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_unsigned,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SDA_FP7U2_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0000007f, /* src_mask */
|
||
+ 0x0000007f, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_WORD_9_PCREL_RELA,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_WORD_9_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xff, /* src_mask */
|
||
+ 0xff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_25_ABS_RELA, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 24, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_25_ABS_RELA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffff, /* src_mask */
|
||
+ 0xffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* A relative 17 bit relocation for ifc, right shifted by 1. */
|
||
- HOWTO (R_NDS32_17IFC_PCREL_RELA, /* type */
|
||
- 1, /* 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_NDS32_17IFC_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffff, /* src_mask */
|
||
- 0xffff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_17IFC_PCREL_RELA,/* type */
|
||
+ 1, /* 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_NDS32_17IFC_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffff, /* src_mask */
|
||
+ 0xffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* A relative unsigned 10 bit relocation for ifc, right shifted by 1. */
|
||
- HOWTO (R_NDS32_10IFCU_PCREL_RELA, /* type */
|
||
- 1, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 9, /* bitsize */
|
||
- TRUE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_unsigned, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_10IFCU_PCREL_RELA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x1ff, /* src_mask */
|
||
- 0x1ff, /* dst_mask */
|
||
- TRUE), /* pcrel_offset */
|
||
-
|
||
- /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
|
||
- HOWTO (R_NDS32_TLS_LE_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_LO12, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 12, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_LO12", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x00000fff, /* src_mask */
|
||
- 0x00000fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
-
|
||
- /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
|
||
- HOWTO (R_NDS32_TLS_IE_HI20, /* type */
|
||
- 12, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_IE_HI20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000fffff, /* src_mask */
|
||
- 0x000fffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_IE_LO12S2, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 10, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_IE_LO12S2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000003ff, /* src_mask */
|
||
- 0x000003ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- /* Mark a TLS IE entry in GOT. */
|
||
- HOWTO (R_NDS32_TLS_TPOFF, /* 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_NDS32_TLS_TPOFF", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- /* A 20 bit address. */
|
||
- HOWTO (R_NDS32_TLS_LE_20, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 20, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_20", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xfffff, /* src_mask */
|
||
- 0xfffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_15S0, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_15S0", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x7fff, /* src_mask */
|
||
- 0x7fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_15S1, /* type */
|
||
- 1, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_15S1", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x7fff, /* src_mask */
|
||
- 0x7fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_15S2, /* type */
|
||
- 2, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 15, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_signed, /* complain_on_overflow */
|
||
- bfd_elf_generic_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_15S2", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x7fff, /* src_mask */
|
||
- 0x7fff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_10IFCU_PCREL_RELA,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 9, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_unsigned,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_10IFCU_PCREL_RELA",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x1ff, /* src_mask */
|
||
+ 0x1ff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
|
||
/* Relax hint for unconditional call sequence */
|
||
- HOWTO (R_NDS32_LONGCALL4, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGCALL4", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL4, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL4", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional call sequence. */
|
||
- HOWTO (R_NDS32_LONGCALL5, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGCALL5", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL5, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL5", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional call sequence. */
|
||
- HOWTO (R_NDS32_LONGCALL6, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGCALL6", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGCALL6, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGCALL6", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for unconditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP4, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGJUMP4", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP4, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP4", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP5, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGJUMP5", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP5, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP5", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP6, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGJUMP6", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP6, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP6", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
|
||
/* Relax hint for conditional branch sequence. */
|
||
- HOWTO (R_NDS32_LONGJUMP7, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_LONGJUMP7", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_LONGJUMP7, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LONGJUMP7", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* Check sum value for security. */
|
||
+ HOWTO2 (R_NDS32_SECURITY_16, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 5, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_SECURITY_16", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x1fffe0, /* src_mask */
|
||
+ 0x1fffe0, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS LE TP offset relocation */
|
||
+ HOWTO2 (R_NDS32_TLS_TPOFF, /* 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_NDS32_TLS_TPOFF", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* Like R_NDS32_HI20, but referring to the TLS LE entry for the symbol. */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* A 20 bit address. */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_20, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xfffff, /* src_mask */
|
||
+ 0xfffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_15S0, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_15S0", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x7fff, /* src_mask */
|
||
+ 0x7fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_15S1, /* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_15S1", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x7fff, /* src_mask */
|
||
+ 0x7fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_LE_15S2, /* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 15, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_LE_15S2", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x7fff, /* src_mask */
|
||
+ 0x7fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* Like R_NDS32_HI20, but referring to the TLS IE entry for the symbol. */
|
||
+ HOWTO2 (R_NDS32_TLS_IE_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IE_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IE_LO12", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_TLS_IE_LO12S2,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IE_LO12S2",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* Like R_NDS32_HI20, but referring to the TLS IE (PIE) entry for the symbol. */
|
||
+ HOWTO2 (R_NDS32_TLS_IEGP_HI20,/* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IEGP_HI20",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_TLS_IEGP_LO12,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IEGP_LO12",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO2 (R_NDS32_TLS_IEGP_LO12S2,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_IEGP_LO12S2",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS description relocation */
|
||
+ HOWTO2 (R_NDS32_TLS_DESC, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_hi20_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_DESC_HI20",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description offset high part. */
|
||
+ HOWTO2 (R_NDS32_TLS_DESC_HI20,/* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_hi20_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_DESC_HI20",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ /* TLS GD/LD description offset low part. */
|
||
+ HOWTO2 (R_NDS32_TLS_DESC_LO12,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_lo12_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_DESC_LO12",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description offset set (movi). */
|
||
+ HOWTO2 (R_NDS32_TLS_DESC_20, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_DESC_20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description offset set (lwi.gp). */
|
||
+ HOWTO2 (R_NDS32_TLS_DESC_SDA17S2,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 17, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_TLS_DESC_SDA17S2",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0001ffff, /* src_mask */
|
||
+ 0x0001ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* Jump-patch table relocations. */
|
||
+ /* High 20 bits of jump-patch table address. */
|
||
+ HOWTO2 (R_NDS32_ICT_HI20, /* type */
|
||
+ 12, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 20, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_ICT_HI20", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000fffff, /* src_mask */
|
||
+ 0x000fffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ /* Lower 12 bits of jump-patch table address. */
|
||
+ HOWTO2 (R_NDS32_ICT_LO12,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 12, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_ICT_LO12",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x00000fff, /* src_mask */
|
||
+ 0x00000fff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO2 (R_NDS32_ICT_LO12S2,/* type */
|
||
+ 2, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 10, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_ICT_LO12S2",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000003ff, /* src_mask */
|
||
+ 0x000003ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* A relative 25 bit relocation, right shifted by 2. */
|
||
+ HOWTO2 (R_NDS32_ICT_25PC,/* type */
|
||
+ 1, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 24, /* bitsize */
|
||
+ TRUE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_signed,/* complain_on_overflow */
|
||
+ bfd_elf_generic_reloc, /* special_function */
|
||
+ "R_NDS32_ICT_25PC",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffff, /* src_mask */
|
||
+ 0xffffff, /* dst_mask */
|
||
+ TRUE), /* pcrel_offset */
|
||
};
|
||
|
||
/* Relocations used for relaxation. */
|
||
-static reloc_howto_type nds32_elf_relax_howto_table[] =
|
||
-{
|
||
- HOWTO (R_NDS32_RELAX_ENTRY, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_RELAX_ENTRY", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOT_SUFF, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_GOT_SUFF", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_GOTOFF_SUFF, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_bitfield, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_GOTOFF_SUFF", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_PLT_GOT_SUFF, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_PLT_GOT_SUFF",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_MULCALL_SUFF, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_MULCALL_SUFF",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_PTR, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_PTR", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_PTR_COUNT, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_PTR_COUNT", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_PTR_RESOLVED, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_PTR_RESOLVED",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_PLTBLOCK, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_PLTBLOCK", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_RELAX_REGION_BEGIN, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_RELAX_REGION_BEGIN", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_RELAX_REGION_END, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_RELAX_REGION_END", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_MINUEND, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_MINUEND", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_SUBTRAHEND, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_SUBTRAHEND", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DIFF8, /* type */
|
||
- 0, /* rightshift */
|
||
- 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 8, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DIFF8", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x000000ff, /* src_mask */
|
||
- 0x000000ff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DIFF16, /* type */
|
||
- 0, /* rightshift */
|
||
- 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 16, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DIFF16", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0x0000ffff, /* src_mask */
|
||
- 0x0000ffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DIFF32, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DIFF32", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DIFF_ULEB128, /* type */
|
||
- 0, /* rightshift */
|
||
- 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 0, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DIFF_ULEB128",/* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_DATA, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_DATA", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TRAN, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont,/* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc,/* special_function */
|
||
- "R_NDS32_TRAN", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_ADD, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_ADD", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_TLS_LE_LS, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_TLS_LE_LS", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
- HOWTO (R_NDS32_EMPTY, /* type */
|
||
- 0, /* rightshift */
|
||
- 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
- 32, /* bitsize */
|
||
- FALSE, /* pc_relative */
|
||
- 0, /* bitpos */
|
||
- complain_overflow_dont, /* complain_on_overflow */
|
||
- nds32_elf_ignore_reloc, /* special_function */
|
||
- "R_NDS32_EMPTY", /* name */
|
||
- FALSE, /* partial_inplace */
|
||
- 0xffffffff, /* src_mask */
|
||
- 0xffffffff, /* dst_mask */
|
||
- FALSE), /* pcrel_offset */
|
||
+#define HOWTO3(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
||
+ [C-R_NDS32_RELAX_ENTRY] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC)
|
||
+
|
||
+static reloc_howto_type nds32_elf_relax_howto_table[] = {
|
||
+ HOWTO3 (R_NDS32_RELAX_ENTRY, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_RELAX_ENTRY", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_GOT_SUFF, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_GOT_SUFF", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_GOTOFF_SUFF, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_bitfield,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_GOTOFF_SUFF", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_PLT_GOT_SUFF, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_PLT_GOT_SUFF",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_MULCALL_SUFF, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_MULCALL_SUFF",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_PTR, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_PTR", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_PTR_COUNT, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_PTR_COUNT", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_PTR_RESOLVED, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_PTR_RESOLVED",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_PLTBLOCK, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_PLTBLOCK", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_RELAX_REGION_BEGIN,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_RELAX_REGION_BEGIN",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_RELAX_REGION_END,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_RELAX_REGION_END",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_MINUEND, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_MINUEND", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_SUBTRAHEND, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_SUBTRAHEND", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_DIFF8, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 8, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DIFF8", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x000000ff, /* src_mask */
|
||
+ 0x000000ff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_DIFF16, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 16, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DIFF16", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0x0000ffff, /* src_mask */
|
||
+ 0x0000ffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_DIFF32, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DIFF32", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_DIFF_ULEB128, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 0, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DIFF_ULEB128",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_DATA, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_DATA", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_TRAN, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TRAN", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_EMPTY, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_EMPTY", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO3 (R_NDS32_TLS_LE_ADD, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_LE_ADD", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+ HOWTO3 (R_NDS32_TLS_LE_LS, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_LE_LS", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ HOWTO3 (R_NDS32_TLS_IEGP_LW, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_IEGP_LW", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description address base addition. */
|
||
+ HOWTO3 (R_NDS32_TLS_DESC_ADD, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_DESC_ADD",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description function load. */
|
||
+ HOWTO3 (R_NDS32_TLS_DESC_FUNC,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_DESC_FUNC",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS DESC resolve function call. */
|
||
+ HOWTO3 (R_NDS32_TLS_DESC_CALL,/* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_DESC_CALL",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS DESC variable access. */
|
||
+ HOWTO3 (R_NDS32_TLS_DESC_MEM, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_TLS_DESC_MEM",/* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description mark (@tlsdec). */
|
||
+ HOWTO3 (R_NDS32_RELAX_REMOVE, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_REMOVE", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* TLS GD/LD description mark (@tlsdec). */
|
||
+ HOWTO3 (R_NDS32_RELAX_GROUP, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_GROUP", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
+
|
||
+ /* LA and FLSI relaxation. */
|
||
+ HOWTO3 (R_NDS32_LSI, /* type */
|
||
+ 0, /* rightshift */
|
||
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
|
||
+ 32, /* bitsize */
|
||
+ FALSE, /* pc_relative */
|
||
+ 0, /* bitpos */
|
||
+ complain_overflow_dont,/* complain_on_overflow */
|
||
+ nds32_elf_ignore_reloc,/* special_function */
|
||
+ "R_NDS32_LSI", /* name */
|
||
+ FALSE, /* partial_inplace */
|
||
+ 0xffffffff, /* src_mask */
|
||
+ 0xffffffff, /* dst_mask */
|
||
+ FALSE), /* pcrel_offset */
|
||
};
|
||
-
|
||
|
||
+
|
||
+static unsigned long dl_tlsdesc_lazy_trampoline[] =
|
||
+{
|
||
+ 0x46200000, /* sethi $r2,#0x0 */
|
||
+ 0x58210000, /* ori $r2,$r2,#0x0 */
|
||
+ 0x40217400, /* add $r2,$r2,$gp */
|
||
+ 0x04210000, /* lwi $r2,[$r2+#0x0] */
|
||
+ 0x46300000, /* sethi $r3,#0x0 */
|
||
+ 0x58318000, /* ori $r3,$r3,#0x0 */
|
||
+ 0x4031f400, /* add $r3,$r3,$gp */
|
||
+ 0x4a000800, /* jr $r2 */
|
||
+};
|
||
+
|
||
+/* === code === */
|
||
+
|
||
+static void
|
||
+nds32_put_trampoline (void *contents, const unsigned long *template,
|
||
+ unsigned count)
|
||
+{
|
||
+ unsigned ix;
|
||
+
|
||
+ for (ix = 0; ix != count; ix++)
|
||
+ {
|
||
+ unsigned long insn = template[ix];
|
||
+ bfd_putb32 (insn, (char *) contents + ix * 4);
|
||
+ }
|
||
+}
|
||
+
|
||
/* nds32_insertion_sort sorts an array with nmemb elements of size size.
|
||
This prototype is the same as qsort (). */
|
||
|
||
@@ -2224,7 +2713,7 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size,
|
||
{
|
||
char *ptr = (char *) base;
|
||
int i, j;
|
||
- char *tmp = xmalloc (size);
|
||
+ char *tmp = alloca (size);
|
||
|
||
/* If i is less than j, i is inserted before j.
|
||
|
||
@@ -2248,7 +2737,6 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size,
|
||
memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size);
|
||
memcpy (ptr + j * size, tmp, size);
|
||
}
|
||
- free (tmp);
|
||
}
|
||
|
||
/* Sort relocation by r_offset.
|
||
@@ -2277,14 +2765,13 @@ compar_reloc (const void *lhs, const void *rhs)
|
||
}
|
||
|
||
/* Functions listed below are only used for old relocs.
|
||
- * nds32_elf_9_pcrel_reloc
|
||
- * nds32_elf_do_9_pcrel_reloc
|
||
- * nds32_elf_hi20_reloc
|
||
- * nds32_elf_relocate_hi20
|
||
- * nds32_elf_lo12_reloc
|
||
- * nds32_elf_sda15_reloc
|
||
- * nds32_elf_generic_reloc
|
||
- */
|
||
+ nds32_elf_9_pcrel_reloc
|
||
+ nds32_elf_do_9_pcrel_reloc
|
||
+ nds32_elf_hi20_reloc
|
||
+ nds32_elf_relocate_hi20
|
||
+ nds32_elf_lo12_reloc
|
||
+ nds32_elf_sda15_reloc
|
||
+ nds32_elf_generic_reloc */
|
||
|
||
/* Handle the R_NDS32_9_PCREL & R_NDS32_9_PCREL_RELA reloc. */
|
||
|
||
@@ -2705,8 +3192,7 @@ struct nds32_reloc_map_entry
|
||
unsigned char elf_reloc_val;
|
||
};
|
||
|
||
-static const struct nds32_reloc_map_entry nds32_reloc_map[] =
|
||
-{
|
||
+static const struct nds32_reloc_map_entry nds32_reloc_map[] = {
|
||
{BFD_RELOC_NONE, R_NDS32_NONE},
|
||
{BFD_RELOC_16, R_NDS32_16_RELA},
|
||
{BFD_RELOC_32, R_NDS32_32_RELA},
|
||
@@ -2765,6 +3251,7 @@ static const struct nds32_reloc_map_entry nds32_reloc_map[] =
|
||
{BFD_RELOC_NDS32_LONGJUMP5, R_NDS32_LONGJUMP5},
|
||
{BFD_RELOC_NDS32_LONGJUMP6, R_NDS32_LONGJUMP6},
|
||
{BFD_RELOC_NDS32_LONGJUMP7, R_NDS32_LONGJUMP7},
|
||
+ {BFD_RELOC_NDS32_SECURITY_16, R_NDS32_SECURITY_16},
|
||
{BFD_RELOC_NDS32_LOADSTORE, R_NDS32_LOADSTORE},
|
||
{BFD_RELOC_NDS32_9_FIXED, R_NDS32_9_FIXED_RELA},
|
||
{BFD_RELOC_NDS32_15_FIXED, R_NDS32_15_FIXED_RELA},
|
||
@@ -2822,15 +3309,52 @@ static const struct nds32_reloc_map_entry nds32_reloc_map[] =
|
||
{BFD_RELOC_NDS32_TLS_LE_LS, R_NDS32_TLS_LE_LS},
|
||
{BFD_RELOC_NDS32_TLS_IE_HI20, R_NDS32_TLS_IE_HI20},
|
||
{BFD_RELOC_NDS32_TLS_IE_LO12S2, R_NDS32_TLS_IE_LO12S2},
|
||
- {BFD_RELOC_NDS32_TLS_TPOFF, R_NDS32_TLS_TPOFF},
|
||
{BFD_RELOC_NDS32_TLS_LE_20, R_NDS32_TLS_LE_20},
|
||
{BFD_RELOC_NDS32_TLS_LE_15S0, R_NDS32_TLS_LE_15S0},
|
||
{BFD_RELOC_NDS32_TLS_LE_15S1, R_NDS32_TLS_LE_15S1},
|
||
{BFD_RELOC_NDS32_TLS_LE_15S2, R_NDS32_TLS_LE_15S2},
|
||
+
|
||
+ {BFD_RELOC_NDS32_TLS_DESC, R_NDS32_TLS_DESC},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_HI20, R_NDS32_TLS_DESC_HI20},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_LO12, R_NDS32_TLS_DESC_LO12},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_ADD, R_NDS32_TLS_DESC_ADD},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_FUNC, R_NDS32_TLS_DESC_FUNC},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_CALL, R_NDS32_TLS_DESC_CALL},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_MEM, R_NDS32_TLS_DESC_MEM},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_20, R_NDS32_TLS_DESC_20},
|
||
+ {BFD_RELOC_NDS32_TLS_DESC_SDA17S2, R_NDS32_TLS_DESC_SDA17S2},
|
||
+ {BFD_RELOC_NDS32_TLS_IE_LO12, R_NDS32_TLS_IE_LO12},
|
||
+ {BFD_RELOC_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_IEGP_HI20},
|
||
+ {BFD_RELOC_NDS32_TLS_IEGP_LO12, R_NDS32_TLS_IEGP_LO12},
|
||
+ {BFD_RELOC_NDS32_TLS_IEGP_LO12S2, R_NDS32_TLS_IEGP_LO12S2},
|
||
+ {BFD_RELOC_NDS32_TLS_IEGP_LW, R_NDS32_TLS_IEGP_LW},
|
||
+
|
||
+ {BFD_RELOC_NDS32_REMOVE, R_NDS32_RELAX_REMOVE},
|
||
+ {BFD_RELOC_NDS32_GROUP, R_NDS32_RELAX_GROUP},
|
||
+
|
||
+ {BFD_RELOC_NDS32_ICT_HI20, R_NDS32_ICT_HI20},
|
||
+ {BFD_RELOC_NDS32_ICT_LO12, R_NDS32_ICT_LO12},
|
||
+ {BFD_RELOC_NDS32_ICT_25PC, R_NDS32_ICT_25PC},
|
||
+ {BFD_RELOC_NDS32_ICT_LO12S2, R_NDS32_ICT_LO12S2},
|
||
+
|
||
+ {BFD_RELOC_NDS32_LSI, R_NDS32_LSI},
|
||
};
|
||
|
||
/* Patch tag. */
|
||
|
||
+/* Reserve space for COUNT dynamic relocations in relocation selection
|
||
+ SRELOC. */
|
||
+
|
||
+static inline void
|
||
+elf32_nds32_allocate_dynrelocs (struct bfd_link_info *info, asection *sreloc,
|
||
+ bfd_size_type count)
|
||
+{
|
||
+ BFD_ASSERT (elf_hash_table (info)->dynamic_sections_created);
|
||
+ if (sreloc == NULL)
|
||
+ abort ();
|
||
+ sreloc->size += sizeof (Elf32_External_Rela) * count;
|
||
+}
|
||
+
|
||
static reloc_howto_type *
|
||
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||
const char *r_name)
|
||
@@ -2860,6 +3384,13 @@ bfd_elf32_bfd_reloc_type_table_lookup (enum elf_nds32_reloc_type code)
|
||
}
|
||
else
|
||
{
|
||
+ if ((size_t) (code - R_NDS32_RELAX_ENTRY) >=
|
||
+ ARRAY_SIZE (nds32_elf_relax_howto_table))
|
||
+ {
|
||
+ int i = code;
|
||
+ i += 1;
|
||
+ }
|
||
+
|
||
BFD_ASSERT ((size_t) (code - R_NDS32_RELAX_ENTRY)
|
||
< ARRAY_SIZE (nds32_elf_relax_howto_table));
|
||
return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY];
|
||
@@ -2876,7 +3407,7 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||
{
|
||
if (nds32_reloc_map[i].bfd_reloc_val == code)
|
||
return bfd_elf32_bfd_reloc_type_table_lookup
|
||
- (nds32_reloc_map[i].elf_reloc_val);
|
||
+ (nds32_reloc_map[i].elf_reloc_val);
|
||
}
|
||
|
||
return NULL;
|
||
@@ -2897,6 +3428,8 @@ nds32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
|
||
_bfd_error_handler (_("%B: invalid NDS32 reloc number: %d"), abfd, r_type);
|
||
r_type = 0;
|
||
}
|
||
+
|
||
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY);
|
||
cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
|
||
}
|
||
|
||
@@ -2922,29 +3455,29 @@ nds32_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
|
||
switch (note->descsz)
|
||
{
|
||
case 0x114:
|
||
- /* Linux/NDS32 32-bit, ABI1 */
|
||
+ /* Linux/NDS32 32-bit, ABI1 */
|
||
|
||
- /* pr_cursig */
|
||
+ /* pr_cursig */
|
||
elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
|
||
|
||
- /* pr_pid */
|
||
+ /* pr_pid */
|
||
elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
|
||
|
||
- /* pr_reg */
|
||
+ /* pr_reg */
|
||
offset = 72;
|
||
size = 200;
|
||
break;
|
||
|
||
case 0xfc:
|
||
- /* Linux/NDS32 32-bit */
|
||
+ /* Linux/NDS32 32-bit */
|
||
|
||
- /* pr_cursig */
|
||
+ /* pr_cursig */
|
||
elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
|
||
|
||
- /* pr_pid */
|
||
+ /* pr_pid */
|
||
elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
|
||
|
||
- /* pr_reg */
|
||
+ /* pr_reg */
|
||
offset = 72;
|
||
size = 176;
|
||
break;
|
||
@@ -2964,7 +3497,7 @@ nds32_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
|
||
switch (note->descsz)
|
||
{
|
||
case 124:
|
||
- /* Linux/NDS32 */
|
||
+ /* Linux/NDS32 */
|
||
|
||
/* __kernel_uid_t, __kernel_gid_t are short on NDS32 platform. */
|
||
elf_tdata (abfd)->core->program =
|
||
@@ -3097,20 +3630,20 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
|
||
struct elf_nds32_link_hash_table *table;
|
||
struct bfd_link_hash_entry *h, *h2;
|
||
long unsigned int total = 0;
|
||
+ asection *first = NULL, *final = NULL, *temp;
|
||
+ bfd_vma sda_base = 0;
|
||
|
||
h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE);
|
||
if (!h || (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak))
|
||
{
|
||
- asection *first = NULL, *final = NULL, *temp;
|
||
- bfd_vma sda_base;
|
||
/* The first section must be 4-byte aligned to promise _SDA_BASE_ being
|
||
4 byte-aligned. Therefore, it has to set the first section ".data"
|
||
4 byte-aligned. */
|
||
static const char sec_name[SDA_SECTION_NUM][10] =
|
||
- {
|
||
- ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b",
|
||
- ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d"
|
||
- };
|
||
+ {
|
||
+ ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b",
|
||
+ ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d"
|
||
+ };
|
||
size_t i = 0;
|
||
|
||
if (output_bfd->sections == NULL)
|
||
@@ -3120,7 +3653,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
|
||
}
|
||
|
||
/* Get the first and final section. */
|
||
- while (i < sizeof (sec_name) / sizeof (sec_name [0]))
|
||
+ while (i < ARRAY_SIZE (sec_name))
|
||
{
|
||
temp = bfd_get_section_by_name (output_bfd, sec_name[i]);
|
||
if (temp && !first && (temp->size != 0 || temp->rawsize != 0))
|
||
@@ -3162,7 +3695,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
||
/* Find the section sda_base located. */
|
||
i = 0;
|
||
- while (i < sizeof (sec_name) / sizeof (sec_name [0]))
|
||
+ while (i < ARRAY_SIZE (sec_name))
|
||
{
|
||
final = bfd_get_section_by_name (output_bfd, sec_name[i]);
|
||
if (final && (final->size != 0 || final->rawsize != 0)
|
||
@@ -3177,17 +3710,44 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
|
||
}
|
||
else
|
||
{
|
||
- /* There is not any data section in output bfd, and set _SDA_BASE_ in
|
||
- first output section. */
|
||
- first = output_bfd->sections;
|
||
- while (first && first->size == 0 && first->rawsize == 0)
|
||
- first = first->next;
|
||
+ /* If there is not any default data section in output bfd, try to find
|
||
+ the first data section. If no data section be found, just simplily
|
||
+ choose the first output section. */
|
||
+ temp = output_bfd->sections;
|
||
+ while (temp)
|
||
+ {
|
||
+ if (temp->flags & SEC_ALLOC
|
||
+ && (((temp->flags & SEC_DATA)
|
||
+ && ((temp->flags & SEC_READONLY) == 0))
|
||
+ || (temp->flags & SEC_LOAD) == 0)
|
||
+ && (temp->size != 0 || temp->rawsize != 0))
|
||
+ {
|
||
+ if (!first)
|
||
+ first = temp;
|
||
+ final = temp;
|
||
+ }
|
||
+ temp = temp->next;
|
||
+ }
|
||
+
|
||
+ /* There is no data or bss section. */
|
||
+ if (!first || (first->size == 0 && first->rawsize == 0))
|
||
+ {
|
||
+ first = output_bfd->sections;
|
||
+ while (first && first->size == 0 && first->rawsize == 0)
|
||
+ first = first->next;
|
||
+ }
|
||
+
|
||
+ /* There is no concrete section. */
|
||
if (!first)
|
||
{
|
||
*psb = elf_gp (output_bfd);
|
||
return bfd_reloc_ok;
|
||
}
|
||
- sda_base = first->vma + first->rawsize;
|
||
+
|
||
+ if (final && (final->vma + final->rawsize - first->vma) <= 0x4000)
|
||
+ sda_base = final->vma / 2 + final->rawsize / 2 + first->vma / 2;
|
||
+ else
|
||
+ sda_base = first->vma + 0x2000;
|
||
}
|
||
|
||
sda_base -= first->vma;
|
||
@@ -3201,24 +3761,34 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
||
sda_rela_sec = first;
|
||
|
||
- table = nds32_elf_hash_table (info);
|
||
- relax_fp_as_gp = table->relax_fp_as_gp;
|
||
- if (relax_fp_as_gp)
|
||
- {
|
||
- h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME,
|
||
- FALSE, FALSE, FALSE);
|
||
- /* Define a weak FP_BASE_NAME here to prevent the undefined symbol.
|
||
- And set FP equal to SDA_BASE to do relaxation for
|
||
- la $fp, _FP_BASE_. */
|
||
- if (!_bfd_generic_link_add_one_symbol
|
||
- (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK,
|
||
- first, (bfd_vma) sda_base, (const char *) NULL,
|
||
- FALSE, get_elf_backend_data (output_bfd)->collect, &h2))
|
||
- return FALSE;
|
||
- }
|
||
}
|
||
|
||
- if (add_symbol)
|
||
+ /* Set _FP_BASE_ to _SDA_BASE_. */
|
||
+ table = nds32_elf_hash_table (info);
|
||
+ relax_fp_as_gp = table->relax_fp_as_gp;
|
||
+ h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME, FALSE, FALSE, FALSE);
|
||
+ /* _SDA_BASE_ is difined in linker script. */
|
||
+ if (!first)
|
||
+ {
|
||
+ first = h->u.def.section;
|
||
+ sda_base = h->u.def.value;
|
||
+ }
|
||
+
|
||
+ if (relax_fp_as_gp && h2
|
||
+ && (h2->type == bfd_link_hash_undefweak
|
||
+ || h2->type == bfd_link_hash_undefined))
|
||
+ {
|
||
+ /* Define a weak FP_BASE_NAME here to prevent the undefined symbol.
|
||
+ And set FP equal to SDA_BASE to do relaxation for
|
||
+ la $fp, _FP_BASE_. */
|
||
+ if (!_bfd_generic_link_add_one_symbol
|
||
+ (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK,
|
||
+ first, sda_base, (const char *) NULL,
|
||
+ FALSE, get_elf_backend_data (output_bfd)->collect, &h2))
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ if (add_symbol == TRUE)
|
||
{
|
||
if (h)
|
||
{
|
||
@@ -3275,6 +3845,8 @@ nds32_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
|
||
eh = (struct elf_nds32_link_hash_entry *) ret;
|
||
eh->dyn_relocs = NULL;
|
||
eh->tls_type = GOT_UNKNOWN;
|
||
+ eh->offset_to_gp = 0;
|
||
+ eh->indirect_call = FALSE;
|
||
}
|
||
|
||
return (struct bfd_hash_entry *) ret;
|
||
@@ -3303,22 +3875,61 @@ nds32_elf_link_hash_table_create (bfd *abfd)
|
||
return NULL;
|
||
}
|
||
|
||
+ ret->sdynbss = NULL;
|
||
+ ret->srelbss = NULL;
|
||
+ ret->sym_ld_script = NULL;
|
||
+
|
||
return &ret->root.root;
|
||
}
|
||
|
||
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
|
||
+ shortcuts to them in our hash table. */
|
||
+
|
||
+static bfd_boolean
|
||
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
|
||
+{
|
||
+ struct elf_link_hash_table *ehtab;
|
||
+
|
||
+ if (!_bfd_elf_create_got_section (dynobj, info))
|
||
+ return FALSE;
|
||
+
|
||
+ ehtab = elf_hash_table (info);
|
||
+ ehtab->sgot = bfd_get_section_by_name (dynobj, ".got");
|
||
+ ehtab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
|
||
+ if (!ehtab->sgot || !ehtab->sgotplt)
|
||
+ abort ();
|
||
+
|
||
+ /* _bfd_elf_create_got_section will create it for us. */
|
||
+ ehtab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
|
||
+ if (ehtab->srelgot == NULL
|
||
+ || !bfd_set_section_flags (dynobj, ehtab->srelgot,
|
||
+ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
|
||
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
|
||
+ | SEC_READONLY))
|
||
+ || !bfd_set_section_alignment (dynobj, ehtab->srelgot, 2))
|
||
+ return FALSE;
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
/* Create dynamic sections when linking against a dynamic object. */
|
||
|
||
static bfd_boolean
|
||
nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
||
{
|
||
+ struct elf_link_hash_table *ehtab;
|
||
struct elf_nds32_link_hash_table *htab;
|
||
flagword flags, pltflags;
|
||
register asection *s;
|
||
const struct elf_backend_data *bed;
|
||
int ptralign = 2; /* 32-bit */
|
||
+ const char *secname;
|
||
+ char *relname;
|
||
+ flagword secflags;
|
||
+ asection *sec;
|
||
|
||
bed = get_elf_backend_data (abfd);
|
||
-
|
||
+ ehtab = elf_hash_table (info);
|
||
htab = nds32_elf_hash_table (info);
|
||
|
||
/* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
|
||
@@ -3335,7 +3946,7 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
||
pltflags |= SEC_READONLY;
|
||
|
||
s = bfd_make_section (abfd, ".plt");
|
||
- htab->root.splt = s;
|
||
+ ehtab->splt = s;
|
||
if (s == NULL
|
||
|| !bfd_set_section_flags (abfd, s, pltflags)
|
||
|| !bfd_set_section_alignment (abfd, s, bed->plt_alignment))
|
||
@@ -3364,40 +3975,33 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
||
|
||
s = bfd_make_section (abfd,
|
||
bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
|
||
- htab->root.srelplt = s;
|
||
+ ehtab->srelplt = s;
|
||
if (s == NULL
|
||
|| !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|
||
|| !bfd_set_section_alignment (abfd, s, ptralign))
|
||
return FALSE;
|
||
|
||
- if (htab->root.sgot == NULL && !_bfd_elf_create_got_section (abfd, info))
|
||
+ if (ehtab->sgot == NULL && !create_got_section (abfd, info))
|
||
return FALSE;
|
||
|
||
- {
|
||
- const char *secname;
|
||
- char *relname;
|
||
- flagword secflags;
|
||
- asection *sec;
|
||
-
|
||
- for (sec = abfd->sections; sec; sec = sec->next)
|
||
- {
|
||
- secflags = bfd_get_section_flags (abfd, sec);
|
||
- if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
|
||
- || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
|
||
- continue;
|
||
- secname = bfd_get_section_name (abfd, sec);
|
||
- relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
|
||
- strcpy (relname, ".rela");
|
||
- strcat (relname, secname);
|
||
- if (bfd_get_section_by_name (abfd, secname))
|
||
- continue;
|
||
- s = bfd_make_section (abfd, relname);
|
||
- if (s == NULL
|
||
- || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|
||
- || !bfd_set_section_alignment (abfd, s, ptralign))
|
||
- return FALSE;
|
||
- }
|
||
- }
|
||
+ for (sec = abfd->sections; sec; sec = sec->next)
|
||
+ {
|
||
+ secflags = bfd_get_section_flags (abfd, sec);
|
||
+ if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
|
||
+ || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
|
||
+ continue;
|
||
+ secname = bfd_get_section_name (abfd, sec);
|
||
+ relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
|
||
+ strcpy (relname, ".rela");
|
||
+ strcat (relname, secname);
|
||
+ if (bfd_get_section_by_name (abfd, secname))
|
||
+ continue;
|
||
+ s = bfd_make_section (abfd, relname);
|
||
+ if (s == NULL
|
||
+ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|
||
+ || !bfd_set_section_alignment (abfd, s, ptralign))
|
||
+ return FALSE;
|
||
+ }
|
||
|
||
if (bed->want_dynbss)
|
||
{
|
||
@@ -3453,8 +4057,8 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
||
{
|
||
if (edir->dyn_relocs != NULL)
|
||
{
|
||
- struct elf_dyn_relocs **pp;
|
||
- struct elf_dyn_relocs *p;
|
||
+ struct elf_nds32_dyn_relocs **pp;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
|
||
if (ind->root.type == bfd_link_hash_indirect)
|
||
abort ();
|
||
@@ -3463,7 +4067,7 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
||
list. Merge any entries against the same section. */
|
||
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
|
||
{
|
||
- struct elf_dyn_relocs *q;
|
||
+ struct elf_nds32_dyn_relocs *q;
|
||
|
||
for (q = edir->dyn_relocs; q != NULL; q = q->next)
|
||
if (q->sec == p->sec)
|
||
@@ -3483,25 +4087,18 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
||
eind->dyn_relocs = NULL;
|
||
}
|
||
|
||
- _bfd_elf_link_hash_copy_indirect (info, dir, ind);
|
||
-}
|
||
-
|
||
-/* Find dynamic relocs for H that apply to read-only sections. */
|
||
-
|
||
-static asection *
|
||
-readonly_dynrelocs (struct elf_link_hash_entry *h)
|
||
-{
|
||
- struct elf_dyn_relocs *p;
|
||
-
|
||
- for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
|
||
+ if (ind->root.type == bfd_link_hash_indirect)
|
||
{
|
||
- asection *s = p->sec->output_section;
|
||
-
|
||
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
||
- return p->sec;
|
||
+ if (dir->got.refcount <= 0)
|
||
+ {
|
||
+ edir->tls_type = eind->tls_type;
|
||
+ eind->tls_type = GOT_UNKNOWN;
|
||
+ }
|
||
}
|
||
- return NULL;
|
||
+
|
||
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
|
||
}
|
||
+
|
||
|
||
/* Adjust a symbol defined by a dynamic object and referenced by a
|
||
regular object. The current definition is in some section of the
|
||
@@ -3514,6 +4111,8 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||
struct elf_link_hash_entry *h)
|
||
{
|
||
struct elf_nds32_link_hash_table *htab;
|
||
+ struct elf_nds32_link_hash_entry *eh;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
bfd *dynobj;
|
||
asection *s;
|
||
unsigned int power_of_two;
|
||
@@ -3558,7 +4157,8 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||
if (h->is_weakalias)
|
||
{
|
||
struct elf_link_hash_entry *def = weakdef (h);
|
||
- BFD_ASSERT (def->root.type == bfd_link_hash_defined);
|
||
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined
|
||
+ || def->root.type == bfd_link_hash_defweak);
|
||
h->root.u.def.section = def->root.u.def.section;
|
||
h->root.u.def.value = def->root.u.def.value;
|
||
return TRUE;
|
||
@@ -3580,15 +4180,24 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||
return TRUE;
|
||
|
||
/* If -z nocopyreloc was given, we won't generate them either. */
|
||
- if (0 && info->nocopyreloc)
|
||
+ if (info->nocopyreloc)
|
||
{
|
||
h->non_got_ref = 0;
|
||
return TRUE;
|
||
}
|
||
|
||
- /* If we don't find any dynamic relocs in read-only sections, then
|
||
- we'll be keeping the dynamic relocs and avoiding the copy reloc. */
|
||
- if (0 && !readonly_dynrelocs (h))
|
||
+ eh = (struct elf_nds32_link_hash_entry *) h;
|
||
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||
+ {
|
||
+ s = p->sec->output_section;
|
||
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ /* If we didn't find any dynamic relocs in sections which needs the
|
||
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
|
||
+ the copy reloc. */
|
||
+ if (p == NULL)
|
||
{
|
||
h->non_got_ref = 0;
|
||
return TRUE;
|
||
@@ -3653,25 +4262,31 @@ static bfd_boolean
|
||
allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
{
|
||
struct bfd_link_info *info;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
struct elf_nds32_link_hash_table *htab;
|
||
struct elf_nds32_link_hash_entry *eh;
|
||
- struct elf_dyn_relocs *p;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
|
||
if (h->root.type == bfd_link_hash_indirect)
|
||
return TRUE;
|
||
|
||
+ /* When warning symbols are created, they **replace** the "real"
|
||
+ entry in the hash table, thus we never get to see the real
|
||
+ symbol in a hash traversal. So look at it now. */
|
||
if (h->root.type == bfd_link_hash_warning)
|
||
- /* When warning symbols are created, they **replace** the "real"
|
||
- entry in the hash table, thus we never get to see the real
|
||
- symbol in a hash traversal. So look at it now. */
|
||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||
|
||
+ eh = (struct elf_nds32_link_hash_entry *) h;
|
||
+
|
||
info = (struct bfd_link_info *) inf;
|
||
+ ehtab = elf_hash_table (info);
|
||
htab = nds32_elf_hash_table (info);
|
||
+ if (htab == NULL)
|
||
+ return FALSE;
|
||
|
||
- eh = (struct elf_nds32_link_hash_entry *) h;
|
||
-
|
||
- if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
|
||
+ if ((htab->root.dynamic_sections_created || h->type == STT_GNU_IFUNC)
|
||
+ && h->plt.refcount > 0
|
||
+ && !(bfd_link_pie (info) && h->def_regular))
|
||
{
|
||
/* Make sure this symbol is output as a dynamic symbol.
|
||
Undefined weak syms won't yet be marked as dynamic. */
|
||
@@ -3683,7 +4298,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
|
||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
|
||
{
|
||
- asection *s = htab->root.splt;
|
||
+ asection *s = ehtab->splt;
|
||
|
||
/* If this is the first .plt entry, make room for the special
|
||
first entry. */
|
||
@@ -3708,10 +4323,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
|
||
/* 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->root.sgotplt->size += 4;
|
||
+ ehtab->sgotplt->size += 4;
|
||
|
||
/* We also need to make an entry in the .rel.plt section. */
|
||
- htab->root.srelplt->size += sizeof (Elf32_External_Rela);
|
||
+ ehtab->srelplt->size += sizeof (Elf32_External_Rela);
|
||
+ if (htab->tls_desc_trampoline)
|
||
+ htab->next_tls_desc_index++;
|
||
}
|
||
else
|
||
{
|
||
@@ -3727,7 +4344,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
|
||
if (h->got.refcount > 0)
|
||
{
|
||
- asection *s;
|
||
+ asection *sgot;
|
||
bfd_boolean dyn;
|
||
int tls_type = elf32_nds32_hash_entry (h)->tls_type;
|
||
|
||
@@ -3739,22 +4356,44 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
return FALSE;
|
||
}
|
||
|
||
- s = htab->root.sgot;
|
||
- h->got.offset = s->size;
|
||
+ sgot = elf_hash_table (info)->sgot;
|
||
+ h->got.offset = sgot->size;
|
||
|
||
if (tls_type == GOT_UNKNOWN)
|
||
abort ();
|
||
- else if (tls_type == GOT_NORMAL
|
||
- || tls_type == GOT_TLS_IE)
|
||
- /* Need a GOT slot. */
|
||
- s->size += 4;
|
||
+
|
||
+ /* Non-TLS symbols, and TLS_IE need one GOT slot. */
|
||
+ if (tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP))
|
||
+ sgot->size += 4;
|
||
+ else
|
||
+ {
|
||
+ /* TLS_DESC, TLS_GD, and TLS_LD need 2 consecutive GOT slots. */
|
||
+ if (tls_type & GOT_TLS_DESC)
|
||
+ sgot->size += 8;
|
||
+ }
|
||
|
||
dyn = htab->root.dynamic_sections_created;
|
||
+
|
||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
|
||
- htab->root.srelgot->size += sizeof (Elf32_External_Rela);
|
||
+ {
|
||
+ if (tls_type == GOT_TLS_DESC && htab->tls_desc_trampoline)
|
||
+ {
|
||
+ /* TLS_DESC with trampoline needs a relocation slot
|
||
+ within .rela.plt. */
|
||
+ htab->num_tls_desc++;
|
||
+ ehtab->srelplt->size += sizeof (Elf32_External_Rela);
|
||
+ htab->tls_trampoline = -1;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* other relocations, including TLS_DESC without trampoline, need
|
||
+ a relocation slot within .rela.got. */
|
||
+ ehtab->srelgot->size += sizeof (Elf32_External_Rela);
|
||
+ }
|
||
+ }
|
||
}
|
||
else
|
||
- h->got.offset = (bfd_vma) - 1;
|
||
+ h->got.offset = (bfd_vma) -1;
|
||
|
||
if (eh->dyn_relocs == NULL)
|
||
return TRUE;
|
||
@@ -3769,7 +4408,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
{
|
||
if (h->def_regular && (h->forced_local || info->symbolic))
|
||
{
|
||
- struct elf_dyn_relocs **pp;
|
||
+ struct elf_nds32_dyn_relocs **pp;
|
||
|
||
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
|
||
{
|
||
@@ -3810,7 +4449,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
|
||
eh->dyn_relocs = NULL;
|
||
|
||
- keep:;
|
||
+keep:;
|
||
}
|
||
|
||
/* Finally, allocate space. */
|
||
@@ -3823,29 +4462,50 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Set DF_TEXTREL if we find any dynamic relocs that apply to
|
||
- read-only sections. */
|
||
+/* Add relocation REL to the end of relocation section SRELOC. */
|
||
+
|
||
+static void
|
||
+elf32_nds32_add_dynreloc (bfd *output_bfd,
|
||
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
|
||
+ asection *sreloc, Elf_Internal_Rela *rel)
|
||
+{
|
||
+ bfd_byte *loc;
|
||
+ if (sreloc == NULL)
|
||
+ abort ();
|
||
+
|
||
+ loc = sreloc->contents;
|
||
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
|
||
+ if (sreloc->reloc_count * sizeof (Elf32_External_Rela) > sreloc->size)
|
||
+ abort ();
|
||
+
|
||
+ bfd_elf32_swap_reloca_out (output_bfd, rel, loc);
|
||
+}
|
||
+
|
||
+/* Find any dynamic relocs that apply to read-only sections. */
|
||
|
||
static bfd_boolean
|
||
-maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
|
||
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||
{
|
||
- asection *sec;
|
||
+ struct elf_nds32_link_hash_entry *eh;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
|
||
- if (h->root.type == bfd_link_hash_indirect)
|
||
- return TRUE;
|
||
+ if (h->root.type == bfd_link_hash_warning)
|
||
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||
|
||
- sec = readonly_dynrelocs (h);
|
||
- if (sec != NULL)
|
||
+ eh = (struct elf_nds32_link_hash_entry *) h;
|
||
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||
{
|
||
- struct bfd_link_info *info = (struct bfd_link_info *) info_p;
|
||
+ asection *s = p->sec->output_section;
|
||
+
|
||
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
||
+ {
|
||
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
|
||
|
||
- info->flags |= DF_TEXTREL;
|
||
- info->callbacks->minfo
|
||
- (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
|
||
- sec->owner, h->root.root.string, sec);
|
||
+ info->flags |= DF_TEXTREL;
|
||
|
||
- /* Not an error, just cut short the traversal. */
|
||
- return FALSE;
|
||
+ /* Not an error, just cut short the traversal. */
|
||
+ return FALSE;
|
||
+ }
|
||
}
|
||
return TRUE;
|
||
}
|
||
@@ -3856,20 +4516,24 @@ static bfd_boolean
|
||
nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
struct bfd_link_info *info)
|
||
{
|
||
- struct elf_nds32_link_hash_table *htab;
|
||
bfd *dynobj;
|
||
asection *s;
|
||
+ bfd_boolean plt;
|
||
bfd_boolean relocs;
|
||
bfd *ibfd;
|
||
+ struct elf_nds32_link_hash_table *htab;
|
||
|
||
htab = nds32_elf_hash_table (info);
|
||
- dynobj = htab->root.dynobj;
|
||
+ if (htab == NULL)
|
||
+ return FALSE;
|
||
+
|
||
+ dynobj = elf_hash_table (info)->dynobj;
|
||
BFD_ASSERT (dynobj != NULL);
|
||
|
||
- if (htab->root.dynamic_sections_created)
|
||
+ if (elf_hash_table (info)->dynamic_sections_created)
|
||
{
|
||
/* Set the contents of the .interp section to the interpreter. */
|
||
- if (bfd_link_executable (info) && !info->nointerp)
|
||
+ if (bfd_link_executable (info))
|
||
{
|
||
s = bfd_get_section_by_name (dynobj, ".interp");
|
||
BFD_ASSERT (s != NULL);
|
||
@@ -3886,16 +4550,19 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
bfd_signed_vma *end_local_got;
|
||
bfd_size_type locsymcount;
|
||
Elf_Internal_Shdr *symtab_hdr;
|
||
- asection *srel;
|
||
+ asection *sgot;
|
||
+ char *local_tls_type;
|
||
+ unsigned long symndx;
|
||
+ bfd_vma *local_tlsdesc_gotent;
|
||
|
||
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
|
||
continue;
|
||
|
||
for (s = ibfd->sections; s != NULL; s = s->next)
|
||
{
|
||
- struct elf_dyn_relocs *p;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
|
||
- for (p = ((struct elf_dyn_relocs *)
|
||
+ for (p = ((struct elf_nds32_dyn_relocs *)
|
||
elf_section_data (s)->local_dynrel);
|
||
p != NULL; p = p->next)
|
||
{
|
||
@@ -3909,8 +4576,8 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
}
|
||
else if (p->count != 0)
|
||
{
|
||
- srel = elf_section_data (p->sec)->sreloc;
|
||
- srel->size += p->count * sizeof (Elf32_External_Rela);
|
||
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
|
||
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
|
||
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
|
||
info->flags |= DF_TEXTREL;
|
||
}
|
||
@@ -3924,19 +4591,57 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
|
||
locsymcount = symtab_hdr->sh_info;
|
||
end_local_got = local_got + locsymcount;
|
||
- s = htab->root.sgot;
|
||
- srel = htab->root.srelgot;
|
||
- for (; local_got < end_local_got; ++local_got)
|
||
+ sgot = elf_hash_table (info)->sgot;
|
||
+ local_tls_type = elf32_nds32_local_got_tls_type (ibfd);
|
||
+ local_tlsdesc_gotent = elf32_nds32_local_tlsdesc_gotent (ibfd);
|
||
+ for (symndx = 0; local_got < end_local_got;
|
||
+ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent, ++symndx)
|
||
{
|
||
if (*local_got > 0)
|
||
{
|
||
- *local_got = s->size;
|
||
- s->size += 4;
|
||
- if (bfd_link_pic (info))
|
||
- srel->size += sizeof (Elf32_External_Rela);
|
||
+ int num_of_got_entry_needed = 0;
|
||
+ *local_got = sgot->size;
|
||
+ *local_tlsdesc_gotent = sgot->size;
|
||
+
|
||
+ /* TLS_NORMAL, and TLS_IE need one slot in .got. */
|
||
+ if (*local_tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP))
|
||
+ num_of_got_entry_needed = 1;
|
||
+ /* TLS_GD, TLS_LD, and TLS_DESC need an 8-byte structure in the GOT. */
|
||
+ else if (*local_tls_type & GOT_TLS_DESC)
|
||
+ num_of_got_entry_needed = 2;
|
||
+
|
||
+ sgot->size += (num_of_got_entry_needed << 2);
|
||
+
|
||
+ /* non-relax-able TLS_DESCs need a slot in .rela.plt.
|
||
+ others need a slot in .rela.got. */
|
||
+ if (*local_tls_type == GOT_TLS_DESC)
|
||
+ {
|
||
+ if (bfd_link_pic (info))
|
||
+ {
|
||
+ if (htab->tls_desc_trampoline)
|
||
+ {
|
||
+ htab->num_tls_desc++;
|
||
+ htab->root.srelplt->size += sizeof (Elf32_External_Rela);
|
||
+ htab->tls_trampoline = -1;
|
||
+ }
|
||
+ else
|
||
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* TLS_DESC -> TLS_LE */
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
|
||
+ }
|
||
}
|
||
else
|
||
- *local_got = (bfd_vma) - 1;
|
||
+ {
|
||
+ *local_got = (bfd_vma) -1;
|
||
+ *local_tlsdesc_gotent = (bfd_vma) -1;
|
||
+ }
|
||
}
|
||
}
|
||
|
||
@@ -3944,8 +4649,36 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
sym dynamic relocs. */
|
||
elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (void *) info);
|
||
|
||
+ /* For every jump slot reserved in the sgotplt, reloc_count is
|
||
+ incremented. However, when we reserve space for TLS descriptors,
|
||
+ it's not incremented, so in order to compute the space reserved
|
||
+ for them, it suffices to multiply the reloc count by the jump
|
||
+ slot size. */
|
||
+ if (htab->tls_desc_trampoline && htab->root.srelplt)
|
||
+ htab->sgotplt_jump_table_size = elf32_nds32_compute_jump_table_size (htab);
|
||
+
|
||
+ if (htab->tls_trampoline)
|
||
+ {
|
||
+ htab->tls_trampoline = htab->root.splt->size;
|
||
+
|
||
+ /* If we're not using lazy TLS relocations, don't generate the
|
||
+ PLT and GOT entries they require. */
|
||
+ if (!(info->flags & DF_BIND_NOW))
|
||
+ {
|
||
+ htab->dt_tlsdesc_got = htab->root.sgot->size;
|
||
+ htab->root.sgot->size += 4;
|
||
+
|
||
+ htab->dt_tlsdesc_plt = htab->root.splt->size;
|
||
+ htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline);
|
||
+ }
|
||
+ }
|
||
+
|
||
/* We now have determined the sizes of the various dynamic sections.
|
||
Allocate memory for them. */
|
||
+ /* The check_relocs and adjust_dynamic_symbol entry points have
|
||
+ determined the sizes of the various dynamic sections. Allocate
|
||
+ memory for them. */
|
||
+ plt = FALSE;
|
||
relocs = FALSE;
|
||
for (s = dynobj->sections; s != NULL; s = s->next)
|
||
{
|
||
@@ -3956,18 +4689,19 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
{
|
||
/* Strip this section if we don't need it; see the
|
||
comment below. */
|
||
+ plt = s->size != 0;
|
||
}
|
||
- else if (s == htab->root.sgot)
|
||
+ else if (s == elf_hash_table (info)->sgot)
|
||
{
|
||
got_size += s->size;
|
||
}
|
||
- else if (s == htab->root.sgotplt)
|
||
+ else if (s == elf_hash_table (info)->sgotplt)
|
||
{
|
||
got_size += s->size;
|
||
}
|
||
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
|
||
{
|
||
- if (s->size != 0 && s != htab->root.srelplt)
|
||
+ if (s->size != 0 && s != elf_hash_table (info)->srelplt)
|
||
relocs = TRUE;
|
||
|
||
/* We use the reloc_count field as a counter if we need
|
||
@@ -4013,16 +4747,15 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
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)
|
||
+#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
|
||
|
||
- if (!bfd_link_pic (info))
|
||
+ if (bfd_link_executable (info))
|
||
{
|
||
if (!add_dynamic_entry (DT_DEBUG, 0))
|
||
return FALSE;
|
||
}
|
||
|
||
- if (htab->root.splt->size != 0)
|
||
+ if (elf_hash_table (info)->splt->size != 0)
|
||
{
|
||
if (!add_dynamic_entry (DT_PLTGOT, 0)
|
||
|| !add_dynamic_entry (DT_PLTRELSZ, 0)
|
||
@@ -4031,6 +4764,14 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
return FALSE;
|
||
}
|
||
|
||
+ if (htab->tls_desc_trampoline && plt)
|
||
+ {
|
||
+ if (htab->dt_tlsdesc_plt
|
||
+ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
|
||
+ || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
if (relocs)
|
||
{
|
||
if (!add_dynamic_entry (DT_RELA, 0)
|
||
@@ -4041,7 +4782,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
/* If any dynamic relocs apply to a read-only section,
|
||
then we need a DT_TEXTREL entry. */
|
||
if ((info->flags & DF_TEXTREL) == 0)
|
||
- elf_link_hash_traverse (&htab->root, maybe_set_textrel,
|
||
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
|
||
(void *) info);
|
||
|
||
if ((info->flags & DF_TEXTREL) != 0)
|
||
@@ -4076,10 +4817,11 @@ nds32_relocate_contents (reloc_howto_type *howto, bfd *input_bfd,
|
||
switch (size)
|
||
{
|
||
default:
|
||
+ case 0:
|
||
+ case 1:
|
||
+ case 8:
|
||
abort ();
|
||
break;
|
||
- case 0:
|
||
- return bfd_reloc_ok;
|
||
case 2:
|
||
x = bfd_getb16 (location);
|
||
break;
|
||
@@ -4297,9 +5039,9 @@ nds32_elf_output_symbol_hook (struct bfd_link_info *info,
|
||
else
|
||
source = input_sec->owner->filename;
|
||
|
||
- fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n",
|
||
+ fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n",
|
||
h->root.root.string,
|
||
- (long) (h->root.u.def.value
|
||
+ (h->root.u.def.value
|
||
+ h->root.u.def.section->output_section->vma
|
||
+ h->root.u.def.section->output_offset), source);
|
||
}
|
||
@@ -4340,59 +5082,252 @@ nds32_elf_output_symbol_hook (struct bfd_link_info *info,
|
||
section, which means that the addend must be adjusted
|
||
accordingly. */
|
||
|
||
+/* Return the base VMA address which should be subtracted from real addresses
|
||
+ when resolving @dtpoff relocation.
|
||
+ This is PT_TLS segment p_vaddr. */
|
||
+
|
||
+/* Return the relocation value for @tpoff relocation
|
||
+ if STT_TLS virtual address is ADDRESS. */
|
||
+
|
||
+/* Return the relocation value for @gottpoff relocation
|
||
+ if STT_TLS virtual address is ADDRESS. */
|
||
static bfd_vma
|
||
-dtpoff_base (struct bfd_link_info *info)
|
||
+gottpoff (struct bfd_link_info *info, bfd_vma address)
|
||
{
|
||
+ bfd_vma tp_base;
|
||
+ bfd_vma tp_offset;
|
||
+
|
||
/* 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;
|
||
-}
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
- struct bfd_link_info * info,
|
||
- bfd * input_bfd,
|
||
- asection * input_section,
|
||
- bfd_byte * contents,
|
||
- Elf_Internal_Rela * relocs,
|
||
- Elf_Internal_Sym * local_syms,
|
||
- asection ** local_sections)
|
||
-{
|
||
- Elf_Internal_Shdr *symtab_hdr;
|
||
- struct elf_link_hash_entry **sym_hashes;
|
||
- Elf_Internal_Rela *rel, *relend;
|
||
- bfd_boolean ret = TRUE; /* Assume success. */
|
||
- int align = 0;
|
||
- bfd_reloc_status_type r;
|
||
- const char *errmsg = NULL;
|
||
- bfd_vma gp;
|
||
- struct elf_nds32_link_hash_table *htab;
|
||
- bfd *dynobj;
|
||
- bfd_vma *local_got_offsets;
|
||
- asection *sgot, *splt, *sreloc;
|
||
- bfd_vma high_address;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- int eliminate_gc_relocs;
|
||
- bfd_vma fpbase_addr;
|
||
|
||
- symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||
- sym_hashes = elf_sym_hashes (input_bfd);
|
||
- htab = nds32_elf_hash_table (info);
|
||
- high_address = bfd_get_section_limit (input_bfd, input_section);
|
||
+ tp_base = elf_hash_table (info)->tls_sec->vma;
|
||
+ tp_offset = address - tp_base;
|
||
|
||
- dynobj = htab->root.dynobj;
|
||
- local_got_offsets = elf_local_got_offsets (input_bfd);
|
||
+ return tp_offset;
|
||
+}
|
||
|
||
- sgot = htab->root.sgot;
|
||
- splt = htab->root.splt;
|
||
- sreloc = NULL;
|
||
+/* Move all SECURITY_16 to the final one for each instruction. */
|
||
|
||
- rel = relocs;
|
||
+static void
|
||
+nds32_elf_crc_adjust_reloc (Elf_Internal_Rela *relocs,
|
||
+ Elf_Internal_Rela *relend)
|
||
+{
|
||
+ Elf_Internal_Rela *rel, *crc_rel = NULL;
|
||
+ Elf_Internal_Rela rel_temp;
|
||
+
|
||
+ for (rel = relocs; rel < relend; rel++)
|
||
+ {
|
||
+ if (crc_rel && crc_rel->r_offset == rel->r_offset)
|
||
+ {
|
||
+ memcpy (&rel_temp, rel, sizeof (Elf_Internal_Rela));
|
||
+ memcpy (rel, crc_rel, sizeof (Elf_Internal_Rela));
|
||
+ memcpy (crc_rel, &rel_temp, sizeof (Elf_Internal_Rela));
|
||
+ crc_rel = rel;
|
||
+ }
|
||
+ else if (ELF32_R_TYPE (rel->r_info) == R_NDS32_SECURITY_16)
|
||
+ {
|
||
+ crc_rel = rel;
|
||
+ continue;
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+static bfd_boolean
|
||
+patch_tls_desc_to_ie (bfd_byte *contents, Elf_Internal_Rela *rel, bfd *ibfd)
|
||
+{
|
||
+ /* TLS_GD/TLS_LD model #1
|
||
+ 46 00 00 00 sethi $r0,#0x0
|
||
+ 58 00 00 00 ori $r0,$r0,#0x0
|
||
+ 40 00 74 00 add $r0,$r0,$gp
|
||
+ 04 10 00 00 lwi $r1,[$r0+#0x0]
|
||
+ 4b e0 04 01 jral $lp,$r1 */
|
||
+
|
||
+ /* TLS_GD/TLS_LD model #2
|
||
+ 46 00 00 00 sethi $r0,#0x0
|
||
+ 58 00 00 00 ori $r0,$r0,#0x0
|
||
+ 38 10 74 02 lw $r1,[$r0+($gp<<#0x0)] <= TODO: not necessary $r1 register allocation
|
||
+ 40 00 74 00 add $r0,$r0,$gp
|
||
+ 4b e0 04 01 jral $lp,$r1 */
|
||
+
|
||
+ /* TLS_IE model (non-PIC)
|
||
+ 46 00 00 00 sethi $r0,#0x0
|
||
+ 04 00 00 00 lwi $r0,[$r0+#0x0]
|
||
+ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */
|
||
+
|
||
+ /* TLS_IE model (PIC)
|
||
+ 46 00 00 00 sethi $r0,#0x0
|
||
+ 58 00 00 00 ori $r0,$r0,#0x0
|
||
+ 38 00 74 02 lw $r0,[$r0+($gp<<#0x0)]
|
||
+ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */
|
||
+
|
||
+ /* TLS_GD_TO_IE model
|
||
+ 46 00 00 00 sethi $r0,#0x0
|
||
+ 58 00 00 00 ori $r0,$r0,#0x0
|
||
+ 40 00 74 00 add $r0,$rM,$gp
|
||
+ 04 00 00 01 lwi $r0,[$r0+#0x4]
|
||
+ 40 00 64 00 add $r0,$r0,$r25 */
|
||
+
|
||
+ bfd_boolean rz = FALSE;
|
||
+
|
||
+ typedef struct
|
||
+ {
|
||
+ uint32_t opcode;
|
||
+ uint32_t mask;
|
||
+ } pat_t;
|
||
+
|
||
+ uint32_t patch[3] =
|
||
+ {
|
||
+ 0x40007400, /* add $r0,$rM,$gp */
|
||
+ 0x04000001, /* lwi $r0,[$r0+#0x4] */
|
||
+ 0x40006400, /* add $r0,$r0,$r25 */
|
||
+ };
|
||
+
|
||
+ pat_t mode0[3] =
|
||
+ {
|
||
+ { 0x40000000, 0xfe0003ff },
|
||
+ { 0x04000000, 0xfe000000 },
|
||
+ { 0x4be00001, 0xffff83ff },
|
||
+ };
|
||
+
|
||
+ pat_t mode1[3] =
|
||
+ {
|
||
+ { 0x38007402, 0xfe007fff },
|
||
+ { 0x40007400, 0xfe007fff },
|
||
+ { 0x4be00001, 0xffff83ff },
|
||
+ };
|
||
+
|
||
+ unsigned char *p = contents + rel->r_offset;
|
||
+
|
||
+ uint32_t insn;
|
||
+ uint32_t regidx = 0;
|
||
+ insn = bfd_getb32 (p);
|
||
+ if (INSN_SETHI == (0xfe0fffffu & insn))
|
||
+ {
|
||
+ regidx = 0x1f & (insn >> 20);
|
||
+ p += 4;
|
||
+ }
|
||
+
|
||
+ insn = bfd_getb32 (p);
|
||
+ if (INSN_ORI == (0xfe007fffu & insn))
|
||
+ {
|
||
+ regidx = 0x1f & (insn >> 20);
|
||
+ p += 4;
|
||
+ }
|
||
+
|
||
+ if (patch[2] == bfd_getb32 (p + 8)) /* character instruction */
|
||
+ {
|
||
+ /* already patched? */
|
||
+ if ((patch[0] == (0xfff07fffu & bfd_getb32 (p + 0))) &&
|
||
+ (patch[1] == bfd_getb32 (p + 4)))
|
||
+ rz = TRUE;
|
||
+ }
|
||
+ else if (mode0[0].opcode == (mode0[0].mask & bfd_getb32 (p + 0)))
|
||
+ {
|
||
+ if ((mode0[1].opcode == (mode0[1].mask & bfd_getb32 (p + 4))) &&
|
||
+ (mode0[2].opcode == (mode0[2].mask & bfd_getb32 (p + 8))))
|
||
+ {
|
||
+ bfd_putb32 (patch[0] | (regidx << 15), p + 0);
|
||
+ bfd_putb32 (patch[1], p + 4);
|
||
+ bfd_putb32 (patch[2], p + 8);
|
||
+ rz = TRUE;
|
||
+ }
|
||
+ }
|
||
+ else if (mode1[0].opcode == (mode1[0].mask & bfd_getb32 (p + 0)))
|
||
+ {
|
||
+ if ((mode1[1].opcode == (mode1[1].mask & bfd_getb32 (p + 4))) &&
|
||
+ (mode1[2].opcode == (mode1[2].mask & bfd_getb32 (p + 8))))
|
||
+ {
|
||
+ bfd_putb32 (patch[0] | (regidx << 15), p + 0);
|
||
+ bfd_putb32 (patch[1], p + 4);
|
||
+ bfd_putb32 (patch[2], p + 8);
|
||
+ rz = TRUE;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (!rz)
|
||
+ {
|
||
+ printf ("%s: %s @ 0x%08x\n", __func__, ibfd->filename,
|
||
+ (int) rel->r_offset);
|
||
+ BFD_ASSERT(0); /* unsupported pattern */
|
||
+ }
|
||
+
|
||
+ return rz;
|
||
+}
|
||
+
|
||
+static enum elf_nds32_tls_type
|
||
+get_tls_type (enum elf_nds32_reloc_type r_type, struct elf_link_hash_entry *h);
|
||
+
|
||
+static unsigned int
|
||
+ones32 (register unsigned int x)
|
||
+{
|
||
+ /* 32-bit recursive reduction using SWAR...
|
||
+ but first step is mapping 2-bit values
|
||
+ into sum of 2 1-bit values in sneaky way. */
|
||
+ x -= ((x >> 1) & 0x55555555);
|
||
+ x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
|
||
+ x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||
+ x += (x >> 8);
|
||
+ x += (x >> 16);
|
||
+ return (x & 0x0000003f);
|
||
+}
|
||
+
|
||
+static unsigned int
|
||
+fls (register unsigned int x)
|
||
+{
|
||
+ return ffs (x & (-x));
|
||
+}
|
||
+
|
||
+#define nds32_elf_local_tlsdesc_gotent(bfd) \
|
||
+ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent)
|
||
+
|
||
+static bfd_boolean
|
||
+nds32_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||
+ struct bfd_link_info *info, bfd *input_bfd,
|
||
+ asection *input_section, bfd_byte *contents,
|
||
+ Elf_Internal_Rela *relocs,
|
||
+ Elf_Internal_Sym *local_syms,
|
||
+ asection **local_sections)
|
||
+{
|
||
+ Elf_Internal_Shdr *symtab_hdr;
|
||
+ struct elf_link_hash_entry **sym_hashes;
|
||
+ Elf_Internal_Rela *rel, *relend;
|
||
+ bfd_boolean ret = TRUE; /* Assume success. */
|
||
+ int align = 0;
|
||
+ bfd_reloc_status_type r;
|
||
+ const char *errmsg = NULL;
|
||
+ bfd_vma gp;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
+ struct elf_nds32_link_hash_table *htab;
|
||
+ bfd *dynobj;
|
||
+ bfd_vma *local_got_offsets;
|
||
+ asection *sgot, *splt, *sreloc;
|
||
+ bfd_vma high_address;
|
||
+ struct elf_nds32_link_hash_table *table;
|
||
+ int eliminate_gc_relocs;
|
||
+ bfd_vma fpbase_addr;
|
||
+ Elf_Internal_Rela *crc_rel = NULL;
|
||
+
|
||
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||
+ sym_hashes = elf_sym_hashes (input_bfd);
|
||
+ ehtab = elf_hash_table (info);
|
||
+ htab = nds32_elf_hash_table (info);
|
||
+ high_address = bfd_get_section_limit (input_bfd, input_section);
|
||
+
|
||
+ dynobj = htab->root.dynobj;
|
||
+ local_got_offsets = elf_local_got_offsets (input_bfd);
|
||
+
|
||
+ sgot = ehtab->sgot;
|
||
+ splt = ehtab->splt;
|
||
+ sreloc = NULL;
|
||
+
|
||
+ rel = relocs;
|
||
relend = relocs + input_section->reloc_count;
|
||
|
||
table = nds32_elf_hash_table (info);
|
||
eliminate_gc_relocs = table->eliminate_gc_relocs;
|
||
+
|
||
+ /* explain _SDA_BASE_ */
|
||
/* By this time, we can adjust the value of _SDA_BASE_. */
|
||
if ((!bfd_link_relocatable (info)))
|
||
{
|
||
@@ -4402,40 +5337,37 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
return FALSE;
|
||
}
|
||
|
||
- if (is_ITB_BASE_set == 0)
|
||
- {
|
||
- /* Set the _ITB_BASE_. */
|
||
- if (!nds32_elf_ex9_itb_base (info))
|
||
- {
|
||
- _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"),
|
||
- output_bfd);
|
||
- bfd_set_error (bfd_error_bad_value);
|
||
- }
|
||
- }
|
||
-
|
||
- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
|
||
- if (!nds32_elf_ifc_reloc ())
|
||
- _bfd_error_handler (_("error: IFC relocation error."));
|
||
+#ifdef NDS32_LINUX_TOOLCHAIN
|
||
+ /* Do TLS model conversion once at first. */
|
||
+ nds32_elf_unify_tls_model (input_bfd, input_section, contents, info);
|
||
+#endif
|
||
|
||
- /* Relocation for .ex9.itable. */
|
||
- if (table->target_optimize & NDS32_RELAX_EX9_ON
|
||
- || (table->ex9_import_file && table->update_ex9_table))
|
||
- nds32_elf_ex9_reloc_jmp (info);
|
||
+ if (indirect_call_table.count > 0)
|
||
+ nds32_elf_ict_relocate (output_bfd, info);
|
||
|
||
/* Use gp as fp to prevent truncated fit. Because in relaxation time
|
||
the fp value is set as gp, and it has be reverted for instruction
|
||
setting fp. */
|
||
fpbase_addr = elf_gp (output_bfd);
|
||
|
||
+ /* Move all SECURITY_16 to the final one for each instruction. */
|
||
+ nds32_elf_crc_adjust_reloc (relocs, relend);
|
||
+
|
||
+ /* Deal with (dynamic) relocations. */
|
||
for (rel = relocs; rel < relend; rel++)
|
||
{
|
||
enum elf_nds32_reloc_type r_type;
|
||
reloc_howto_type *howto = NULL;
|
||
unsigned long r_symndx;
|
||
struct elf_link_hash_entry *h = NULL;
|
||
+ struct bfd_link_hash_entry *h2;
|
||
Elf_Internal_Sym *sym = NULL;
|
||
asection *sec;
|
||
bfd_vma relocation;
|
||
+ struct elf_nds32_ict_hash_entry *entry;
|
||
+ bfd_vma relocation_sym = 0xdeadbeef;
|
||
+ Elf_Internal_Rela *lorel;
|
||
+ bfd_vma off;
|
||
|
||
/* We can't modify r_addend here as elf_link_input_bfd has an assert to
|
||
ensure it's zero (we use REL relocs, not RELA). Therefore this
|
||
@@ -4463,12 +5395,17 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
|| r_type == R_NDS32_RELA_GNU_VTINHERIT
|
||
|| (r_type >= R_NDS32_INSN16 && r_type <= R_NDS32_25_FIXED_RELA)
|
||
|| r_type == R_NDS32_DATA
|
||
- || r_type == R_NDS32_TRAN
|
||
- || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP7))
|
||
+ || r_type == R_NDS32_TRAN)
|
||
continue;
|
||
|
||
- /* If we enter the fp-as-gp region. Resolve the address
|
||
- of best fp-base. */
|
||
+ /* Save security beginning. */
|
||
+ if (r_type == R_NDS32_SECURITY_16 && crc_rel == NULL)
|
||
+ {
|
||
+ crc_rel = rel;
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ /* If we enter the fp-as-gp region. Resolve the address of best fp-base. */
|
||
if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_BEGIN
|
||
&& (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
|
||
{
|
||
@@ -4485,9 +5422,13 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
fpbase_addr = elf_gp (output_bfd);
|
||
}
|
||
|
||
- if (((r_type >= R_NDS32_DWARF2_OP1_RELA
|
||
- && r_type <= R_NDS32_DWARF2_LEB_RELA)
|
||
- || r_type >= R_NDS32_RELAX_ENTRY) && !bfd_link_relocatable (info))
|
||
+ /* Skip the relocations used for relaxation. */
|
||
+ /* Fix ticket-11832, we have to update LONGCALL and LONGJUMP
|
||
+ relocations when generating the relocatable files. */
|
||
+ if (!bfd_link_relocatable (info)
|
||
+ && (r_type >= R_NDS32_RELAX_ENTRY
|
||
+ || (r_type >= R_NDS32_LONGCALL4
|
||
+ && r_type <= R_NDS32_LONGJUMP7)))
|
||
continue;
|
||
|
||
howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
|
||
@@ -4506,10 +5447,26 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
|
||
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
|
||
addend = rel->r_addend;
|
||
+
|
||
+ /* keep symbol location for static TLS_IE GOT entry */
|
||
+ relocation_sym = relocation;
|
||
+ 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. */
|
||
+ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
|
||
+ rel->r_addend += sec->output_offset + sym->st_value;
|
||
+
|
||
+ continue;
|
||
+ }
|
||
}
|
||
else
|
||
{
|
||
/* External symbol. */
|
||
+ if (bfd_link_relocatable (info))
|
||
+ continue;
|
||
bfd_boolean warned, ignored, unresolved_reloc;
|
||
int symndx = r_symndx - symtab_hdr->sh_info;
|
||
|
||
@@ -4518,10 +5475,27 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
relocation, unresolved_reloc, warned,
|
||
ignored);
|
||
|
||
+ /* keep symbol location for static TLS_IE GOT entry */
|
||
+ relocation_sym = relocation;
|
||
+
|
||
/* la $fp, _FP_BASE_ is per-function (region).
|
||
Handle it specially. */
|
||
switch ((int) r_type)
|
||
{
|
||
+ case R_NDS32_HI20_RELA:
|
||
+ case R_NDS32_LO12S0_RELA:
|
||
+ if (strcmp (elf_sym_hashes (input_bfd)[symndx]->root.root.string,
|
||
+ FP_BASE_NAME) == 0)
|
||
+ {
|
||
+ if (!bfd_link_pie (info))
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ ("%pB: warning: _FP_BASE_ setting insns relaxation failed.",
|
||
+ input_bfd);
|
||
+ }
|
||
+ relocation = fpbase_addr;
|
||
+ break;
|
||
+ }
|
||
case R_NDS32_SDA19S0_RELA:
|
||
case R_NDS32_SDA15S0_RELA:
|
||
case R_NDS32_20_RELA:
|
||
@@ -4532,19 +5506,6 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
break;
|
||
}
|
||
}
|
||
-
|
||
- }
|
||
-
|
||
- 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. */
|
||
- if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
|
||
- rel->r_addend += sec->output_offset + sym->st_value;
|
||
-
|
||
- continue;
|
||
}
|
||
|
||
/* Sanity check the address. */
|
||
@@ -4554,16 +5515,14 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
goto check_reloc;
|
||
}
|
||
|
||
- if ((r_type >= R_NDS32_DWARF2_OP1_RELA
|
||
- && r_type <= R_NDS32_DWARF2_LEB_RELA)
|
||
- || r_type >= R_NDS32_RELAX_ENTRY)
|
||
+ if (r_type >= R_NDS32_RELAX_ENTRY)
|
||
continue;
|
||
|
||
switch ((int) r_type)
|
||
{
|
||
case R_NDS32_GOTOFF:
|
||
/* Relocation is relative to the start of the global offset
|
||
- table (for ld24 rx, #uimm24), e.g. access at label+addend
|
||
+ table (for ld24 rx, #uimm24), e.g. access at label + addend
|
||
|
||
ld24 rx. #label@GOTOFF + addend
|
||
sub rx, r12. */
|
||
@@ -4605,12 +5564,18 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
case R_NDS32_PLT_GOTREL_LO15:
|
||
case R_NDS32_PLT_GOTREL_LO19:
|
||
case R_NDS32_PLT_GOTREL_LO20:
|
||
- if (h == NULL || h->forced_local || h->plt.offset == (bfd_vma) - 1)
|
||
+ if (h == NULL
|
||
+ || h->forced_local
|
||
+ || h->plt.offset == (bfd_vma) -1
|
||
+ || (bfd_link_pie (info) && h->def_regular))
|
||
{
|
||
+ /* TODO: find better checking to optimize PIE PLT relocations. */
|
||
/* We didn't make a PLT entry for this symbol. This
|
||
happens when statically linking PIC code, or when
|
||
using -Bsymbolic. */
|
||
- relocation -= elf_gp (output_bfd);
|
||
+ if (h)
|
||
+ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */
|
||
+ relocation -= elf_gp(output_bfd);
|
||
break;
|
||
}
|
||
|
||
@@ -4661,21 +5626,18 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
|
||
case R_NDS32_GOTPC_HI20:
|
||
case R_NDS32_GOTPC_LO12:
|
||
- {
|
||
- /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
|
||
- bl .+4
|
||
- seth rx,#high(_GLOBAL_OFFSET_TABLE_)
|
||
- or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
|
||
- or
|
||
- bl .+4
|
||
- seth rx,#shigh(_GLOBAL_OFFSET_TABLE_)
|
||
- add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
|
||
- */
|
||
- relocation = elf_gp (output_bfd);
|
||
- relocation -= (input_section->output_section->vma
|
||
- + input_section->output_offset + rel->r_offset);
|
||
- break;
|
||
- }
|
||
+ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
|
||
+ bl .+4
|
||
+ seth rx,#high(_GLOBAL_OFFSET_TABLE_)
|
||
+ or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
|
||
+ or
|
||
+ bl .+4
|
||
+ seth rx,#shigh(_GLOBAL_OFFSET_TABLE_)
|
||
+ add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) */
|
||
+ relocation = elf_gp (output_bfd);
|
||
+ relocation -= (input_section->output_section->vma
|
||
+ + input_section->output_offset + rel->r_offset);
|
||
+ break;
|
||
|
||
case R_NDS32_GOT20:
|
||
/* Fall through. */
|
||
@@ -4687,17 +5649,14 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
offset table. */
|
||
BFD_ASSERT (sgot != NULL);
|
||
|
||
- if (h != NULL)
|
||
+ if (h != NULL) /* External symbol */
|
||
{
|
||
bfd_boolean dyn;
|
||
- bfd_vma off;
|
||
|
||
off = h->got.offset;
|
||
BFD_ASSERT (off != (bfd_vma) - 1);
|
||
dyn = htab->root.dynamic_sections_created;
|
||
- if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
|
||
- bfd_link_pic (info),
|
||
- h)
|
||
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
|
||
|| (bfd_link_pic (info)
|
||
&& (info->symbolic
|
||
|| h->dynindx == -1
|
||
@@ -4707,28 +5666,27 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
-Bsymbolic link and the symbol is defined
|
||
locally, or the symbol was forced to be local
|
||
because of a version file. We must initialize
|
||
- this entry in the global offset table. Since the
|
||
+ this entry in the global offset table. Since the
|
||
offset must always be a multiple of 4, we use the
|
||
least significant bit to record whether we have
|
||
initialized it already.
|
||
|
||
When doing a dynamic link, we create a .rela.got
|
||
- relocation entry to initialize the value. This
|
||
+ relocation entry to initialize the value. This
|
||
is done in the finish_dynamic_symbol routine. */
|
||
- if ((off & 1) != 0)
|
||
+ if ((off & 1) != 0) /* clear LSB */
|
||
off &= ~1;
|
||
else
|
||
{
|
||
bfd_put_32 (output_bfd, relocation, sgot->contents + off);
|
||
- h->got.offset |= 1;
|
||
+ h->got.offset |= 1; /* mark initialized */
|
||
}
|
||
}
|
||
relocation = sgot->output_section->vma + sgot->output_offset + off
|
||
- - elf_gp (output_bfd);
|
||
+ - elf_gp (output_bfd);
|
||
}
|
||
- else
|
||
+ else /* Local symbol */
|
||
{
|
||
- bfd_vma off;
|
||
bfd_byte *loc;
|
||
|
||
BFD_ASSERT (local_got_offsets != NULL
|
||
@@ -4736,10 +5694,10 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
|
||
off = local_got_offsets[r_symndx];
|
||
|
||
- /* The offset must always be a multiple of 4. We use
|
||
+ /* The offset must always be a multiple of 4. We use
|
||
the least significant bit to record whether we have
|
||
already processed this entry. */
|
||
- if ((off & 1) != 0)
|
||
+ if ((off & 1) != 0) /* clear LSB */
|
||
off &= ~1;
|
||
else
|
||
{
|
||
@@ -4752,7 +5710,7 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
|
||
/* We need to generate a R_NDS32_RELATIVE reloc
|
||
for the dynamic linker. */
|
||
- srelgot = htab->root.srelgot;
|
||
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
|
||
BFD_ASSERT (srelgot != NULL);
|
||
|
||
outrel.r_offset = (elf_gp (output_bfd)
|
||
@@ -4768,11 +5726,57 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
local_got_offsets[r_symndx] |= 1;
|
||
}
|
||
relocation = sgot->output_section->vma + sgot->output_offset + off
|
||
- - elf_gp (output_bfd);
|
||
+ - elf_gp (output_bfd);
|
||
}
|
||
|
||
break;
|
||
|
||
+ case R_NDS32_25_PCREL_RELA:
|
||
+ case R_NDS32_HI20_RELA:
|
||
+ case R_NDS32_LO12S0_RELA:
|
||
+ case R_NDS32_LO12S2_RELA:
|
||
+ /* Merge normal and indirect call functions. */
|
||
+ if (!ignore_indirect_call && h
|
||
+ && elf32_nds32_hash_entry (h)->indirect_call)
|
||
+ {
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: Error: there are mixed indirect call function in"
|
||
+ " ICT large model\'%s\'\n"),
|
||
+ input_bfd, h->root.root.string);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+ else
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: Warning: there are mixed indirect call function"
|
||
+ " \'%s\'\n"), input_bfd, h->root.root.string);
|
||
+
|
||
+ entry = (struct elf_nds32_ict_hash_entry*)
|
||
+ bfd_hash_lookup (&indirect_call_table, h->root.root.string,
|
||
+ FALSE, FALSE);
|
||
+ if (!entry)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB %pA: internal error indirect call relocation "
|
||
+ "0x%lx without hash.\n"),
|
||
+ input_bfd, sec, rel->r_offset);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ h2 = bfd_link_hash_lookup (info->hash,
|
||
+ "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ relocation = ((h2->u.def.value
|
||
+ + h2->u.def.section->output_section->vma
|
||
+ + h2->u.def.section->output_offset)
|
||
+ + (entry->order * 4));
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ /* Fall through. */
|
||
case R_NDS32_16_RELA:
|
||
case R_NDS32_20_RELA:
|
||
case R_NDS32_5_RELA:
|
||
@@ -4782,14 +5786,10 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
case R_NDS32_10_UPCREL_RELA:
|
||
case R_NDS32_15_PCREL_RELA:
|
||
case R_NDS32_17_PCREL_RELA:
|
||
- case R_NDS32_25_PCREL_RELA:
|
||
- case R_NDS32_HI20_RELA:
|
||
case R_NDS32_LO12S3_RELA:
|
||
- case R_NDS32_LO12S2_RELA:
|
||
case R_NDS32_LO12S2_DP_RELA:
|
||
case R_NDS32_LO12S2_SP_RELA:
|
||
case R_NDS32_LO12S1_RELA:
|
||
- case R_NDS32_LO12S0_RELA:
|
||
case R_NDS32_LO12S0_ORI_RELA:
|
||
if (bfd_link_pic (info) && r_symndx != 0
|
||
&& (input_section->flags & SEC_ALLOC) != 0
|
||
@@ -4863,15 +5863,37 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
become local. */
|
||
if (h == NULL
|
||
|| ((info->symbolic || h->dynindx == -1)
|
||
- && h->def_regular))
|
||
+ && h->def_regular)
|
||
+ || (bfd_link_pie (info) && h->def_regular))
|
||
{
|
||
relocate = TRUE;
|
||
outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
|
||
outrel.r_addend = relocation + rel->r_addend;
|
||
+ if (h)
|
||
+ {
|
||
+ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */
|
||
+
|
||
+ BFD_ASSERT (sgot != NULL);
|
||
+ /* If we did not allocate got entry for the symbol, we can not
|
||
+ fill the nonexistent got entry. */
|
||
+ if (h->got.offset != (bfd_vma) -1 && (h->got.offset & 1) == 0)
|
||
+ {
|
||
+ bfd_put_32 (output_bfd, outrel.r_addend,
|
||
+ sgot->contents + h->got.offset);
|
||
+ }
|
||
+ }
|
||
}
|
||
else
|
||
{
|
||
- BFD_ASSERT (h->dynindx != -1);
|
||
+ if (h->dynindx == -1)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: relocation %s against `%s' can not be used when"
|
||
+ "making a shared object; recompile with -fPIC"),
|
||
+ input_bfd, nds32_elf_howto_table[r_type].name, h->root.root.string);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
||
outrel.r_addend = rel->r_addend;
|
||
}
|
||
@@ -4895,8 +5917,8 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
if (bfd_link_pic (info))
|
||
{
|
||
_bfd_error_handler
|
||
- (_("%B: warning: cannot deal R_NDS32_25_ABS_RELA in shared "
|
||
- "mode."), input_bfd);
|
||
+ (_("%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared mode."),
|
||
+ bfd_get_filename (input_bfd));
|
||
return FALSE;
|
||
}
|
||
break;
|
||
@@ -4908,123 +5930,115 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
goto check_reloc;
|
||
|
||
case R_NDS32_HI20:
|
||
+ /* We allow an arbitrary number of HI20 relocs before the
|
||
+ LO12 reloc. This permits GCC to emit the HI and LO relocs
|
||
+ itself. */
|
||
+ for (lorel = rel + 1;
|
||
+ (lorel < relend
|
||
+ && ELF32_R_TYPE (lorel->r_info) == R_NDS32_HI20); lorel++)
|
||
+ continue;
|
||
+ if (lorel < relend
|
||
+ && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3
|
||
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2
|
||
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1
|
||
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0))
|
||
{
|
||
- Elf_Internal_Rela *lorel;
|
||
-
|
||
- /* We allow an arbitrary number of HI20 relocs before the
|
||
- LO12 reloc. This permits gcc to emit the HI and LO relocs
|
||
- itself. */
|
||
- for (lorel = rel + 1;
|
||
- (lorel < relend
|
||
- && ELF32_R_TYPE (lorel->r_info) == R_NDS32_HI20); lorel++)
|
||
- continue;
|
||
- if (lorel < relend
|
||
- && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3
|
||
- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2
|
||
- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1
|
||
- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0))
|
||
- {
|
||
- nds32_elf_relocate_hi20 (input_bfd, r_type, rel, lorel,
|
||
- contents, relocation + addend);
|
||
- r = bfd_reloc_ok;
|
||
- }
|
||
- else
|
||
- r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||
- contents, offset, relocation,
|
||
- addend);
|
||
+ nds32_elf_relocate_hi20 (input_bfd, r_type, rel, lorel,
|
||
+ contents, relocation + addend);
|
||
+ r = bfd_reloc_ok;
|
||
}
|
||
+ else
|
||
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||
+ contents, offset, relocation,
|
||
+ addend);
|
||
|
||
goto check_reloc;
|
||
|
||
case R_NDS32_GOT17S2_RELA:
|
||
case R_NDS32_GOT15S2_RELA:
|
||
+ BFD_ASSERT (sgot != NULL);
|
||
+
|
||
+ if (h != NULL)
|
||
{
|
||
- bfd_vma off;
|
||
+ bfd_boolean dyn;
|
||
|
||
- BFD_ASSERT (sgot != NULL);
|
||
+ off = h->got.offset;
|
||
+ BFD_ASSERT (off != (bfd_vma) - 1);
|
||
|
||
- if (h != NULL)
|
||
+ dyn = htab->root.dynamic_sections_created;
|
||
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
|
||
+ (dyn, bfd_link_pic (info), h) || (bfd_link_pic (info)
|
||
+ && (info->symbolic
|
||
+ || h->dynindx == -1
|
||
+ || h->forced_local)
|
||
+ && h->def_regular))
|
||
{
|
||
- bfd_boolean dyn;
|
||
-
|
||
- off = h->got.offset;
|
||
- BFD_ASSERT (off != (bfd_vma) - 1);
|
||
-
|
||
- dyn = htab->root.dynamic_sections_created;
|
||
- if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
|
||
- (dyn, bfd_link_pic (info), h)
|
||
- || (bfd_link_pic (info)
|
||
- && (info->symbolic
|
||
- || h->dynindx == -1
|
||
- || h->forced_local)
|
||
- && h->def_regular))
|
||
+ /* This is actually a static link, or it is a
|
||
+ -Bsymbolic link and the symbol is defined
|
||
+ locally, or the symbol was forced to be local
|
||
+ because of a version file. We must initialize
|
||
+ this entry in the global offset table. Since the
|
||
+ offset must always be a multiple of 4, we use the
|
||
+ least significant bit to record whether we have
|
||
+ initialized it already.
|
||
+
|
||
+ When doing a dynamic link, we create a .rela.got
|
||
+ relocation entry to initialize the value. This
|
||
+ is done in the finish_dynamic_symbol routine. */
|
||
+ if ((off & 1) != 0)
|
||
+ off &= ~1;
|
||
+ else
|
||
{
|
||
- /* This is actually a static link, or it is a
|
||
- -Bsymbolic link and the symbol is defined
|
||
- locally, or the symbol was forced to be local
|
||
- because of a version file. We must initialize
|
||
- this entry in the global offset table. Since the
|
||
- offset must always be a multiple of 4, we use the
|
||
- least significant bit to record whether we have
|
||
- initialized it already.
|
||
-
|
||
- When doing a dynamic link, we create a .rela.got
|
||
- relocation entry to initialize the value. This
|
||
- is done in the finish_dynamic_symbol routine. */
|
||
- if ((off & 1) != 0)
|
||
- off &= ~1;
|
||
- else
|
||
- {
|
||
- bfd_put_32 (output_bfd, relocation,
|
||
- sgot->contents + off);
|
||
- h->got.offset |= 1;
|
||
- }
|
||
+ bfd_put_32 (output_bfd, relocation,
|
||
+ sgot->contents + off);
|
||
+ h->got.offset |= 1;
|
||
}
|
||
}
|
||
- else
|
||
- {
|
||
- bfd_byte *loc;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ bfd_byte *loc;
|
||
|
||
- BFD_ASSERT (local_got_offsets != NULL
|
||
- && local_got_offsets[r_symndx] != (bfd_vma) - 1);
|
||
+ BFD_ASSERT (local_got_offsets != NULL
|
||
+ && local_got_offsets[r_symndx] != (bfd_vma) - 1);
|
||
|
||
- off = local_got_offsets[r_symndx];
|
||
+ off = local_got_offsets[r_symndx];
|
||
|
||
- /* The offset must always be a multiple of 4. We use
|
||
- the least significant bit to record whether we have
|
||
- already processed this entry. */
|
||
- if ((off & 1) != 0)
|
||
- off &= ~1;
|
||
- else
|
||
+ /* The offset must always be a multiple of 4. We use
|
||
+ the least significant bit to record whether we have
|
||
+ already processed this entry. */
|
||
+ if ((off & 1) != 0)
|
||
+ off &= ~1;
|
||
+ else
|
||
+ {
|
||
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
|
||
+
|
||
+ if (bfd_link_pic (info))
|
||
{
|
||
- bfd_put_32 (output_bfd, relocation, sgot->contents + off);
|
||
+ asection *srelgot;
|
||
+ Elf_Internal_Rela outrel;
|
||
|
||
- if (bfd_link_pic (info))
|
||
- {
|
||
- asection *srelgot;
|
||
- Elf_Internal_Rela outrel;
|
||
-
|
||
- /* We need to generate a R_NDS32_RELATIVE reloc
|
||
- for the dynamic linker. */
|
||
- srelgot = htab->root.srelgot;
|
||
- BFD_ASSERT (srelgot != NULL);
|
||
-
|
||
- outrel.r_offset = (elf_gp (output_bfd)
|
||
- + sgot->output_offset + off);
|
||
- outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
|
||
- outrel.r_addend = relocation;
|
||
- loc = srelgot->contents;
|
||
- loc +=
|
||
- srelgot->reloc_count * sizeof (Elf32_External_Rela);
|
||
- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||
- ++srelgot->reloc_count;
|
||
- }
|
||
- local_got_offsets[r_symndx] |= 1;
|
||
+ /* We need to generate a R_NDS32_RELATIVE reloc
|
||
+ for the dynamic linker. */
|
||
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
|
||
+ BFD_ASSERT (srelgot != NULL);
|
||
+
|
||
+ outrel.r_offset = (elf_gp (output_bfd)
|
||
+ + sgot->output_offset + off);
|
||
+ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
|
||
+ outrel.r_addend = relocation;
|
||
+ loc = srelgot->contents;
|
||
+ loc +=
|
||
+ srelgot->reloc_count * sizeof (Elf32_External_Rela);
|
||
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||
+ ++srelgot->reloc_count;
|
||
}
|
||
+ local_got_offsets[r_symndx] |= 1;
|
||
}
|
||
- relocation = sgot->output_section->vma + sgot->output_offset + off
|
||
- - elf_gp (output_bfd);
|
||
}
|
||
+ relocation = sgot->output_section->vma + sgot->output_offset + off
|
||
+ - elf_gp (output_bfd);
|
||
+
|
||
if (relocation & align)
|
||
{
|
||
/* Incorrect alignment. */
|
||
@@ -5060,50 +6074,48 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||
case R_NDS32_SDA19S0_RELA:
|
||
case R_NDS32_SDA15S0_RELA:
|
||
case R_NDS32_SDA15S0:
|
||
- {
|
||
- align = 0x0;
|
||
+ align = 0x0;
|
||
handle_sda:
|
||
- BFD_ASSERT (sec != NULL);
|
||
+ BFD_ASSERT (sec != NULL);
|
||
|
||
- /* If the symbol is in the abs section, the out_bfd will be null.
|
||
- This happens when the relocation has a symbol@GOTOFF. */
|
||
- r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE);
|
||
- if (r != bfd_reloc_ok)
|
||
- {
|
||
- _bfd_error_handler
|
||
- (_("%B: warning: relocate SDA_BASE failed."), input_bfd);
|
||
- ret = FALSE;
|
||
- goto check_reloc;
|
||
- }
|
||
+ /* If the symbol is in the abs section, the out_bfd will be null.
|
||
+ This happens when the relocation has a symbol@GOTOFF. */
|
||
+ r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE);
|
||
+ if (r != bfd_reloc_ok)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%B: warning: relocate SDA_BASE failed."), input_bfd);
|
||
+ ret = FALSE;
|
||
+ goto check_reloc;
|
||
+ }
|
||
|
||
- /* At this point `relocation' contains the object's
|
||
- address. */
|
||
- if (r_type == R_NDS32_SDA_FP7U2_RELA)
|
||
- {
|
||
- relocation -= fpbase_addr;
|
||
- }
|
||
- else
|
||
- relocation -= gp;
|
||
- /* Now it contains the offset from _SDA_BASE_. */
|
||
+ /* At this point `relocation' contains the object's
|
||
+ address. */
|
||
+ if (r_type == R_NDS32_SDA_FP7U2_RELA)
|
||
+ {
|
||
+ relocation -= fpbase_addr;
|
||
+ }
|
||
+ else
|
||
+ relocation -= gp;
|
||
+ /* Now it contains the offset from _SDA_BASE_. */
|
||
|
||
- /* Make sure alignment is correct. */
|
||
+ /* Make sure alignment is correct. */
|
||
|
||
- if (relocation & align)
|
||
- {
|
||
- /* Incorrect alignment. */
|
||
- _bfd_error_handler
|
||
- /* xgettext:c-format */
|
||
- (_("%B(%A): warning: unaligned small data access of type %d."),
|
||
- input_bfd, input_section, r_type);
|
||
- ret = FALSE;
|
||
- goto check_reloc;
|
||
- }
|
||
+ if (relocation & align)
|
||
+ {
|
||
+ /* Incorrect alignment. */
|
||
+ _bfd_error_handler
|
||
+ (_("%B(%A): warning: unaligned small data access of type %d."),
|
||
+ input_bfd, input_section, r_type);
|
||
+ ret = FALSE;
|
||
+ goto check_reloc;
|
||
}
|
||
|
||
break;
|
||
case R_NDS32_17IFC_PCREL_RELA:
|
||
case R_NDS32_10IFCU_PCREL_RELA:
|
||
- /* do nothing */
|
||
+ ifc_flag = TRUE;
|
||
+ /* do nothing */
|
||
break;
|
||
|
||
case R_NDS32_TLS_LE_HI20:
|
||
@@ -5112,28 +6124,38 @@ handle_sda:
|
||
case R_NDS32_TLS_LE_15S0:
|
||
case R_NDS32_TLS_LE_15S1:
|
||
case R_NDS32_TLS_LE_15S2:
|
||
+ /* TODO: we do not have garbage collection for got entries.
|
||
+ IE to LE may have one empty entry, and DESC to LE may
|
||
+ have two. */
|
||
if (elf_hash_table (info)->tls_sec != NULL)
|
||
relocation -= (elf_hash_table (info)->tls_sec->vma + TP_OFFSET);
|
||
break;
|
||
case R_NDS32_TLS_IE_HI20:
|
||
case R_NDS32_TLS_IE_LO12S2:
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ case R_NDS32_TLS_IE_LO12:
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ case R_NDS32_TLS_IEGP_LO12S2:
|
||
{
|
||
/* Relocation is to the entry for this symbol in the global
|
||
offset table. */
|
||
- unsigned int tls_type;
|
||
+ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type;
|
||
asection *srelgot;
|
||
Elf_Internal_Rela outrel;
|
||
- bfd_vma off;
|
||
bfd_byte *loc;
|
||
int indx = 0;
|
||
|
||
+ eff_tls_type = org_tls_type = get_tls_type (r_type, h);
|
||
+
|
||
BFD_ASSERT (sgot != NULL);
|
||
if (h != NULL)
|
||
{
|
||
bfd_boolean dyn;
|
||
|
||
off = h->got.offset;
|
||
- BFD_ASSERT (off != (bfd_vma) - 1);
|
||
+ BFD_ASSERT (off != (bfd_vma) -1);
|
||
dyn = htab->root.dynamic_sections_created;
|
||
tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type;
|
||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
|
||
@@ -5143,64 +6165,184 @@ handle_sda:
|
||
}
|
||
else
|
||
{
|
||
- /* Never happen currently. */
|
||
BFD_ASSERT (local_got_offsets != NULL
|
||
&& local_got_offsets[r_symndx] != (bfd_vma) - 1);
|
||
|
||
off = local_got_offsets[r_symndx];
|
||
-
|
||
tls_type = elf32_nds32_local_got_tls_type (input_bfd)[r_symndx];
|
||
}
|
||
+
|
||
relocation = sgot->output_section->vma + sgot->output_offset + off;
|
||
|
||
- if (r_type == R_NDS32_TLS_IE_LO12S2)
|
||
- break;
|
||
+ if (1 < ones32 (tls_type))
|
||
+ {
|
||
+ eff_tls_type = 1 << (fls (tls_type) - 1);
|
||
+ /* TLS model shall be handled in nds32_elf_unify_tls_model () */
|
||
+
|
||
+ /* TLS model X -> LE is not implement yet!
|
||
+ * workaround here! */
|
||
+ if (eff_tls_type == GOT_TLS_LE)
|
||
+ {
|
||
+ eff_tls_type = 1 << (fls (tls_type ^ eff_tls_type) - 1);
|
||
+ }
|
||
+ }
|
||
|
||
/* The offset must always be a multiple of 4. We use
|
||
the least significant bit to record whether we have
|
||
already processed this entry. */
|
||
- if ((off & 1) != 0)
|
||
- off &= ~1;
|
||
+ bfd_boolean need_relocs = FALSE;
|
||
+ srelgot = ehtab->srelgot;
|
||
+ if ((bfd_link_pic (info) || indx != 0)
|
||
+ && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||
+ || h->root.type != bfd_link_hash_undefweak))
|
||
+ {
|
||
+ need_relocs = TRUE;
|
||
+ BFD_ASSERT (srelgot != NULL);
|
||
+ }
|
||
+
|
||
+ if (off & 1)
|
||
+ {
|
||
+ off &= ~1;
|
||
+ relocation &= ~1;
|
||
+
|
||
+ if (eff_tls_type & GOT_TLS_DESC)
|
||
+ {
|
||
+ relocation -= elf_gp (output_bfd);
|
||
+ if ((R_NDS32_TLS_DESC_HI20 == r_type) && (!need_relocs))
|
||
+ {
|
||
+ /* TLS model shall be converted */
|
||
+ BFD_ASSERT(0);
|
||
+ }
|
||
+ }
|
||
+ else if (eff_tls_type & GOT_TLS_IEGP)
|
||
+ {
|
||
+ relocation -= elf_gp (output_bfd);
|
||
+ }
|
||
+ }
|
||
else
|
||
{
|
||
- bfd_boolean need_relocs = FALSE;
|
||
- srelgot = htab->root.srelgot;
|
||
- if ((bfd_link_pic (info) || indx != 0)
|
||
- && (h == NULL
|
||
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||
- || h->root.type != bfd_link_hash_undefweak))
|
||
+ if ((eff_tls_type & GOT_TLS_LE) && (tls_type ^ eff_tls_type))
|
||
{
|
||
- need_relocs = TRUE;
|
||
- BFD_ASSERT (srelgot != NULL);
|
||
+ /* TLS model workaround shall be applied */
|
||
+ BFD_ASSERT(0);
|
||
}
|
||
- if (tls_type & GOT_TLS_IE)
|
||
+ else if (eff_tls_type & (GOT_TLS_IE | GOT_TLS_IEGP))
|
||
{
|
||
+ if (eff_tls_type & GOT_TLS_IEGP)
|
||
+ relocation -= elf_gp(output_bfd);
|
||
+
|
||
if (need_relocs)
|
||
{
|
||
- if (h->dynindx == 0)
|
||
- outrel.r_addend = relocation - dtpoff_base (info);
|
||
+ if (indx == 0)
|
||
+ outrel.r_addend = gottpoff (info, relocation_sym);
|
||
else
|
||
outrel.r_addend = 0;
|
||
outrel.r_offset = (sgot->output_section->vma
|
||
- + sgot->output_offset
|
||
- + off);
|
||
- outrel.r_info =
|
||
- ELF32_R_INFO (h->dynindx, R_NDS32_TLS_TPOFF);
|
||
-
|
||
- loc = srelgot->contents;
|
||
- loc +=
|
||
- srelgot->reloc_count * sizeof (Elf32_External_Rela);
|
||
- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||
- ++srelgot->reloc_count;
|
||
+ + sgot->output_offset + off);
|
||
+ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_TPOFF);
|
||
+
|
||
+ elf32_nds32_add_dynreloc (output_bfd, info, srelgot,
|
||
+ &outrel);
|
||
}
|
||
else
|
||
- bfd_put_32 (output_bfd, h->root.u.def.value - TP_OFFSET,
|
||
- sgot->contents + off);
|
||
+ {
|
||
+ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym),
|
||
+ sgot->contents + off);
|
||
+ }
|
||
+ }
|
||
+ else if (eff_tls_type & GOT_TLS_DESC)
|
||
+ {
|
||
+ relocation -= elf_gp (output_bfd);
|
||
+ if (need_relocs)
|
||
+ {
|
||
+ if (indx == 0)
|
||
+ outrel.r_addend = gottpoff (info, relocation_sym);
|
||
+ else
|
||
+ outrel.r_addend = 0;
|
||
+ outrel.r_offset = (sgot->output_section->vma
|
||
+ + sgot->output_offset + off);
|
||
+ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_DESC);
|
||
+
|
||
+ if (htab->tls_desc_trampoline)
|
||
+ {
|
||
+ asection *srelplt;
|
||
+ srelplt = ehtab->srelplt;
|
||
+ loc = srelplt->contents;
|
||
+ loc += htab->next_tls_desc_index++ * sizeof (Elf32_External_Rela);
|
||
+ BFD_ASSERT (loc + sizeof (Elf32_External_Rela)
|
||
+ <= srelplt->contents + srelplt->size);
|
||
+
|
||
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ loc = srelgot->contents;
|
||
+ loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
|
||
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||
+ ++srelgot->reloc_count;
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* feed me! */
|
||
+ bfd_put_32 (output_bfd, 0xdeadbeef,
|
||
+ sgot->contents + off);
|
||
+ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym),
|
||
+ sgot->contents + off + 4);
|
||
+ patch_tls_desc_to_ie (contents, rel, input_bfd);
|
||
+ BFD_ASSERT(0);
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* TLS model workaround shall be applied */
|
||
+ BFD_ASSERT(0);
|
||
}
|
||
+
|
||
+ if (h != NULL)
|
||
+ h->got.offset |= 1;
|
||
+ else
|
||
+ local_got_offsets[r_symndx] |= 1;
|
||
}
|
||
}
|
||
- break;
|
||
+ break;
|
||
+
|
||
+ case R_NDS32_SECURITY_16:
|
||
+ relocation = 0;
|
||
+ crc_rel->r_addend = NDS32_SECURITY_NONE;
|
||
+ r = nds32_elf_final_link_relocate (howto, input_bfd,
|
||
+ input_section, contents,
|
||
+ crc_rel->r_offset, relocation,
|
||
+ crc_rel->r_addend);
|
||
+ crc_rel = NULL;
|
||
+ goto check_reloc;
|
||
+ break;
|
||
+ /* DON'T fall through. */
|
||
+ case R_NDS32_ICT_HI20:
|
||
+ case R_NDS32_ICT_LO12:
|
||
+ case R_NDS32_ICT_25PC:
|
||
+ case R_NDS32_ICT_LO12S2:
|
||
+ entry = (struct elf_nds32_ict_hash_entry*)
|
||
+ bfd_hash_lookup (&indirect_call_table, h->root.root.string,
|
||
+ FALSE, FALSE);
|
||
+ if (!entry)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB %pA: internal error indirect call relocation "
|
||
+ "0x%lx without hash.\n"),
|
||
+ input_bfd, sec, rel->r_offset);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
|
||
+ h2 = bfd_link_hash_lookup (info->hash,
|
||
+ "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ relocation = ((h2->u.def.value
|
||
+ + h2->u.def.section->output_section->vma
|
||
+ + h2->u.def.section->output_offset)
|
||
+ + (entry->order * 4));
|
||
+ break;
|
||
/* DON'T fall through. */
|
||
|
||
default:
|
||
@@ -5275,6 +6417,12 @@ handle_sda:
|
||
case R_NDS32_TLS_LE_15S0:
|
||
case R_NDS32_TLS_LE_15S1:
|
||
case R_NDS32_TLS_LE_15S2:
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ case R_NDS32_TLS_IE_LO12:
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ case R_NDS32_TLS_IEGP_LO12S2:
|
||
/* Instruction related relocs must handle endian properly. */
|
||
/* NOTE: PIC IS NOT HANDLE YET; DO IT LATER. */
|
||
r = nds32_elf_final_link_relocate (howto, input_bfd,
|
||
@@ -5283,6 +6431,15 @@ handle_sda:
|
||
rel->r_addend);
|
||
break;
|
||
|
||
+ case R_NDS32_ICT_HI20:
|
||
+ case R_NDS32_ICT_LO12:
|
||
+ case R_NDS32_ICT_25PC:
|
||
+ case R_NDS32_ICT_LO12S2:
|
||
+ r = nds32_elf_final_link_relocate (howto, input_bfd, input_section,
|
||
+ contents, rel->r_offset,
|
||
+ relocation, 0);
|
||
+ break;
|
||
+
|
||
default:
|
||
/* All other relocs can use default handler. */
|
||
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||
@@ -5314,6 +6471,17 @@ check_reloc:
|
||
switch (r)
|
||
{
|
||
case bfd_reloc_overflow:
|
||
+ if (r_type == R_NDS32_17IFC_PCREL_RELA)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("\n%pB: (%pA+0x%x): The IFC optimization range exceeded.\n"
|
||
+ "Please turn off the IFC optimization (-mno-ifc) when "
|
||
+ "compiling the file %s.\n"),
|
||
+ input_bfd, sec, (int) rel->r_offset,
|
||
+ h->root.u.def.section->owner->filename);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ }
|
||
+
|
||
(*info->callbacks->reloc_overflow)
|
||
(info, (h ? &h->root : NULL), name, howto->name,
|
||
(bfd_vma) 0, input_bfd, input_section, offset);
|
||
@@ -5340,14 +6508,18 @@ check_reloc:
|
||
errmsg = _("internal error: unknown error");
|
||
/* Fall through. */
|
||
|
||
- common_error:
|
||
- (*info->callbacks->warning) (info, errmsg, name, input_bfd,
|
||
- input_section, offset);
|
||
+common_error:
|
||
+ (*info->callbacks->warning)
|
||
+ (info, errmsg, name, input_bfd, input_section, offset);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
+ /* Resotre header size to avoid overflow load. */
|
||
+ if (elf_nds32_tdata (input_bfd)->hdr_size != 0)
|
||
+ symtab_hdr->sh_size = elf_nds32_tdata (input_bfd)->hdr_size;
|
||
+
|
||
return ret;
|
||
}
|
||
|
||
@@ -5356,12 +6528,15 @@ check_reloc:
|
||
|
||
static bfd_boolean
|
||
nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
- struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
|
||
+ struct elf_link_hash_entry *h,
|
||
+ Elf_Internal_Sym *sym)
|
||
{
|
||
- struct elf_nds32_link_hash_table *htab;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
+ struct elf_nds32_link_hash_entry *hent;
|
||
bfd_byte *loc;
|
||
|
||
- htab = nds32_elf_hash_table (info);
|
||
+ ehtab = elf_hash_table (info);
|
||
+ hent = (struct elf_nds32_link_hash_entry *) h;
|
||
|
||
if (h->plt.offset != (bfd_vma) - 1)
|
||
{
|
||
@@ -5379,9 +6554,9 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
||
BFD_ASSERT (h->dynindx != -1);
|
||
|
||
- splt = htab->root.splt;
|
||
- sgot = htab->root.sgotplt;
|
||
- srela = htab->root.srelplt;
|
||
+ splt = ehtab->splt;
|
||
+ sgot = ehtab->sgotplt;
|
||
+ srela = ehtab->srelplt;
|
||
BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
|
||
|
||
/* Get the index in the procedure linkage table which
|
||
@@ -5417,7 +6592,7 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
bfd_putb32 (insn, splt->contents + h->plt.offset + 12);
|
||
|
||
insn = PLT_ENTRY_WORD4
|
||
- + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff);
|
||
+ + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff);
|
||
bfd_putb32 (insn, splt->contents + h->plt.offset + 16);
|
||
local_plt_offset = 12;
|
||
}
|
||
@@ -5428,9 +6603,8 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
long offset;
|
||
|
||
/* FIXME, sda_base is 65536, it will damage opcode. */
|
||
- /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */
|
||
offset = sgot->output_section->vma + sgot->output_offset + got_offset
|
||
- - elf_gp (output_bfd);
|
||
+ - elf_gp (output_bfd);
|
||
insn = PLT_PIC_ENTRY_WORD0 + ((offset >> 12) & 0xfffff);
|
||
bfd_putb32 (insn, splt->contents + h->plt.offset);
|
||
|
||
@@ -5479,18 +6653,18 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
}
|
||
}
|
||
|
||
- if (h->got.offset != (bfd_vma) - 1)
|
||
+ if ((h->got.offset != (bfd_vma) -1) && (hent->tls_type == GOT_NORMAL))
|
||
{
|
||
asection *sgot;
|
||
- asection *srela;
|
||
+ asection *srelagot;
|
||
Elf_Internal_Rela rela;
|
||
|
||
/* This symbol has an entry in the global offset table.
|
||
Set it up. */
|
||
|
||
- sgot = htab->root.sgot;
|
||
- srela = htab->root.srelgot;
|
||
- BFD_ASSERT (sgot != NULL && srela != NULL);
|
||
+ sgot = ehtab->sgot;
|
||
+ srelagot = ehtab->srelgot;
|
||
+ BFD_ASSERT (sgot != NULL && srelagot != NULL);
|
||
|
||
rela.r_offset = (sgot->output_section->vma
|
||
+ sgot->output_offset + (h->got.offset & ~1));
|
||
@@ -5500,14 +6674,24 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
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->dynindx == -1 || h->forced_local) && h->def_regular)
|
||
+ if ((bfd_link_pic (info)
|
||
+ && (info->symbolic || h->dynindx == -1 || h->forced_local)
|
||
+ && h->def_regular)
|
||
+ || (bfd_link_pie (info) && h->def_regular))
|
||
{
|
||
rela.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
|
||
rela.r_addend = (h->root.u.def.value
|
||
- + h->root.u.def.section->output_section->vma
|
||
- + h->root.u.def.section->output_offset);
|
||
+ + h->root.u.def.section->output_section->vma
|
||
+ + h->root.u.def.section->output_offset);
|
||
+
|
||
+ /* FIXME: cancel PLT trampoline, too late ?? */
|
||
+ /* h->plt.offset = (bfd_vma) -1; */
|
||
+
|
||
+ if ((h->got.offset & 1) == 0)
|
||
+ {
|
||
+ bfd_put_32 (output_bfd, rela.r_addend,
|
||
+ sgot->contents + h->got.offset);
|
||
+ }
|
||
}
|
||
else
|
||
{
|
||
@@ -5518,10 +6702,11 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
rela.r_addend = 0;
|
||
}
|
||
|
||
- loc = srela->contents;
|
||
- loc += srela->reloc_count * sizeof (Elf32_External_Rela);
|
||
+ loc = srelagot->contents;
|
||
+ loc += srelagot->reloc_count * sizeof (Elf32_External_Rela);
|
||
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
|
||
- ++srela->reloc_count;
|
||
+ ++srelagot->reloc_count;
|
||
+ BFD_ASSERT (loc < (srelagot->contents + srelagot->size));
|
||
}
|
||
|
||
if (h->needs_copy)
|
||
@@ -5563,23 +6748,32 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
||
static bfd_boolean
|
||
nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||
{
|
||
- struct elf_nds32_link_hash_table *htab;
|
||
bfd *dynobj;
|
||
asection *sdyn;
|
||
- asection *sgot;
|
||
+ asection *sgotplt;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
+ struct elf_nds32_link_hash_table *htab;
|
||
|
||
+ ehtab = elf_hash_table (info);
|
||
htab = nds32_elf_hash_table (info);
|
||
- dynobj = htab->root.dynobj;
|
||
+ if (htab == NULL)
|
||
+ return FALSE;
|
||
+
|
||
+ dynobj = elf_hash_table (info)->dynobj;
|
||
|
||
- sgot = htab->root.sgotplt;
|
||
+ sgotplt = ehtab->sgotplt;
|
||
+ /* A broken linker script might have discarded the dynamic sections.
|
||
+ Catch this here so that we do not seg-fault later on. */
|
||
+ if (sgotplt != NULL && bfd_is_abs_section (sgotplt->output_section))
|
||
+ return FALSE;
|
||
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
|
||
|
||
- if (htab->root.dynamic_sections_created)
|
||
+ if (elf_hash_table (info)->dynamic_sections_created)
|
||
{
|
||
asection *splt;
|
||
Elf32_External_Dyn *dyncon, *dynconend;
|
||
|
||
- BFD_ASSERT (sgot != NULL && sdyn != NULL);
|
||
+ BFD_ASSERT (sgotplt != NULL && sdyn != NULL);
|
||
|
||
dyncon = (Elf32_External_Dyn *) sdyn->contents;
|
||
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
|
||
@@ -5597,25 +6791,60 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||
break;
|
||
|
||
case DT_PLTGOT:
|
||
- s = htab->root.sgotplt;
|
||
+ /* name = ".got"; */
|
||
+ s = ehtab->sgot->output_section;
|
||
goto get_vma;
|
||
case DT_JMPREL:
|
||
- s = htab->root.srelplt;
|
||
- get_vma:
|
||
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
|
||
+ s = ehtab->srelplt->output_section;
|
||
+get_vma:
|
||
+ BFD_ASSERT (s != NULL);
|
||
+ dyn.d_un.d_ptr = s->vma;
|
||
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||
break;
|
||
|
||
case DT_PLTRELSZ:
|
||
- s = htab->root.srelplt;
|
||
+ s = ehtab->srelplt->output_section;
|
||
+ BFD_ASSERT (s != NULL);
|
||
dyn.d_un.d_val = s->size;
|
||
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||
break;
|
||
+
|
||
+ case DT_RELASZ:
|
||
+ /* My reading of the SVR4 ABI indicates that the
|
||
+ procedure linkage table relocs (DT_JMPREL) should be
|
||
+ included in the overall relocs (DT_RELA). This is
|
||
+ what Solaris does. However, UnixWare can not handle
|
||
+ that case. Therefore, we override the DT_RELASZ entry
|
||
+ here to make it not include the JMPREL relocs. Since
|
||
+ the linker script arranges for .rela.plt to follow all
|
||
+ other relocation sections, we don't have to worry
|
||
+ about changing the DT_RELA entry. */
|
||
+ if (ehtab->srelplt != NULL)
|
||
+ {
|
||
+ s = ehtab->srelplt->output_section;
|
||
+ dyn.d_un.d_val -= s->size;
|
||
+ }
|
||
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||
+ break;
|
||
+
|
||
+ case DT_TLSDESC_PLT:
|
||
+ s = htab->root.splt;
|
||
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
|
||
+ + htab->dt_tlsdesc_plt);
|
||
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||
+ break;
|
||
+
|
||
+ case DT_TLSDESC_GOT:
|
||
+ s = htab->root.sgot;
|
||
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
|
||
+ + htab->dt_tlsdesc_got);
|
||
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||
+ break;
|
||
}
|
||
}
|
||
|
||
/* Fill in the first entry in the procedure linkage table. */
|
||
- splt = htab->root.splt;
|
||
+ splt = ehtab->splt;
|
||
if (splt && splt->size > 0)
|
||
{
|
||
if (bfd_link_pic (info))
|
||
@@ -5624,13 +6853,11 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||
long offset;
|
||
|
||
/* FIXME, sda_base is 65536, it will damage opcode. */
|
||
- /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */
|
||
- offset = sgot->output_section->vma + sgot->output_offset + 4
|
||
- - elf_gp (output_bfd);
|
||
+ offset = sgotplt->output_section->vma + sgotplt->output_offset + 4
|
||
+ - elf_gp (output_bfd);
|
||
insn = PLT0_PIC_ENTRY_WORD0 | ((offset >> 12) & 0xfffff);
|
||
bfd_putb32 (insn, splt->contents);
|
||
|
||
- /* insn = PLT0_PIC_ENTRY_WORD0 | (((8 - sda_base) >> 2) & 0x7fff) ; */
|
||
/* here has a typo? */
|
||
insn = PLT0_PIC_ENTRY_WORD1 | (offset & 0xfff);
|
||
bfd_putb32 (insn, splt->contents + 4);
|
||
@@ -5652,8 +6879,8 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||
unsigned long insn;
|
||
unsigned long addr;
|
||
|
||
- /* addr = .got + 4 */
|
||
- addr = sgot->output_section->vma + sgot->output_offset + 4;
|
||
+ /* addr = .got + 4 */
|
||
+ addr = sgotplt->output_section->vma + sgotplt->output_offset + 4;
|
||
insn = PLT0_ENTRY_WORD0 | ((addr >> 12) & 0xfffff);
|
||
bfd_putb32 (insn, splt->contents);
|
||
|
||
@@ -5673,21 +6900,48 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||
elf_section_data (splt->output_section)->this_hdr.sh_entsize =
|
||
PLT_ENTRY_SIZE;
|
||
}
|
||
+
|
||
+ if (htab->dt_tlsdesc_plt)
|
||
+ {
|
||
+ /* Calculate addresses. */
|
||
+ asection *sgot = sgot = ehtab->sgot;
|
||
+ bfd_vma pltgot = sgotplt->output_section->vma
|
||
+ + sgotplt->output_offset;
|
||
+ bfd_vma tlsdesc_got = sgot->output_section->vma + sgot->output_offset
|
||
+ + htab->dt_tlsdesc_got;
|
||
+
|
||
+ /* Get GP offset. */
|
||
+ pltgot -= elf_gp (output_bfd) - 4; /* PLTGOT[1] */
|
||
+ tlsdesc_got -= elf_gp (output_bfd);
|
||
+
|
||
+ /* Do relocation. */
|
||
+ dl_tlsdesc_lazy_trampoline[0] += ((1 << 20) - 1) & (tlsdesc_got >> 12);
|
||
+ dl_tlsdesc_lazy_trampoline[1] += 0xfff & tlsdesc_got;
|
||
+ dl_tlsdesc_lazy_trampoline[4] += ((1 << 20) - 1) & (pltgot >> 12);
|
||
+ dl_tlsdesc_lazy_trampoline[5] += 0xfff & pltgot;
|
||
+
|
||
+ /* TODO: relaxation. */
|
||
+
|
||
+ /* Insert .plt. */
|
||
+ nds32_put_trampoline (splt->contents + htab->dt_tlsdesc_plt,
|
||
+ dl_tlsdesc_lazy_trampoline,
|
||
+ ARRAY_SIZE (dl_tlsdesc_lazy_trampoline));
|
||
+ }
|
||
}
|
||
|
||
/* Fill in the first three entries in the global offset table. */
|
||
- if (sgot && sgot->size > 0)
|
||
+ if (sgotplt && sgotplt->size > 0)
|
||
{
|
||
if (sdyn == NULL)
|
||
- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
|
||
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
|
||
else
|
||
bfd_put_32 (output_bfd,
|
||
sdyn->output_section->vma + sdyn->output_offset,
|
||
- sgot->contents);
|
||
- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
|
||
- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
|
||
+ sgotplt->contents);
|
||
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
|
||
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
|
||
|
||
- elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
||
+ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
|
||
}
|
||
|
||
return TRUE;
|
||
@@ -5738,6 +6992,7 @@ nds32_elf_final_write_processing (bfd *abfd,
|
||
{
|
||
unsigned long val;
|
||
static unsigned int cur_mach = 0;
|
||
+ unsigned int i;
|
||
|
||
if (bfd_mach_n1 != bfd_get_mach (abfd))
|
||
{
|
||
@@ -5771,6 +7026,36 @@ nds32_elf_final_write_processing (bfd *abfd,
|
||
|
||
elf_elfheader (abfd)->e_flags &= ~EF_NDS_ARCH;
|
||
elf_elfheader (abfd)->e_flags |= val;
|
||
+ if (ifc_flag)
|
||
+ elf_elfheader (abfd)->e_flags |= E_NDS32_HAS_IFC_INST ;
|
||
+
|
||
+ if (ict_file)
|
||
+ {
|
||
+ fprintf (ict_file, ".section " NDS32_ICT_SECTION ", \"ax\"\n");
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ fprintf (ict_file, ".ict_model\tlarge\n");
|
||
+ else
|
||
+ fprintf (ict_file, ".ict_model\tsmall\n");
|
||
+ fprintf (ict_file, ".globl _INDIRECT_CALL_TABLE_BASE_\n"
|
||
+ "_INDIRECT_CALL_TABLE_BASE_:\n");
|
||
+ /* Output rom patch entries. */
|
||
+ indirect_call_table.frozen = 1;
|
||
+ for (i = 0; i < indirect_call_table.size; i++)
|
||
+ {
|
||
+ struct bfd_hash_entry *p;
|
||
+ struct elf_nds32_ict_hash_entry *entry;
|
||
+
|
||
+ for (p = indirect_call_table.table[i]; p != NULL; p = p->next)
|
||
+ {
|
||
+ entry = (struct elf_nds32_ict_hash_entry *) p;
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ fprintf (ict_file, "\t.word\t%s\n", entry->root.string);
|
||
+ else
|
||
+ fprintf (ict_file, "\tj\t%s\n", entry->root.string);
|
||
+ }
|
||
+ }
|
||
+ indirect_call_table.frozen = 0;
|
||
+ }
|
||
}
|
||
|
||
/* Function to keep NDS32 specific file flags. */
|
||
@@ -5856,13 +7141,27 @@ nds32_check_vec_size (bfd *ibfd)
|
||
return TRUE;
|
||
}
|
||
|
||
+static unsigned int
|
||
+nds32_elf_force_to_set_output_abi (char *str)
|
||
+{
|
||
+ flagword flags;
|
||
+
|
||
+ if (strcmp (str, "AABI") == 0)
|
||
+ flags = E_NDS_ABI_AABI;
|
||
+ else if (strcmp (str, "V2FP+") == 0)
|
||
+ flags = E_NDS_ABI_V2FP_PLUS;
|
||
+ else
|
||
+ flags = 0;
|
||
+
|
||
+ return flags;
|
||
+}
|
||
+
|
||
/* Merge backend specific data from an object file to the output
|
||
object file when linking. */
|
||
|
||
static bfd_boolean
|
||
nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
|
||
{
|
||
- bfd *obfd = info->output_bfd;
|
||
flagword out_flags;
|
||
flagword in_flags;
|
||
flagword out_16regs;
|
||
@@ -5873,6 +7172,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
|
||
flagword in_version;
|
||
flagword out_fpu_config;
|
||
flagword in_fpu_config;
|
||
+ bfd *obfd = info->output_bfd;
|
||
|
||
/* TODO: Revise to use object-attributes instead. */
|
||
if (!nds32_check_vec_size (ibfd))
|
||
@@ -5891,135 +7191,171 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
|
||
return FALSE;
|
||
}
|
||
|
||
- in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION;
|
||
- if (in_version == E_NDS32_ELF_VER_1_2)
|
||
- {
|
||
- _bfd_error_handler
|
||
- (_("%B: warning: Older version of object file encountered, "
|
||
- "Please recompile with current tool chain."), ibfd);
|
||
- }
|
||
-
|
||
- /* We may need to merge V1 and V2 arch object files to V2. */
|
||
- if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
- != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
|
||
+ /* [Bug 11585] [Ticket 7067] -B option in objcopy cannot work as expected.
|
||
+ e_flags = 0 shall be treat as generic one.
|
||
+ no checking, and no merging. */
|
||
+ if (elf_elfheader (ibfd)->e_flags)
|
||
{
|
||
- /* Need to convert version. */
|
||
- if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
- == E_NDS_ARCH_STAR_RESERVED)
|
||
+ in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION;
|
||
+ if (in_version == E_NDS32_ELF_VER_1_2)
|
||
{
|
||
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: warning: Older version of object file encountered, "
|
||
+ "Please recompile with current tool chain."), ibfd);
|
||
}
|
||
- else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9
|
||
- || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
- > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
|
||
+
|
||
+ if (output_abi != NULL)
|
||
{
|
||
- elf_elfheader (obfd)->e_flags =
|
||
- convert_e_flags (elf_elfheader (obfd)->e_flags,
|
||
- (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH));
|
||
+ elf_elfheader (ibfd)->e_flags &= ~(EF_NDS_ABI);
|
||
+ elf_elfheader (ibfd)->e_flags
|
||
+ |= nds32_elf_force_to_set_output_abi (output_abi);
|
||
+ elf_elfheader (obfd)->e_flags &= ~(EF_NDS_ABI);
|
||
+ elf_elfheader (obfd)->e_flags
|
||
+ |= nds32_elf_force_to_set_output_abi (output_abi);
|
||
}
|
||
- else
|
||
+
|
||
+ /* We may need to merge V1 and V2 arch object files to V2. */
|
||
+ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
+ != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
|
||
{
|
||
- elf_elfheader (ibfd)->e_flags =
|
||
- convert_e_flags (elf_elfheader (ibfd)->e_flags,
|
||
- (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH));
|
||
- }
|
||
- }
|
||
-
|
||
- /* Extract some flags. */
|
||
- in_flags = elf_elfheader (ibfd)->e_flags
|
||
- & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
|
||
- | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
|
||
-
|
||
- /* The following flags need special treatment. */
|
||
- in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
|
||
- in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
|
||
- in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF;
|
||
-
|
||
- /* Extract some flags. */
|
||
- out_flags = elf_elfheader (obfd)->e_flags
|
||
- & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
|
||
- | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
|
||
-
|
||
- /* The following flags need special treatment. */
|
||
- out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
|
||
- out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
|
||
- out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF;
|
||
- out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION;
|
||
- if (!elf_flags_init (obfd))
|
||
- {
|
||
- /* If the input is the default architecture then do not
|
||
- bother setting the flags for the output architecture,
|
||
- instead allow future merges to do this. If no future
|
||
- merges ever set these flags then they will retain their
|
||
- unitialised values, which surprise surprise, correspond
|
||
- to the default values. */
|
||
- if (bfd_get_arch_info (ibfd)->the_default)
|
||
- return TRUE;
|
||
+ /* Need to convert version. */
|
||
+ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
+ == E_NDS_ARCH_STAR_RESERVED)
|
||
+ {
|
||
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||
+ }
|
||
+ else if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
+ == E_NDS_ARCH_STAR_V3_M
|
||
+ && (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)
|
||
+ == E_NDS_ARCH_STAR_V3_0)
|
||
+ {
|
||
+ elf_elfheader (ibfd)->e_flags =
|
||
+ (elf_elfheader (ibfd)->e_flags & (~EF_NDS_ARCH))
|
||
+ | E_NDS_ARCH_STAR_V3_0;
|
||
+ }
|
||
+ else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)
|
||
+ == E_NDS_ARCH_STAR_V0_9
|
||
+ || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
|
||
+ > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
|
||
+ {
|
||
+ elf_elfheader (obfd)->e_flags =
|
||
+ convert_e_flags (elf_elfheader (obfd)->e_flags,
|
||
+ (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH));
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ elf_elfheader (ibfd)->e_flags =
|
||
+ convert_e_flags (elf_elfheader (ibfd)->e_flags,
|
||
+ (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH));
|
||
+ }
|
||
+ }
|
||
|
||
- elf_flags_init (obfd) = TRUE;
|
||
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||
+ /* Extract some flags. */
|
||
+ in_flags = elf_elfheader (ibfd)->e_flags
|
||
+ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
|
||
+ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
|
||
+
|
||
+ /* The following flags need special treatment. */
|
||
+ in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
|
||
+ in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
|
||
+ in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF;
|
||
+
|
||
+ /* Extract some flags. */
|
||
+ out_flags = elf_elfheader (obfd)->e_flags
|
||
+ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
|
||
+ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
|
||
+
|
||
+ /* The following flags need special treatment. */
|
||
+ out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
|
||
+ out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
|
||
+ out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF;
|
||
+ out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION;
|
||
+ if (!elf_flags_init (obfd))
|
||
+ {
|
||
+ /* If the input is the default architecture then do not
|
||
+ bother setting the flags for the output architecture,
|
||
+ instead allow future merges to do this. If no future
|
||
+ merges ever set these flags then they will retain their
|
||
+ unitialised values, which surprise surprise, correspond
|
||
+ to the default values. */
|
||
+ if (bfd_get_arch_info (ibfd)->the_default)
|
||
+ return TRUE;
|
||
|
||
- if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
|
||
- && bfd_get_arch_info (obfd)->the_default)
|
||
- {
|
||
- return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
|
||
- bfd_get_mach (ibfd));
|
||
+ elf_flags_init (obfd) = TRUE;
|
||
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||
+
|
||
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
|
||
+ && bfd_get_arch_info (obfd)->the_default)
|
||
+ {
|
||
+ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
|
||
+ bfd_get_mach (ibfd));
|
||
+ }
|
||
+
|
||
+ return TRUE;
|
||
}
|
||
|
||
- return TRUE;
|
||
- }
|
||
+ /* Check flag compatibility. */
|
||
+ if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI))
|
||
+ {
|
||
+ asection *section = NULL;
|
||
+ bfd_byte *contents = NULL;
|
||
+ section = bfd_get_section_by_name (ibfd, ".note.v2abi_compatible");
|
||
+ if (section)
|
||
+ bfd_get_full_section_contents (ibfd, section, &contents);
|
||
|
||
- /* Check flag compatibility. */
|
||
- if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI))
|
||
- {
|
||
- _bfd_error_handler
|
||
- (_("%B: error: ABI mismatch with previous modules."), ibfd);
|
||
+ /* Only enable v3f/v3s toolchain to link v2abi compatible objects. */
|
||
+ if ((contents == NULL)
|
||
+ || bfd_getb32 (contents) != 1
|
||
+ || (out_flags & EF_NDS_ABI) != E_NDS_ABI_V2FP_PLUS)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: error: ABI mismatch with previous modules."), ibfd);
|
||
|
||
- bfd_set_error (bfd_error_bad_value);
|
||
- return FALSE;
|
||
- }
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+ }
|
||
|
||
- if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH))
|
||
- {
|
||
- if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH))
|
||
+ if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH))
|
||
{
|
||
- _bfd_error_handler
|
||
- (_("%B: error: Instruction set mismatch with previous modules."), ibfd);
|
||
+ if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH))
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%B: error: Instruction set mismatch with previous modules."), ibfd);
|
||
|
||
- bfd_set_error (bfd_error_bad_value);
|
||
- return FALSE;
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
}
|
||
- }
|
||
|
||
- /* When linking with V1.2 and V1.3 objects together the output is V1.2.
|
||
- and perf ext1 and DIV are mergerd to perf ext1. */
|
||
- if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2)
|
||
- {
|
||
- elf_elfheader (obfd)->e_flags =
|
||
- (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
- | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
- | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
- ? E_NDS32_HAS_EXT_INST : 0)
|
||
- | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
- ? E_NDS32_HAS_EXT_INST : 0)
|
||
- | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
|
||
- | ((in_version > out_version) ? out_version : in_version);
|
||
- }
|
||
- else
|
||
- {
|
||
- if (in_version != out_version)
|
||
- _bfd_error_handler
|
||
- /* xgettext:c-format */
|
||
- (_("%B: warning: Incompatible elf-versions %s and %s."),
|
||
- ibfd, nds32_elfver_strtab[out_version],
|
||
- nds32_elfver_strtab[in_version]);
|
||
+ /* When linking with V1.2 and V1.3 objects together the output is V1.2.
|
||
+ and perf ext1 and DIV are mergerd to perf ext1. */
|
||
+ if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2)
|
||
+ {
|
||
+ elf_elfheader (obfd)->e_flags =
|
||
+ (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
+ | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
+ | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
+ ? E_NDS32_HAS_EXT_INST : 0)
|
||
+ | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
|
||
+ ? E_NDS32_HAS_EXT_INST : 0)
|
||
+ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
|
||
+ | ((in_version > out_version) ? out_version : in_version);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ if (in_version != out_version)
|
||
+ _bfd_error_handler
|
||
+ (_("%B: warning: Incompatible elf-versions %s and %s."), ibfd,
|
||
+ nds32_elfver_strtab[out_version],
|
||
+ nds32_elfver_strtab[in_version]);
|
||
|
||
- elf_elfheader (obfd)->e_flags = in_flags | out_flags
|
||
- | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
|
||
- | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config)
|
||
- | (in_version > out_version ? out_version : in_version);
|
||
+ elf_elfheader (obfd)->e_flags = in_flags | out_flags
|
||
+ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
|
||
+ | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config)
|
||
+ | (in_version > out_version ? out_version : in_version);
|
||
+ }
|
||
}
|
||
-
|
||
return TRUE;
|
||
}
|
||
|
||
@@ -6081,6 +7417,79 @@ nds32_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
|
||
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
|
||
}
|
||
|
||
+static enum elf_nds32_tls_type
|
||
+get_tls_type (enum elf_nds32_reloc_type r_type,
|
||
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ enum elf_nds32_tls_type tls_type;
|
||
+ switch (r_type)
|
||
+ {
|
||
+ case R_NDS32_TLS_LE_HI20:
|
||
+ case R_NDS32_TLS_LE_LO12:
|
||
+ tls_type = GOT_TLS_LE;
|
||
+ break;
|
||
+ case R_NDS32_TLS_IE_HI20:
|
||
+ case R_NDS32_TLS_IE_LO12S2:
|
||
+ case R_NDS32_TLS_IE_LO12:
|
||
+ tls_type = GOT_TLS_IE;
|
||
+ break;
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ case R_NDS32_TLS_IEGP_LO12S2:
|
||
+ tls_type = GOT_TLS_IEGP;
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ case R_NDS32_TLS_DESC_ADD:
|
||
+ case R_NDS32_TLS_DESC_FUNC:
|
||
+ case R_NDS32_TLS_DESC_CALL:
|
||
+ tls_type = GOT_TLS_DESC;
|
||
+ break;
|
||
+ default:
|
||
+ tls_type = GOT_NORMAL;
|
||
+ break;
|
||
+ }
|
||
+ return tls_type;
|
||
+}
|
||
+
|
||
+/* Ensure that we have allocated bookkeeping structures for ABFD's local
|
||
+ symbols. */
|
||
+
|
||
+static bfd_boolean
|
||
+elf32_nds32_allocate_local_sym_info (bfd *abfd)
|
||
+{
|
||
+ if (elf_local_got_refcounts (abfd) == NULL)
|
||
+ {
|
||
+ bfd_size_type num_syms;
|
||
+ bfd_size_type size;
|
||
+ char *data;
|
||
+
|
||
+ num_syms = elf_tdata (abfd)->symtab_hdr.sh_info;
|
||
+ /* This space is for got_refcounts, got_tls_type, tlsdesc_gotent, and
|
||
+ gp_offset. The details can refer to struct elf_nds32_obj_tdata. */
|
||
+ size = num_syms * (sizeof (bfd_signed_vma) + sizeof (char)
|
||
+ + sizeof (bfd_vma) + sizeof (int)
|
||
+ + sizeof (bfd_boolean) + sizeof (bfd_vma));
|
||
+ data = bfd_zalloc (abfd, size);
|
||
+ if (data == NULL)
|
||
+ return FALSE;
|
||
+
|
||
+ elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data;
|
||
+ data += num_syms * sizeof (bfd_signed_vma);
|
||
+
|
||
+ elf32_nds32_local_got_tls_type (abfd) = (char *) data;
|
||
+ data += num_syms * sizeof (char);
|
||
+
|
||
+ elf32_nds32_local_tlsdesc_gotent (abfd) = (bfd_vma *) data;
|
||
+ data += num_syms * sizeof (bfd_vma);
|
||
+
|
||
+ elf32_nds32_local_gp_offset (abfd) = (int *) data;
|
||
+ data += num_syms * sizeof (int);
|
||
+ }
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
/* Look through the relocs for a section during the first phase.
|
||
Since we don't do .gots or .plts, we just need to consider the
|
||
virtual table relocs for gc. */
|
||
@@ -6093,21 +7502,17 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
||
const Elf_Internal_Rela *rel;
|
||
const Elf_Internal_Rela *rel_end;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
struct elf_nds32_link_hash_table *htab;
|
||
bfd *dynobj;
|
||
asection *sreloc = NULL;
|
||
|
||
+ /* No need for relocation if relocatable already. */
|
||
if (bfd_link_relocatable (info))
|
||
- return TRUE;
|
||
-
|
||
- /* Don't do anything special with non-loaded, non-alloced sections.
|
||
- In particular, any relocs in such sections should not affect GOT
|
||
- and PLT reference counting (ie. we don't allow them to create GOT
|
||
- or PLT entries), there's no possibility or desire to optimize TLS
|
||
- relocs, and there's not much point in propagating relocs to shared
|
||
- libs that the dynamic linker won't relocate. */
|
||
- if ((sec->flags & SEC_ALLOC) == 0)
|
||
- return TRUE;
|
||
+ {
|
||
+ elf32_nds32_check_relax_group (abfd, sec);
|
||
+ return TRUE;
|
||
+ }
|
||
|
||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||
sym_hashes = elf_sym_hashes (abfd);
|
||
@@ -6116,6 +7521,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
if (!elf_bad_symtab (abfd))
|
||
sym_hashes_end -= symtab_hdr->sh_info;
|
||
|
||
+ ehtab = elf_hash_table (info);
|
||
htab = nds32_elf_hash_table (info);
|
||
dynobj = htab->root.dynobj;
|
||
|
||
@@ -6125,7 +7531,8 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
enum elf_nds32_reloc_type r_type;
|
||
struct elf_link_hash_entry *h;
|
||
unsigned long r_symndx;
|
||
- int tls_type, old_tls_type;
|
||
+ enum elf_nds32_tls_type tls_type, old_tls_type;
|
||
+ struct elf_nds32_ict_hash_entry *entry;
|
||
|
||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||
r_type = ELF32_R_TYPE (rel->r_info);
|
||
@@ -6139,10 +7546,11 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||
}
|
||
|
||
- /* Some relocs require a global offset table. We create
|
||
- got section here, since these relocation need got section
|
||
- and it is not created yet. */
|
||
- if (htab->root.sgot == NULL)
|
||
+ /* create .got section if necessary
|
||
+ Some relocs require a global offset table. We create
|
||
+ got section here, since these relocation need a got section
|
||
+ and if it is not created yet. */
|
||
+ if (ehtab->sgot == NULL)
|
||
{
|
||
switch (r_type)
|
||
{
|
||
@@ -6162,10 +7570,16 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
case R_NDS32_GOTPC_LO12:
|
||
case R_NDS32_GOT20:
|
||
case R_NDS32_TLS_IE_HI20:
|
||
+ case R_NDS32_TLS_IE_LO12:
|
||
case R_NDS32_TLS_IE_LO12S2:
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ case R_NDS32_TLS_IEGP_LO12S2:
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
if (dynobj == NULL)
|
||
htab->root.dynobj = dynobj = abfd;
|
||
- if (!_bfd_elf_create_got_section (dynobj, info))
|
||
+ if (!create_got_section (dynobj, info))
|
||
return FALSE;
|
||
break;
|
||
|
||
@@ -6174,59 +7588,54 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
}
|
||
}
|
||
|
||
+ /* Check relocation type. */
|
||
switch ((int) r_type)
|
||
{
|
||
+ case R_NDS32_TLS_LE_HI20:
|
||
+ case R_NDS32_TLS_LE_LO12:
|
||
case R_NDS32_GOT_HI20:
|
||
case R_NDS32_GOT_LO12:
|
||
case R_NDS32_GOT_LO15:
|
||
case R_NDS32_GOT_LO19:
|
||
case R_NDS32_GOT20:
|
||
case R_NDS32_TLS_IE_HI20:
|
||
+ case R_NDS32_TLS_IE_LO12:
|
||
case R_NDS32_TLS_IE_LO12S2:
|
||
- switch (r_type)
|
||
- {
|
||
- case R_NDS32_TLS_IE_HI20:
|
||
- case R_NDS32_TLS_IE_LO12S2:
|
||
- tls_type = GOT_TLS_IE;
|
||
- break;
|
||
- default:
|
||
- tls_type = GOT_NORMAL;
|
||
- break;
|
||
- }
|
||
- if (h != NULL)
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ case R_NDS32_TLS_IEGP_LO12S2:
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ tls_type = get_tls_type (r_type, h);
|
||
+ if (h)
|
||
{
|
||
+ if (tls_type != GOT_TLS_LE)
|
||
+ h->got.refcount += 1;
|
||
old_tls_type = elf32_nds32_hash_entry (h)->tls_type;
|
||
- h->got.refcount += 1;
|
||
}
|
||
else
|
||
{
|
||
- bfd_signed_vma *local_got_refcounts;
|
||
-
|
||
- /* This is a global offset table entry for a local
|
||
- symbol. */
|
||
- local_got_refcounts = elf_local_got_refcounts (abfd);
|
||
- if (local_got_refcounts == NULL)
|
||
- {
|
||
- bfd_size_type size;
|
||
+ /* This is a global offset table entry for a local symbol. */
|
||
+ if (!elf32_nds32_allocate_local_sym_info (abfd))
|
||
+ return FALSE;
|
||
|
||
- size = symtab_hdr->sh_info;
|
||
- size *= sizeof (bfd_signed_vma);
|
||
- local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size);
|
||
- if (local_got_refcounts == NULL)
|
||
- return FALSE;
|
||
- elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||
- }
|
||
- local_got_refcounts[r_symndx] += 1;
|
||
+ BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
|
||
+ if (tls_type != GOT_TLS_LE)
|
||
+ elf_local_got_refcounts (abfd)[r_symndx] += 1;
|
||
old_tls_type = elf32_nds32_local_got_tls_type (abfd)[r_symndx];
|
||
}
|
||
|
||
- /* We will already have issued an error message if there
|
||
+ /* We would already issued an error message if there
|
||
is a TLS/non-TLS mismatch, based on the symbol
|
||
- type. So just combine any TLS types needed. */
|
||
+ type. So just combine any TLS types needed. */
|
||
if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
|
||
&& tls_type != GOT_NORMAL)
|
||
tls_type |= old_tls_type;
|
||
|
||
+ /* DESC to IE/IEGP if link to executable */
|
||
+ if ((tls_type & (GOT_TLS_DESC | GOT_TLS_IEGP)) && (bfd_link_executable (info)))
|
||
+ tls_type |= (bfd_link_pie (info) ? GOT_TLS_IEGP : GOT_TLS_IE);
|
||
+
|
||
if (old_tls_type != tls_type)
|
||
{
|
||
if (h != NULL)
|
||
@@ -6235,6 +7644,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
elf32_nds32_local_got_tls_type (abfd)[r_symndx] = tls_type;
|
||
}
|
||
break;
|
||
+
|
||
case R_NDS32_9_PLTREL:
|
||
case R_NDS32_25_PLTREL:
|
||
case R_NDS32_PLTREL_HI20:
|
||
@@ -6244,19 +7654,20 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
case R_NDS32_PLT_GOTREL_LO15:
|
||
case R_NDS32_PLT_GOTREL_LO19:
|
||
case R_NDS32_PLT_GOTREL_LO20:
|
||
-
|
||
- /* This symbol requires a procedure linkage table entry. We
|
||
- actually build the entry in adjust_dynamic_symbol,
|
||
+ /* This symbol requires a procedure linkage table entry.
|
||
+ We actually build the entry in adjust_dynamic_symbol,
|
||
because this might be a case of linking PIC code without
|
||
linking in any dynamic objects, in which case we don't
|
||
need to generate a procedure linkage table after all. */
|
||
|
||
/* If this is a local symbol, we resolve it directly without
|
||
creating a procedure linkage table entry. */
|
||
+ /* explain: continue v.s. break here following: */
|
||
if (h == NULL)
|
||
continue;
|
||
|
||
- if (h->forced_local)
|
||
+ if (h->forced_local
|
||
+ || (bfd_link_pie (info) && h->def_regular))
|
||
break;
|
||
|
||
elf32_nds32_hash_entry (h)->tls_type = GOT_NORMAL;
|
||
@@ -6330,8 +7741,8 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
&& (h->root.type == bfd_link_hash_defweak
|
||
|| !h->def_regular)))
|
||
{
|
||
- struct elf_dyn_relocs *p;
|
||
- struct elf_dyn_relocs **head;
|
||
+ struct elf_nds32_dyn_relocs *p;
|
||
+ struct elf_nds32_dyn_relocs **head;
|
||
|
||
if (dynobj == NULL)
|
||
htab->root.dynobj = dynobj = abfd;
|
||
@@ -6380,7 +7791,6 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
else
|
||
{
|
||
asection *s;
|
||
- void *vpp;
|
||
|
||
Elf_Internal_Sym *isym;
|
||
isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
|
||
@@ -6392,15 +7802,15 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
if (s == NULL)
|
||
return FALSE;
|
||
|
||
- vpp = &elf_section_data (s)->local_dynrel;
|
||
- head = (struct elf_dyn_relocs **) vpp;
|
||
+ head = ((struct elf_nds32_dyn_relocs **)
|
||
+ &elf_section_data (s)->local_dynrel);
|
||
}
|
||
|
||
p = *head;
|
||
if (p == NULL || p->sec != sec)
|
||
{
|
||
bfd_size_type amt = sizeof (*p);
|
||
- p = (struct elf_dyn_relocs *) bfd_alloc (dynobj, amt);
|
||
+ p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt);
|
||
if (p == NULL)
|
||
return FALSE;
|
||
p->next = *head;
|
||
@@ -6411,19 +7821,98 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
}
|
||
|
||
p->count += 1;
|
||
+
|
||
+ /* FIXME: Since eh_frame is readonly, R_NDS32_32_RELA
|
||
+ reloc for eh_frame will cause shared library has
|
||
+ TEXTREL entry in the dynamic section. This lead glibc
|
||
+ testsuites to failure (bug-13092) and cause kernel fail
|
||
+ (bug-11819). I think the best solution is to replace
|
||
+ absolute reloc with pc relative reloc in the eh_frame.
|
||
+ To do that, we need to support the following issues:
|
||
+
|
||
+ === For GCC ===
|
||
+ * gcc/config/nds32/nds32.h: Define
|
||
+ ASM_PREFERRED_EH_DATA_FORMAT to encode DW_EH_PE_pcrel
|
||
+ and DW_EH_PE_sdata4 into DWARF exception header when
|
||
+ option have '-fpic'.
|
||
+
|
||
+ === For binutils ===
|
||
+ * bfd/: Define new reloc R_NDS32_32_PCREL_RELA.
|
||
+ * gas/config/tc-nds32.h: Define DIFF_EXPR_OK. This
|
||
+ may break our nds DIFF mechanism, therefore, we
|
||
+ must disable all linker relaxations to ensure
|
||
+ correctness.
|
||
+ * gas/config/tc-nds32.c (nds32_apply_fix): Replace
|
||
+ R_NDS32_32_RELA with R_NDS32_32_PCREL_RELA, and
|
||
+ do the necessary modification.
|
||
+
|
||
+ Unfortunately, it still have some problems for nds32
|
||
+ to support pc relative reloc in the eh_frame. So I use
|
||
+ another solution to fix this issue.
|
||
+
|
||
+ However, I find that ld always emit TEXTREL marker for
|
||
+ R_NDS32_NONE relocs in rel.dyn. These none relocs are
|
||
+ correspond to R_NDS32_32_RELA for .eh_frame section.
|
||
+ It means that we always reserve redundant entries of rel.dyn
|
||
+ for these relocs which actually do nothing in dynamic linker.
|
||
+
|
||
+ Therefore, we regard these relocs as pc relative relocs
|
||
+ here and increase the pc_count. */
|
||
if (ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA
|
||
|| ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA
|
||
- || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA)
|
||
+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA
|
||
+ || (r_type == R_NDS32_32_RELA
|
||
+ && strcmp (sec->name, ".eh_frame") == 0))
|
||
p->pc_count += 1;
|
||
}
|
||
break;
|
||
|
||
- /* This relocation describes the C++ object vtable hierarchy.
|
||
- Reconstruct it for later use during GC. */
|
||
- case R_NDS32_RELA_GNU_VTINHERIT:
|
||
- case R_NDS32_GNU_VTINHERIT:
|
||
- if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
|
||
- return FALSE;
|
||
+ /* Merge jump-patch table symbol here. */
|
||
+ case R_NDS32_ICT_HI20:
|
||
+ case R_NDS32_ICT_LO12:
|
||
+ case R_NDS32_ICT_25PC:
|
||
+ if (rel->r_addend != 0)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB %s: Error: Rom-patch relocation offset: 0x%lx "
|
||
+ "with addend 0x%lx\n"),
|
||
+ abfd, sec->name, rel->r_offset, rel->r_addend);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ if (h)
|
||
+ {
|
||
+ elf32_nds32_hash_entry (h)->indirect_call = TRUE;
|
||
+ entry = (struct elf_nds32_ict_hash_entry *)
|
||
+ bfd_hash_lookup (&indirect_call_table, h->root.root.string,
|
||
+ TRUE, TRUE);
|
||
+ entry->h = h;
|
||
+ if (entry == NULL)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: failed creating indirect call %s hash table\n"),
|
||
+ abfd, h->root.root.string);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* Rom-patch functions cannot be local. */
|
||
+ _bfd_error_handler
|
||
+ (_("%pB: indirect call relocation with local symbol.\n"), abfd);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ /* This relocation describes the C++ object vtable hierarchy.
|
||
+ Reconstruct it for later use during GC. */
|
||
+ case R_NDS32_RELA_GNU_VTINHERIT:
|
||
+ case R_NDS32_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
|
||
@@ -6436,6 +7925,18 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
|
||
return FALSE;
|
||
break;
|
||
+ case R_NDS32_RELAX_ENTRY:
|
||
+ if (ict_model == 0)
|
||
+ ict_model = rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK;
|
||
+ else if (ict_model != (rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK)
|
||
+ && (rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK) != 0)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ (_("%pB Error: mixed ict model objects.\n"), abfd);
|
||
+ bfd_set_error (bfd_error_bad_value);
|
||
+ return FALSE;
|
||
+ }
|
||
+ break;
|
||
}
|
||
}
|
||
|
||
@@ -6464,8 +7965,7 @@ write_uleb128 (bfd_byte *p, unsigned int val)
|
||
|
||
static bfd_signed_vma
|
||
calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
- Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr,
|
||
- int *pic_ext_target)
|
||
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr)
|
||
{
|
||
bfd_signed_vma foff;
|
||
bfd_vma symval, addend;
|
||
@@ -6494,7 +7994,6 @@ calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
{
|
||
unsigned long indx;
|
||
struct elf_link_hash_entry *h;
|
||
- bfd *owner;
|
||
|
||
/* An external symbol. */
|
||
indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
||
@@ -6507,9 +8006,6 @@ calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
symbol. Just ignore it--it will be caught by the
|
||
regular reloc processing. */
|
||
return 0;
|
||
- owner = h->root.u.def.section->owner;
|
||
- if (owner && (elf_elfheader (owner)->e_flags & E_NDS32_HAS_PIC))
|
||
- *pic_ext_target = 1;
|
||
|
||
if (h->root.u.def.section->flags & SEC_MERGE)
|
||
{
|
||
@@ -6563,15 +8059,15 @@ calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info,
|
||
{
|
||
unsigned long indx;
|
||
struct elf_link_hash_entry *h;
|
||
- struct elf_nds32_link_hash_table *htab;
|
||
+ struct elf_link_hash_table *ehtab;
|
||
asection *splt;
|
||
|
||
/* An external symbol. */
|
||
indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
||
h = elf_sym_hashes (abfd)[indx];
|
||
BFD_ASSERT (h != NULL);
|
||
- htab = nds32_elf_hash_table (link_info);
|
||
- splt = htab->root.splt;
|
||
+ ehtab = elf_hash_table (link_info);
|
||
+ splt = ehtab->splt;
|
||
|
||
while (h->root.type == bfd_link_hash_indirect
|
||
|| h->root.type == bfd_link_hash_warning)
|
||
@@ -6582,8 +8078,8 @@ calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info,
|
||
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. */
|
||
+ symbol. Just ignore it--it will be caught by the
|
||
+ regular reloc processing. */
|
||
return 0;
|
||
symval = (h->root.u.def.value
|
||
+ h->root.u.def.section->output_section->vma
|
||
@@ -6620,7 +8116,7 @@ nds32_convert_32_to_16_alu1 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
int *pinsn_type)
|
||
{
|
||
uint16_t insn16 = 0;
|
||
- int insn_type = 0;
|
||
+ int insn_type;
|
||
unsigned long mach = bfd_get_mach (abfd);
|
||
|
||
if (N32_SH5 (insn) != 0)
|
||
@@ -6919,8 +8415,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)
|
||
&& N32_IMM15S (insn) > -32)
|
||
{
|
||
- insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn),
|
||
- 0 - N32_IMM15S (insn));
|
||
+ insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn), 0 - N32_IMM15S (insn));
|
||
insn_type = NDS32_INSN_SUBI45;
|
||
}
|
||
else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP
|
||
@@ -6981,7 +8476,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
|
||
if (__builtin_popcount (imm15u) == 1)
|
||
{
|
||
- /* BMSKI33 */
|
||
+ /* BMSKI33 */
|
||
int imm3u = __builtin_ctz (imm15u);
|
||
|
||
insn16 = N16_BFMI333 (BMSKI33, N32_RT5 (insn), imm3u);
|
||
@@ -6989,7 +8484,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
}
|
||
else if (imm15u != 0 && __builtin_popcount (imm15u + 1) == 1)
|
||
{
|
||
- /* FEXTI33 */
|
||
+ /* FEXTI33 */
|
||
int imm3u = __builtin_ctz (imm15u + 1) - 1;
|
||
|
||
insn16 = N16_BFMI333 (FEXTI33, N32_RT5 (insn), imm3u);
|
||
@@ -7150,7 +8645,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
|
||
if ((insn & N32_BIT (14)) == 0)
|
||
{
|
||
- /* N32_BR1_BEQ */
|
||
+ /* N32_BR1_BEQ */
|
||
if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5
|
||
&& N32_RT5 (insn) != REG_R5)
|
||
insn16 = N16_TYPE38 (BEQS38, N32_RT5 (insn), N32_IMM14S (insn));
|
||
@@ -7162,7 +8657,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
}
|
||
else
|
||
{
|
||
- /* N32_BR1_BNE */
|
||
+ /* N32_BR1_BNE */
|
||
if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5
|
||
&& N32_RT5 (insn) != REG_R5)
|
||
insn16 = N16_TYPE38 (BNES38, N32_RT5 (insn), N32_IMM14S (insn));
|
||
@@ -7183,8 +8678,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
insn16 = N16_TYPE38 (BEQZ38, N32_RT5 (insn), N32_IMM16S (insn));
|
||
insn_type = NDS32_INSN_BEQZ38;
|
||
}
|
||
- else if (N32_RT5 (insn) == REG_R15
|
||
- && IS_WITHIN_S (N32_IMM16S (insn), 8))
|
||
+ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8))
|
||
{
|
||
insn16 = N16_TYPE8 (BEQZS8, N32_IMM16S (insn));
|
||
insn_type = NDS32_INSN_BEQZS8;
|
||
@@ -7197,16 +8691,15 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
insn16 = N16_TYPE38 (BNEZ38, N32_RT5 (insn), N32_IMM16S (insn));
|
||
insn_type = NDS32_INSN_BNEZ38;
|
||
}
|
||
- else if (N32_RT5 (insn) == REG_R15
|
||
- && IS_WITHIN_S (N32_IMM16S (insn), 8))
|
||
+ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8))
|
||
{
|
||
insn16 = N16_TYPE8 (BNEZS8, N32_IMM16S (insn));
|
||
insn_type = NDS32_INSN_BNEZS8;
|
||
}
|
||
break;
|
||
|
||
- case N32_BR2_IFCALL:
|
||
- if (IS_WITHIN_U (N32_IMM16S (insn), 9))
|
||
+ case N32_BR2_SOP0:
|
||
+ if (__GF (insn, 20, 5) == 0 && IS_WITHIN_U (N32_IMM16S (insn), 9))
|
||
{
|
||
insn16 = N16_TYPE9 (IFCALL9, N32_IMM16S (insn));
|
||
insn_type = NDS32_INSN_IFCALL9;
|
||
@@ -7218,7 +8711,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
case N32_OP6_JI:
|
||
if ((insn & N32_BIT (24)) == 0)
|
||
{
|
||
- /* N32_JI_J */
|
||
+ /* N32_JI_J */
|
||
if (IS_WITHIN_S (N32_IMM24S (insn), 8))
|
||
{
|
||
insn16 = N16_TYPE8 (J8, N32_IMM24S (insn));
|
||
@@ -7236,19 +8729,19 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
|
||
case N32_JREG_JR:
|
||
if (N32_JREG_HINT (insn) == 0)
|
||
{
|
||
- /* jr */
|
||
+ /* jr */
|
||
insn16 = N16_TYPE5 (JR5, N32_RB5 (insn));
|
||
insn_type = NDS32_INSN_JR5;
|
||
}
|
||
else if (N32_JREG_HINT (insn) == 1)
|
||
{
|
||
- /* ret */
|
||
+ /* ret */
|
||
insn16 = N16_TYPE5 (RET5, N32_RB5 (insn));
|
||
insn_type = NDS32_INSN_RET5;
|
||
}
|
||
else if (N32_JREG_HINT (insn) == 3)
|
||
{
|
||
- /* ifret = mov55 $sp, $sp */
|
||
+ /* ifret = mov55 $sp, $sp */
|
||
insn16 = N16_TYPE55 (MOV55, REG_SP, REG_SP);
|
||
insn_type = NDS32_INSN_IFRET;
|
||
}
|
||
@@ -7347,184 +8840,162 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn)
|
||
|
||
switch (__GF (insn16, 9, 6))
|
||
{
|
||
- case 0x4: /* add45 */
|
||
- insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- N16_RA5 (insn16));
|
||
+ case 0x4: /* add45 */
|
||
+ insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16));
|
||
goto done;
|
||
- case 0x5: /* sub45 */
|
||
- insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- N16_RA5 (insn16));
|
||
+ case 0x5: /* sub45 */
|
||
+ insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16));
|
||
goto done;
|
||
- case 0x6: /* addi45 */
|
||
- insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- N16_IMM5U (insn16));
|
||
+ case 0x6: /* addi45 */
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0x7: /* subi45 */
|
||
- insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- -N16_IMM5U (insn16));
|
||
+ case 0x7: /* subi45 */
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), -N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0x8: /* srai45 */
|
||
- insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- N16_IMM5U (insn16));
|
||
+ case 0x8: /* srai45 */
|
||
+ insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0x9: /* srli45 */
|
||
- insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16),
|
||
- N16_IMM5U (insn16));
|
||
+ case 0x9: /* srli45 */
|
||
+ insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0xa: /* slli333 */
|
||
- insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+
|
||
+ case 0xa: /* slli333 */
|
||
+ insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0xc: /* add333 */
|
||
- insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_RB3 (insn16));
|
||
+ case 0xc: /* add333 */
|
||
+ insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16));
|
||
goto done;
|
||
- case 0xd: /* sub333 */
|
||
- insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_RB3 (insn16));
|
||
+ case 0xd: /* sub333 */
|
||
+ insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16));
|
||
goto done;
|
||
- case 0xe: /* addi333 */
|
||
- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0xe: /* addi333 */
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0xf: /* subi333 */
|
||
- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- -N16_IMM3U (insn16));
|
||
+ case 0xf: /* subi333 */
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), -N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x10: /* lwi333 */
|
||
- insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+
|
||
+ case 0x10: /* lwi333 */
|
||
+ insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x12: /* lhi333 */
|
||
- insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x12: /* lhi333 */
|
||
+ insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x13: /* lbi333 */
|
||
- insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x13: /* lbi333 */
|
||
+ insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x11: /* lwi333.bi */
|
||
- insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x11: /* lwi333.bi */
|
||
+ insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x14: /* swi333 */
|
||
- insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x14: /* swi333 */
|
||
+ insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x16: /* shi333 */
|
||
- insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x16: /* shi333 */
|
||
+ insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x17: /* sbi333 */
|
||
- insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x17: /* sbi333 */
|
||
+ insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x15: /* swi333.bi */
|
||
- insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_IMM3U (insn16));
|
||
+ case 0x15: /* swi333.bi */
|
||
+ insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16));
|
||
goto done;
|
||
- case 0x18: /* addri36.sp */
|
||
- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP,
|
||
- N16_IMM6U (insn16) << 2);
|
||
+
|
||
+ case 0x18: /* addri36.sp */
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP, N16_IMM6U (insn16) << 2);
|
||
goto done;
|
||
- case 0x19: /* lwi45.fe */
|
||
- insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8,
|
||
- (N16_IMM5U (insn16) - 32));
|
||
+
|
||
+ case 0x19: /* lwi45.fe */
|
||
+ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8, (N16_IMM5U (insn16) - 32));
|
||
goto done;
|
||
- case 0x1a: /* lwi450 */
|
||
+ case 0x1a: /* lwi450 */
|
||
insn = N32_TYPE2 (LWI, N16_RT4 (insn16), N16_RA5 (insn16), 0);
|
||
goto done;
|
||
- case 0x1b: /* swi450 */
|
||
+ case 0x1b: /* swi450 */
|
||
insn = N32_TYPE2 (SWI, N16_RT4 (insn16), N16_RA5 (insn16), 0);
|
||
goto done;
|
||
|
||
- /* These are r15 implied instructions. */
|
||
- case 0x30: /* slts45 */
|
||
+ /* These are r15 implied instructions. */
|
||
+ case 0x30: /* slts45 */
|
||
insn = N32_ALU1 (SLTS, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16));
|
||
goto done;
|
||
- case 0x31: /* slt45 */
|
||
+ case 0x31: /* slt45 */
|
||
insn = N32_ALU1 (SLT, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16));
|
||
goto done;
|
||
- case 0x32: /* sltsi45 */
|
||
+ case 0x32: /* sltsi45 */
|
||
insn = N32_TYPE2 (SLTSI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0x33: /* slti45 */
|
||
+ case 0x33: /* slti45 */
|
||
insn = N32_TYPE2 (SLTI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16));
|
||
goto done;
|
||
- case 0x34: /* beqzs8, bnezs8 */
|
||
+ case 0x34: /* beqzs8, bnezs8 */
|
||
if (insn16 & N32_BIT (8))
|
||
insn = N32_BR2 (BNEZ, REG_TA, N16_IMM8S (insn16));
|
||
else
|
||
insn = N32_BR2 (BEQZ, REG_TA, N16_IMM8S (insn16));
|
||
goto done;
|
||
|
||
- case 0x35: /* break16, ex9.it */
|
||
+ case 0x35: /* break16, ex9.it */
|
||
/* Only consider range of v3 break16. */
|
||
insn = N32_TYPE0 (MISC, (N16_IMM5U (insn16) << 5) | N32_MISC_BREAK);
|
||
goto done;
|
||
|
||
- case 0x3c: /* ifcall9 */
|
||
- insn = N32_BR2 (IFCALL, 0, N16_IMM9U (insn16));
|
||
+ case 0x3c: /* ifcall9 */
|
||
+ insn = N32_BR2 (SOP0, 0, N16_IMM9U (insn16));
|
||
goto done;
|
||
- case 0x3d: /* movpi45 */
|
||
+ case 0x3d: /* movpi45 */
|
||
insn = N32_TYPE1 (MOVI, N16_RT4 (insn16), N16_IMM5U (insn16) + 16);
|
||
goto done;
|
||
|
||
- case 0x3f: /* MISC33 */
|
||
+ case 0x3f: /* MISC33 */
|
||
switch (insn16 & 0x7)
|
||
{
|
||
- case 2: /* neg33 */
|
||
+ case 2: /* neg33 */
|
||
insn = N32_TYPE2 (SUBRI, N16_RT3 (insn16), N16_RA3 (insn16), 0);
|
||
break;
|
||
- case 3: /* not33 */
|
||
- insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16),
|
||
- N16_RA3 (insn16));
|
||
+ case 3: /* not33 */
|
||
+ insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16), N16_RA3 (insn16));
|
||
break;
|
||
- case 4: /* mul33 */
|
||
- insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
- N16_RA3 (insn16));
|
||
+ case 4: /* mul33 */
|
||
+ insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16));
|
||
break;
|
||
- case 5: /* xor33 */
|
||
- insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
- N16_RA3 (insn16));
|
||
+ case 5: /* xor33 */
|
||
+ insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16));
|
||
break;
|
||
- case 6: /* and33 */
|
||
- insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
- N16_RA3 (insn16));
|
||
+ case 6: /* and33 */
|
||
+ insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16));
|
||
break;
|
||
- case 7: /* or33 */
|
||
- insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
- N16_RA3 (insn16));
|
||
+ case 7: /* or33 */
|
||
+ insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16));
|
||
break;
|
||
}
|
||
goto done;
|
||
|
||
- case 0xb:
|
||
+ case 0xb: /* ... */
|
||
switch (insn16 & 0x7)
|
||
{
|
||
- case 0: /* zeb33 */
|
||
+ case 0: /* zeb33 */
|
||
insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0xff);
|
||
break;
|
||
- case 1: /* zeh33 */
|
||
+ case 1: /* zeh33 */
|
||
insn = N32_ALU1 (ZEH, N16_RT3 (insn16), N16_RA3 (insn16), 0);
|
||
break;
|
||
- case 2: /* seb33 */
|
||
+ case 2: /* seb33 */
|
||
insn = N32_ALU1 (SEB, N16_RT3 (insn16), N16_RA3 (insn16), 0);
|
||
break;
|
||
- case 3: /* seh33 */
|
||
+ case 3: /* seh33 */
|
||
insn = N32_ALU1 (SEH, N16_RT3 (insn16), N16_RA3 (insn16), 0);
|
||
break;
|
||
- case 4: /* xlsb33 */
|
||
+ case 4: /* xlsb33 */
|
||
insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 1);
|
||
break;
|
||
- case 5: /* x11b33 */
|
||
+ case 5: /* x11b33 */
|
||
insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0x7ff);
|
||
break;
|
||
- case 6: /* bmski33 */
|
||
+ case 6: /* bmski33 */
|
||
insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
1 << __GF (insn16, 3, 3));
|
||
break;
|
||
- case 7: /* fexti33 */
|
||
+ case 7: /* fexti33 */
|
||
insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16),
|
||
(1 << (__GF (insn16, 3, 3) + 1)) - 1);
|
||
break;
|
||
@@ -7534,70 +9005,70 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn)
|
||
|
||
switch (__GF (insn16, 10, 5))
|
||
{
|
||
- case 0x0: /* mov55 or ifret16 */
|
||
+ case 0x0: /* mov55 or ifret16 */
|
||
if (mach >= MACH_V3 && N16_RT5 (insn16) == REG_SP
|
||
&& N16_RT5 (insn16) == N16_RA5 (insn16))
|
||
- insn = N32_JREG (JR, 0, 0, 0, 3);
|
||
+ insn = N32_JREG (JR, 0, 0, 0, 3);
|
||
else
|
||
- insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0);
|
||
+ insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0);
|
||
goto done;
|
||
- case 0x1: /* movi55 */
|
||
+ case 0x1: /* movi55 */
|
||
insn = N32_TYPE1 (MOVI, N16_RT5 (insn16), N16_IMM5S (insn16));
|
||
goto done;
|
||
- case 0x1b: /* addi10s (V2) */
|
||
+ case 0x1b: /* addi10s (V2) */
|
||
insn = N32_TYPE2 (ADDI, REG_SP, REG_SP, N16_IMM10S (insn16));
|
||
goto done;
|
||
}
|
||
|
||
switch (__GF (insn16, 11, 4))
|
||
{
|
||
- case 0x7: /* lwi37.fp/swi37.fp */
|
||
- if (insn16 & N32_BIT (7)) /* swi37.fp */
|
||
+ case 0x7: /* lwi37.fp/swi37.fp */
|
||
+ if (insn16 & N32_BIT (7)) /* swi37.fp */
|
||
insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
|
||
- else /* lwi37.fp */
|
||
+ else /* lwi37.fp */
|
||
insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
|
||
goto done;
|
||
- case 0x8: /* beqz38 */
|
||
+ case 0x8: /* beqz38 */
|
||
insn = N32_BR2 (BEQZ, N16_RT38 (insn16), N16_IMM8S (insn16));
|
||
goto done;
|
||
- case 0x9: /* bnez38 */
|
||
+ case 0x9: /* bnez38 */
|
||
insn = N32_BR2 (BNEZ, N16_RT38 (insn16), N16_IMM8S (insn16));
|
||
goto done;
|
||
- case 0xa: /* beqs38/j8, implied r5 */
|
||
+ case 0xa: /* beqs38/j8, implied r5 */
|
||
if (N16_RT38 (insn16) == 5)
|
||
insn = N32_JI (J, N16_IMM8S (insn16));
|
||
else
|
||
insn = N32_BR1 (BEQ, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16));
|
||
goto done;
|
||
- case 0xb: /* bnes38 and others */
|
||
+ case 0xb: /* bnes38 and others */
|
||
if (N16_RT38 (insn16) == 5)
|
||
{
|
||
switch (__GF (insn16, 5, 3))
|
||
{
|
||
- case 0: /* jr5 */
|
||
+ case 0: /* jr5 */
|
||
insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 0);
|
||
break;
|
||
- case 4: /* ret5 */
|
||
+ case 4: /* ret5 */
|
||
insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 1);
|
||
break;
|
||
- case 1: /* jral5 */
|
||
+ case 1: /* jral5 */
|
||
insn = N32_JREG (JRAL, REG_LP, N16_RA5 (insn16), 0, 0);
|
||
break;
|
||
- case 2: /* ex9.it imm5 */
|
||
+ case 2: /* ex9.it imm5 */
|
||
/* ex9.it had no 32-bit variantl. */
|
||
break;
|
||
- case 5: /* add5.pc */
|
||
+ case 5: /* add5.pc */
|
||
/* add5.pc had no 32-bit variantl. */
|
||
break;
|
||
}
|
||
}
|
||
- else /* bnes38 */
|
||
+ else /* bnes38 */
|
||
insn = N32_BR1 (BNE, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16));
|
||
goto done;
|
||
- case 0xe: /* lwi37/swi37 */
|
||
- if (insn16 & (1 << 7)) /* swi37.sp */
|
||
+ case 0xe: /* lwi37/swi37 */
|
||
+ if (insn16 & (1 << 7)) /* swi37.sp */
|
||
insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16));
|
||
- else /* lwi37.sp */
|
||
+ else /* lwi37.sp */
|
||
insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16));
|
||
goto done;
|
||
}
|
||
@@ -7650,19 +9121,19 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
|
||
switch (N32_OP6 (insn))
|
||
{
|
||
case N32_OP6_LBI:
|
||
- /* lbi.gp */
|
||
+ /* lbi.gp */
|
||
oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0);
|
||
break;
|
||
case N32_OP6_LBSI:
|
||
- /* lbsi.gp */
|
||
+ /* lbsi.gp */
|
||
oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), N32_BIT (19));
|
||
break;
|
||
case N32_OP6_SBI:
|
||
- /* sbi.gp */
|
||
+ /* sbi.gp */
|
||
oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0);
|
||
break;
|
||
case N32_OP6_ORI:
|
||
- /* addi.gp */
|
||
+ /* addi.gp */
|
||
oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19));
|
||
break;
|
||
}
|
||
@@ -7672,15 +9143,15 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
|
||
switch (N32_OP6 (insn))
|
||
{
|
||
case N32_OP6_LHI:
|
||
- /* lhi.gp */
|
||
+ /* lhi.gp */
|
||
oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0);
|
||
break;
|
||
case N32_OP6_LHSI:
|
||
- /* lhsi.gp */
|
||
+ /* lhsi.gp */
|
||
oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (18));
|
||
break;
|
||
case N32_OP6_SHI:
|
||
- /* shi.gp */
|
||
+ /* shi.gp */
|
||
oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (19));
|
||
break;
|
||
}
|
||
@@ -7690,11 +9161,11 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
|
||
switch (N32_OP6 (insn))
|
||
{
|
||
case N32_OP6_LWI:
|
||
- /* lwi.gp */
|
||
+ /* lwi.gp */
|
||
oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3));
|
||
break;
|
||
case N32_OP6_SWI:
|
||
- /* swi.gp */
|
||
+ /* swi.gp */
|
||
oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3));
|
||
break;
|
||
}
|
||
@@ -7835,7 +9306,7 @@ calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info,
|
||
bfd_vma *local_got_offsets;
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
struct elf_link_hash_entry *h;
|
||
- struct elf_nds32_link_hash_table *htab = nds32_elf_hash_table (link_info);
|
||
+ struct elf_link_hash_table *ehtab = elf_hash_table (link_info);
|
||
|
||
/* An external symbol. */
|
||
symndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
||
@@ -7847,18 +9318,13 @@ calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info,
|
||
if (symndx >= 0)
|
||
{
|
||
BFD_ASSERT (h != NULL);
|
||
- return (htab->root.sgot->output_section->vma
|
||
- + htab->root.sgot->output_offset
|
||
- + h->got.offset);
|
||
- }
|
||
- else
|
||
- {
|
||
- local_got_offsets = elf_local_got_offsets (abfd);
|
||
- BFD_ASSERT (local_got_offsets != NULL);
|
||
- return (htab->root.sgot->output_section->vma
|
||
- + htab->root.sgot->output_offset
|
||
- + local_got_offsets[ELF32_R_SYM (irel->r_info)]);
|
||
+ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset
|
||
+ + h->got.offset;
|
||
}
|
||
+ local_got_offsets = elf_local_got_offsets (abfd);
|
||
+ BFD_ASSERT (local_got_offsets != NULL);
|
||
+ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset
|
||
+ + local_got_offsets[ELF32_R_SYM (irel->r_info)];
|
||
|
||
/* The _GLOBAL_OFFSET_TABLE_ may be undefweak(or should be?). */
|
||
/* The check of h->root.type is passed. */
|
||
@@ -7899,7 +9365,6 @@ is_convert_32_to_16 (bfd *abfd, asection *sec,
|
||
bfd_vma mem_addr;
|
||
uint32_t insn = 0;
|
||
Elf_Internal_Rela *pc_rel;
|
||
- int pic_ext_target = 0;
|
||
Elf_Internal_Shdr *symtab_hdr;
|
||
Elf_Internal_Sym *isymbuf = NULL;
|
||
int convert_type;
|
||
@@ -7938,8 +9403,7 @@ is_convert_32_to_16 (bfd *abfd, asection *sec,
|
||
|| ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA
|
||
|| ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL)
|
||
{
|
||
- off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr);
|
||
if (off >= ACCURATE_8BIT_S1 || off < -ACCURATE_8BIT_S1
|
||
|| off == 0)
|
||
return FALSE;
|
||
@@ -7948,10 +9412,8 @@ is_convert_32_to_16 (bfd *abfd, asection *sec,
|
||
else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA)
|
||
{
|
||
/* movi => movi55 */
|
||
- mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf,
|
||
- symtab_hdr);
|
||
- /* mem_addr is unsigned, but the value should
|
||
- be between [-16, 15]. */
|
||
+ mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf, symtab_hdr);
|
||
+ /* mem_addr is unsigned, but the value should be between [-16, 15]. */
|
||
if ((mem_addr + 0x10) >> 5)
|
||
return FALSE;
|
||
break;
|
||
@@ -7980,14 +9442,12 @@ is_convert_32_to_16 (bfd *abfd, asection *sec,
|
||
|| ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_LOADSTORE)
|
||
&& (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_DWARF2_OP1_RELA)))
|
||
{
|
||
- /* Prevent unresolved addi instruction translate
|
||
- to addi45 or addi333. */
|
||
+ /* Prevent unresolved addi instruction translate to addi45 or addi333. */
|
||
return FALSE;
|
||
}
|
||
else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA))
|
||
{
|
||
- off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr);
|
||
if (off >= ACCURATE_U9BIT_S1 || off <= 0)
|
||
return FALSE;
|
||
break;
|
||
@@ -8085,7 +9545,7 @@ static Elf_Internal_Rela *
|
||
find_relocs_at_address_addr (Elf_Internal_Rela *reloc,
|
||
Elf_Internal_Rela *relocs,
|
||
Elf_Internal_Rela *irelend,
|
||
- enum elf_nds32_reloc_type reloc_type,
|
||
+ unsigned char reloc_type,
|
||
bfd_vma offset_p)
|
||
{
|
||
Elf_Internal_Rela *rel_t = NULL;
|
||
@@ -8281,8 +9741,9 @@ insert_nds32_elf_blank (nds32_elf_blank_t **blank_p, bfd_vma addr, bfd_vma len)
|
||
|
||
if (addr < blank_t->offset + blank_t->size)
|
||
{
|
||
- if (addr > blank_t->offset + blank_t->size)
|
||
- blank_t->size = addr - blank_t->offset;
|
||
+ /* Extend the origin blank. */
|
||
+ if (addr + len > blank_t->offset + blank_t->size)
|
||
+ blank_t->size = addr + len - blank_t->offset;
|
||
}
|
||
else
|
||
{
|
||
@@ -8414,7 +9875,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
|
||
|
||
/* Relocations MUST be kept in memory, because relaxation adjust them. */
|
||
internal_relocs = _bfd_elf_link_read_relocs (abfd, sect, NULL, NULL,
|
||
- TRUE /* keep_memory */);
|
||
+ TRUE /* keep_memory */);
|
||
irelend = internal_relocs + sect->reloc_count;
|
||
|
||
blank_t = blank_head;
|
||
@@ -8436,7 +9897,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
|
||
unsigned long val = 0;
|
||
unsigned long mask;
|
||
long before, between;
|
||
- long offset = 0;
|
||
+ long offset;
|
||
|
||
switch (ELF32_R_TYPE (irel->r_info))
|
||
{
|
||
@@ -8468,28 +9929,23 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
|
||
-- before ---| *****************
|
||
--------------------- between ---|
|
||
|
||
- We only care how much data are relax between DIFF,
|
||
- marked as ***. */
|
||
+ We only care how much data are relax between DIFF, marked as ***. */
|
||
|
||
before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0);
|
||
- between = get_nds32_elf_blank_total (&blank_t,
|
||
- irel->r_addend + offset, 0);
|
||
+ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + offset, 0);
|
||
if (between == before)
|
||
goto done_adjust_diff;
|
||
|
||
switch (ELF32_R_TYPE (irel->r_info))
|
||
{
|
||
case R_NDS32_DIFF8:
|
||
- bfd_put_8 (abfd, offset - (between - before),
|
||
- contents + irel->r_offset);
|
||
+ bfd_put_8 (abfd, offset - (between - before), contents + irel->r_offset);
|
||
break;
|
||
case R_NDS32_DIFF16:
|
||
- bfd_put_16 (abfd, offset - (between - before),
|
||
- contents + irel->r_offset);
|
||
+ bfd_put_16 (abfd, offset - (between - before), contents + irel->r_offset);
|
||
break;
|
||
case R_NDS32_DIFF32:
|
||
- bfd_put_32 (abfd, offset - (between - before),
|
||
- contents + irel->r_offset);
|
||
+ bfd_put_32 (abfd, offset - (between - before), contents + irel->r_offset);
|
||
break;
|
||
}
|
||
}
|
||
@@ -8501,12 +9957,10 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
|
||
unsigned long before, between;
|
||
bfd_byte *endp, *p;
|
||
|
||
- val = _bfd_read_unsigned_leb128 (abfd, contents + irel->r_offset,
|
||
- &len);
|
||
+ val = _bfd_read_unsigned_leb128 (abfd, contents + irel->r_offset, &len);
|
||
|
||
before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0);
|
||
- between = get_nds32_elf_blank_total (&blank_t,
|
||
- irel->r_addend + val, 0);
|
||
+ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + val, 0);
|
||
if (between == before)
|
||
goto done_adjust_diff;
|
||
|
||
@@ -8523,16 +9977,14 @@ done_adjust_diff:
|
||
if (sec == sect)
|
||
{
|
||
raddr = irel->r_offset;
|
||
- irel->r_offset -= get_nds32_elf_blank_total (&blank_t2,
|
||
- irel->r_offset, 1);
|
||
+ irel->r_offset -= get_nds32_elf_blank_total (&blank_t2, irel->r_offset, 1);
|
||
|
||
if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
|
||
continue;
|
||
if (blank_t2 && blank_t2->next
|
||
- && (blank_t2->offset > raddr
|
||
- || blank_t2->next->offset <= raddr))
|
||
- _bfd_error_handler
|
||
- (_("%B: Error: search_nds32_elf_blank reports wrong node\n"), abfd);
|
||
+ && (blank_t2->offset > raddr || blank_t2->next->offset <= raddr))
|
||
+ _bfd_error_handler (_("%B: %s\n"), abfd,
|
||
+ "Error: search_nds32_elf_blank reports wrong node");
|
||
|
||
/* Mark reloc in deleted portion as NONE.
|
||
For some relocs like R_NDS32_LABEL that doesn't modify the
|
||
@@ -8584,11 +10036,9 @@ done_adjust_diff:
|
||
isym->st_value -= ahead;
|
||
|
||
/* Adjust function size. */
|
||
- if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC
|
||
- && isym->st_size > 0)
|
||
- isym->st_size -=
|
||
- get_nds32_elf_blank_total
|
||
- (&blank_t, orig_addr + isym->st_size, 0) - ahead;
|
||
+ if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC && isym->st_size > 0)
|
||
+ isym->st_size -= get_nds32_elf_blank_total
|
||
+ (&blank_t, orig_addr + isym->st_size, 0) - ahead;
|
||
}
|
||
}
|
||
}
|
||
@@ -8617,9 +10067,8 @@ done_adjust_diff:
|
||
|
||
/* Adjust function size. */
|
||
if (sym_hash->type == STT_FUNC)
|
||
- sym_hash->size -=
|
||
- get_nds32_elf_blank_total
|
||
- (&blank_t, orig_addr + sym_hash->size, 0) - ahead;
|
||
+ sym_hash->size -= get_nds32_elf_blank_total
|
||
+ (&blank_t, orig_addr + sym_hash->size, 0) - ahead;
|
||
|
||
}
|
||
}
|
||
@@ -8743,7 +10192,7 @@ relax_range_measurement (bfd *abfd)
|
||
bfd_vma align;
|
||
static int decide_relax_range = 0;
|
||
int i;
|
||
- int range_number = sizeof (sdata_init_range) / sizeof (sdata_init_range[0]);
|
||
+ int range_number = ARRAY_SIZE (sdata_init_range);
|
||
|
||
if (decide_relax_range)
|
||
return;
|
||
@@ -8789,11 +10238,7 @@ relax_range_measurement (bfd *abfd)
|
||
#define IS_OPTIMIZE(addend) ((addend) & 0x40000000)
|
||
#define IS_16BIT_ON(addend) ((addend) & 0x20000000)
|
||
|
||
-static const char * unrecognized_reloc_msg =
|
||
- /* xgettext:c-format */
|
||
- N_("%B: warning: %s points to unrecognized reloc at %#Lx");
|
||
-
|
||
-/* Relax LONGCALL1 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL1 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -8803,19 +10248,19 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
{
|
||
/* There are 3 variations for LONGCALL1
|
||
case 4-4-2; 16-bit on, optimize off or optimize for space
|
||
- sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral5 ta ;
|
||
+ jral5 ta ;
|
||
|
||
case 4-4-4; 16-bit off, optimize don't care
|
||
- sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral ta ;
|
||
+ jral ta ;
|
||
|
||
case 4-4-4; 16-bit on, optimize for speed
|
||
- sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral ta ;
|
||
+ jral ta ;
|
||
Check code for -mlong-calls output. */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
@@ -8826,7 +10271,6 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
uint16_t insn16;
|
||
|
||
@@ -8843,21 +10287,21 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (hi_irelfn == irelend || lo_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL1",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL1 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr);
|
||
|
||
/* This condition only happened when symbol is undefined. */
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
- /* Relax to: jal symbol; 25_PCREL */
|
||
+ /* Relax to: jal symbol; 25_PCREL */
|
||
/* For simplicity of coding, we are going to modify the section
|
||
contents, the section relocs, and the BFD symbol table. We
|
||
must tell the rest of the code not to free up this
|
||
@@ -8894,7 +10338,7 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
}
|
||
|
||
#define CONVERT_CONDITION_CALL(insn) (((insn) & 0xffff0000) ^ 0x90000)
|
||
-/* Relax LONGCALL2 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL2 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -8904,7 +10348,7 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
{
|
||
/* bltz rt, .L1 ; LONGCALL2
|
||
jal symbol ; 25_PCREL
|
||
- .L1: */
|
||
+ .L1: */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
being loaded. This reloc will tell us which function is
|
||
@@ -8913,7 +10357,6 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_vma laddr;
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *i1_irelfn, *cond_irelfn, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -8924,23 +10367,23 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (i1_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL2",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL2 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
insn = bfd_getb32 (contents + laddr);
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr);
|
||
|
||
if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
|| foff >= CONSERVATIVE_16BIT_S1)
|
||
return FALSE;
|
||
|
||
/* Relax to bgezal rt, label ; 17_PCREL
|
||
- or bltzal rt, label ; 17_PCREL */
|
||
+ or bltzal rt, label ; 17_PCREL */
|
||
|
||
/* Convert to complimentary conditional call. */
|
||
insn = CONVERT_CONDITION_CALL (insn);
|
||
@@ -8974,7 +10417,7 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGCALL3 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL3 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -8984,25 +10427,25 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
{
|
||
/* There are 3 variations for LONGCALL3
|
||
case 4-4-4-2; 16-bit on, optimize off or optimize for space
|
||
- bltz rt, $1 ; LONGCALL3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bltz rt, $1 ; LONGCALL3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral5 ta ;
|
||
+ jral5 ta ;
|
||
$1
|
||
|
||
case 4-4-4-4; 16-bit off, optimize don't care
|
||
- bltz rt, $1 ; LONGCALL3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bltz rt, $1 ; LONGCALL3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral ta ;
|
||
+ jral ta ;
|
||
$1
|
||
|
||
case 4-4-4-4; 16-bit on, optimize for speed
|
||
- bltz rt, $1 ; LONGCALL3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bltz rt, $1 ; LONGCALL3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jral ta ;
|
||
- $1 */
|
||
+ jral ta ;
|
||
+ $1 */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
being loaded. This reloc will tell us which function is
|
||
@@ -9012,7 +10455,6 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
uint16_t insn16;
|
||
|
||
@@ -9030,16 +10472,16 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (hi_irelfn == irelend || lo_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL3",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL3 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -9047,7 +10489,7 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
|
||
{
|
||
/* Relax to bgezal rt, label ; 17_PCREL
|
||
- or bltzal rt, label ; 17_PCREL */
|
||
+ or bltzal rt, label ; 17_PCREL */
|
||
|
||
/* Convert to complimentary conditional call. */
|
||
insn = CONVERT_CONDITION_CALL (insn);
|
||
@@ -9112,7 +10554,7 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP1 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP1 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9122,19 +10564,19 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
{
|
||
/* There are 3 variations for LONGJUMP1
|
||
case 4-4-2; 16-bit bit on, optimize off or optimize for space
|
||
- sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
- ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr5 ta ;
|
||
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
+ ori ta, ta, lo12(symbol) ; LO12S0
|
||
+ jr5 ta ;
|
||
|
||
case 4-4-4; 16-bit off, optimize don't care
|
||
- sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
- ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr ta ;
|
||
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
+ ori ta, ta, lo12(symbol) ; LO12S0
|
||
+ jr ta ;
|
||
|
||
case 4-4-4; 16-bit on, optimize for speed
|
||
- sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
- ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr ta ; */
|
||
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
|
||
+ ori ta, ta, lo12(symbol) ; LO12S0
|
||
+ jr ta ; */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
being loaded. This reloc will tell us which function is
|
||
@@ -9145,7 +10587,6 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
int insn16_on; /* 16-bit on/off. */
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
uint16_t insn16;
|
||
unsigned long reloc;
|
||
@@ -9164,23 +10605,23 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_LO12S0_ORI_RELA, laddr + 4);
|
||
if (hi_irelfn == irelend || lo_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP1",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP1 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1
|
||
|| foff < -CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
if (insn16_on && foff >= -ACCURATE_8BIT_S1
|
||
&& foff < ACCURATE_8BIT_S1 && (seq_len & 0x2))
|
||
{
|
||
- /* j8 label */
|
||
+ /* j8 label */
|
||
/* 16-bit on, but not optimized for speed. */
|
||
reloc = R_NDS32_9_PCREL_RELA;
|
||
insn16 = INSN_J8;
|
||
@@ -9191,7 +10632,7 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
}
|
||
else
|
||
{
|
||
- /* j label */
|
||
+ /* j label */
|
||
reloc = R_NDS32_25_PCREL_RELA;
|
||
insn = INSN_J;
|
||
bfd_putb32 (insn, contents + irel->r_offset);
|
||
@@ -9275,14 +10716,14 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn,
|
||
switch ((insn16 & 0xf000) >> 12)
|
||
{
|
||
case 0xc:
|
||
- /* beqz38 or bnez38 */
|
||
+ /* beqz38 or bnez38 */
|
||
comp_insn16 = (insn16 ^ 0x0800) & 0xff00;
|
||
comp_insn = (comp_insn16 & 0x0800) ? INSN_BNEZ : INSN_BEQZ;
|
||
comp_insn |= ((comp_insn16 & 0x0700) >> 8) << 20;
|
||
break;
|
||
|
||
case 0xd:
|
||
- /* beqs38 or bnes38 */
|
||
+ /* beqs38 or bnes38 */
|
||
comp_insn16 = (insn16 ^ 0x0800) & 0xff00;
|
||
comp_insn = (comp_insn16 & 0x0800) ? INSN_BNE : INSN_BEQ;
|
||
comp_insn |= (((comp_insn16 & 0x0700) >> 8) << 20)
|
||
@@ -9290,7 +10731,7 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn,
|
||
break;
|
||
|
||
case 0xe:
|
||
- /* beqzS8 or bnezS8 */
|
||
+ /* beqzS8 or bnezS8 */
|
||
comp_insn16 = (insn16 ^ 0x0100) & 0xff00;
|
||
comp_insn = (comp_insn16 & 0x0100) ? INSN_BNEZ : INSN_BEQZ;
|
||
comp_insn |= REG_R15 << 20;
|
||
@@ -9306,7 +10747,7 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn,
|
||
*re_insn16 = comp_insn16;
|
||
}
|
||
|
||
-/* Relax LONGJUMP2 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP2 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9329,7 +10770,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
case 4-4; 1st insn convertible, 16-bit on, optimize for speed
|
||
bne rt, ra, $1 ; LONGJUMP2
|
||
j label ; 25_PCREL
|
||
- $1: */
|
||
+ $1: */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
being loaded. This reloc will tell us which function is
|
||
@@ -9338,7 +10779,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_vma laddr;
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
Elf_Internal_Rela *i2_irelfn, *cond_irelfn, *irelend;
|
||
- int pic_ext_target = 0, first_size;
|
||
+ int first_size;
|
||
unsigned int i;
|
||
bfd_signed_vma foff;
|
||
uint32_t insn, re_insn = 0;
|
||
@@ -9359,7 +10800,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
irelend, R_NDS32_25_PCREL_RELA,
|
||
laddr + first_size);
|
||
|
||
- for (i = 0; i < sizeof (checked_types) / sizeof(checked_types[0]); i++)
|
||
+ for (i = 0; i < ARRAY_SIZE (checked_types); i++)
|
||
{
|
||
cond_irelfn =
|
||
find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
@@ -9370,16 +10811,16 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (i2_irelfn == irelend || cond_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP2",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP2 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
foff =
|
||
- calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
+ calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr);
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
|| foff >= CONSERVATIVE_16BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -9422,7 +10863,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
&& (foff >= -(ACCURATE_14BIT_S1 - first_size)
|
||
&& foff < ACCURATE_14BIT_S1 - first_size))
|
||
{
|
||
- /* beqs label ; 15_PCREL */
|
||
+ /* beqs label ; 15_PCREL */
|
||
bfd_putb32 (re_insn, contents + irel->r_offset);
|
||
*insn_len = 4;
|
||
reloc = R_NDS32_15_PCREL_RELA;
|
||
@@ -9432,7 +10873,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
&& foff >= -CONSERVATIVE_16BIT_S1
|
||
&& foff < CONSERVATIVE_16BIT_S1)
|
||
{
|
||
- /* beqz label ; 17_PCREL */
|
||
+ /* beqz label ; 17_PCREL */
|
||
bfd_putb32 (re_insn, contents + irel->r_offset);
|
||
*insn_len = 4;
|
||
reloc = R_NDS32_17_PCREL_RELA;
|
||
@@ -9465,7 +10906,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP3 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP3 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9476,42 +10917,42 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
/* There are 5 variations for LONGJUMP3
|
||
case 1: 2-4-4-2; 1st insn convertible, 16-bit on,
|
||
optimize off or optimize for space
|
||
- bnes38 rt, ra, $1 ; LONGJUMP3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bnes38 rt, ra, $1 ; LONGJUMP3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr5 ta ;
|
||
- $1: ;
|
||
+ jr5 ta ;
|
||
+ $1: ;
|
||
|
||
case 2: 2-4-4-2; 1st insn convertible, 16-bit on, optimize for speed
|
||
- bnes38 rt, ra, $1 ; LONGJUMP3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bnes38 rt, ra, $1 ; LONGJUMP3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr5 ta ;
|
||
- $1: ; LABEL
|
||
+ jr5 ta ;
|
||
+ $1: ; LABEL
|
||
|
||
case 3: 4-4-4-2; 1st insn not convertible, 16-bit on,
|
||
optimize off or optimize for space
|
||
- bne rt, ra, $1 ; LONGJUMP3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bne rt, ra, $1 ; LONGJUMP3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr5 ta ;
|
||
- $1: ;
|
||
+ jr5 ta ;
|
||
+ $1: ;
|
||
|
||
case 4: 4-4-4-4; 1st insn don't care, 16-bit off, optimize don't care
|
||
16-bit off if no INSN16
|
||
- bne rt, ra, $1 ; LONGJUMP3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bne rt, ra, $1 ; LONGJUMP3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr ta ;
|
||
- $1: ;
|
||
+ jr ta ;
|
||
+ $1: ;
|
||
|
||
case 5: 4-4-4-4; 1st insn not convertible, 16-bit on, optimize for speed
|
||
16-bit off if no INSN16
|
||
- bne rt, ra, $1 ; LONGJUMP3
|
||
- sethi ta, hi20(symbol) ; HI20
|
||
+ bne rt, ra, $1 ; LONGJUMP3
|
||
+ sethi ta, hi20(symbol) ; HI20
|
||
ori ta, ta, lo12(symbol) ; LO12S0
|
||
- jr ta ;
|
||
- $1: ; LABEL */
|
||
+ jr ta ;
|
||
+ $1: ; LABEL */
|
||
|
||
/* Get the reloc for the address from which the register is
|
||
being loaded. This reloc will tell us which function is
|
||
@@ -9523,7 +10964,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_vma laddr;
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend;
|
||
- int pic_ext_target = 0, first_size;
|
||
+ int first_size;
|
||
unsigned int i;
|
||
bfd_signed_vma foff;
|
||
uint32_t insn, re_insn = 0;
|
||
@@ -9551,7 +10992,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_LO12S0_ORI_RELA,
|
||
laddr + first_size + 4);
|
||
|
||
- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
|
||
+ for (i = 0; i < ARRAY_SIZE (checked_types); i++)
|
||
{
|
||
cond_irelfn =
|
||
find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
@@ -9562,16 +11003,16 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (hi_irelfn == irelend || lo_irelfn == irelend || cond_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP3",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP3 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -9624,7 +11065,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
&& (foff >= -(ACCURATE_14BIT_S1 - first_size)
|
||
&& foff < ACCURATE_14BIT_S1 - first_size))
|
||
{
|
||
- /* beqs label ; 15_PCREL */
|
||
+ /* beqs label ; 15_PCREL */
|
||
bfd_putb32 (re_insn, contents + irel->r_offset);
|
||
*insn_len = 4;
|
||
reloc = R_NDS32_15_PCREL_RELA;
|
||
@@ -9635,7 +11076,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
&& foff >= -CONSERVATIVE_16BIT_S1
|
||
&& foff < CONSERVATIVE_16BIT_S1)
|
||
{
|
||
- /* beqz label ; 17_PCREL */
|
||
+ /* beqz label ; 17_PCREL */
|
||
bfd_putb32 (re_insn, contents + irel->r_offset);
|
||
*insn_len = 4;
|
||
reloc = R_NDS32_17_PCREL_RELA;
|
||
@@ -9661,7 +11102,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
case 4-4; 1st insn convertible, 16-bit on, optimize for speed
|
||
bne rt, ra, $1 ; LONGJUMP2
|
||
j label ; 25_PCREL
|
||
- $1 */
|
||
+ $1 */
|
||
|
||
/* Offset for first instruction. */
|
||
|
||
@@ -9711,7 +11152,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGCALL4 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL4 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9728,7 +11169,6 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irel, *ptr_irel, *insn_irel, *em_irel, *call_irel;
|
||
Elf_Internal_Rela *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -9742,21 +11182,21 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (hi_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr);
|
||
|
||
/* This condition only happened when symbol is undefined. */
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
- /* Relax to: jal symbol; 25_PCREL */
|
||
+ /* Relax to: jal symbol; 25_PCREL */
|
||
/* For simplicity of coding, we are going to modify the section
|
||
contents, the section relocs, and the BFD symbol table. We
|
||
must tell the rest of the code not to free up this
|
||
@@ -9772,8 +11212,9 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (ptr_irel == irelend || em_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
/* Check these is enough space to insert jal in R_NDS32_EMPTY. */
|
||
@@ -9812,7 +11253,7 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGCALL5 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL5 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9828,7 +11269,6 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_vma laddr;
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *cond_irel, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -9843,21 +11283,21 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_25_PCREL_RELA, irel->r_addend);
|
||
if (cond_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL5",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL5 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr);
|
||
|
||
if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
|| foff >= CONSERVATIVE_16BIT_S1)
|
||
return FALSE;
|
||
|
||
/* Relax to bgezal rt, label ; 17_PCREL
|
||
- or bltzal rt, label ; 17_PCREL */
|
||
+ or bltzal rt, label ; 17_PCREL */
|
||
|
||
/* Convert to complimentary conditional call. */
|
||
insn = CONVERT_CONDITION_CALL (insn);
|
||
@@ -9889,7 +11329,7 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGCALL6 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGCALL6 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -9907,7 +11347,6 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_vma laddr;
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *em_irel, *cond_irel, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -9921,16 +11360,16 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (em_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL6",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -9943,7 +11382,7 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
|
||
{
|
||
/* Relax to bgezal rt, label ; 17_PCREL
|
||
- or bltzal rt, label ; 17_PCREL */
|
||
+ or bltzal rt, label ; 17_PCREL */
|
||
|
||
/* Convert to complimentary conditional call. */
|
||
*insn_len = 0;
|
||
@@ -9959,8 +11398,9 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_PTR_RESOLVED, irel->r_addend);
|
||
if (cond_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd,
|
||
- "R_NDS32_LONGCALL6", irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
cond_irel->r_addend = 1;
|
||
@@ -10008,8 +11448,9 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_PTR_RESOLVED, irel->r_addend);
|
||
if (cond_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd,
|
||
- "R_NDS32_LONGCALL6", irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
cond_irel->r_addend = 1;
|
||
@@ -10024,7 +11465,7 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP4 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP4 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -10041,7 +11482,6 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irel, *ptr_irel, *em_irel, *call_irel, *irelend;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -10058,21 +11498,21 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (hi_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1
|
||
|| foff < -CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
/* Convert it to "j label", it may be converted to j8 in the final
|
||
- pass of relaxation. Therefore, we do not consider this currently. */
|
||
+ pass of relaxation. Therefore, we do not consider this currently.*/
|
||
ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
R_NDS32_PTR_RESOLVED, irel->r_addend);
|
||
em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
@@ -10080,8 +11520,9 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (ptr_irel == irelend || em_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
@@ -10109,7 +11550,7 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP5 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP5 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -10131,7 +11572,6 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
bfd_vma laddr;
|
||
Elf_Internal_Rela *cond_irel, *irelend;
|
||
- int pic_ext_target = 0;
|
||
unsigned int i;
|
||
bfd_signed_vma foff;
|
||
uint32_t insn, re_insn = 0;
|
||
@@ -10154,16 +11594,16 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_25_PCREL_RELA, irel->r_addend);
|
||
if (cond_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP5",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP5 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
|
||
|| foff >= CONSERVATIVE_16BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -10208,7 +11648,7 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
/* Clean relocations. */
|
||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
|
||
- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
|
||
+ for (i = 0; i < ARRAY_SIZE (checked_types); i++)
|
||
{
|
||
cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
checked_types[i], laddr);
|
||
@@ -10234,7 +11674,7 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP6 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP6 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -10265,7 +11705,6 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
int reloc_off = 0, cond_removed = 0;
|
||
bfd_vma laddr;
|
||
Elf_Internal_Rela *cond_irel, *em_irel, *irelend, *insn_irel;
|
||
- int pic_ext_target = 0;
|
||
unsigned int i;
|
||
bfd_signed_vma foff;
|
||
uint32_t insn, re_insn = 0;
|
||
@@ -10283,16 +11722,16 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (em_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP6",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP6 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1
|
||
|| foff >= CONSERVATIVE_24BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -10318,7 +11757,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
if (N32_OP6 (re_insn) == N32_OP6_BR1
|
||
&& (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1))
|
||
{
|
||
- /* beqs label ; 15_PCREL */
|
||
+ /* beqs label ; 15_PCREL */
|
||
bfd_putb32 (re_insn, contents + em_irel->r_offset);
|
||
reloc = R_NDS32_15_PCREL_RELA;
|
||
cond_removed = 1;
|
||
@@ -10326,7 +11765,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
else if (N32_OP6 (re_insn) == N32_OP6_BR2
|
||
&& foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
|
||
{
|
||
- /* beqz label ; 17_PCREL */
|
||
+ /* beqz label ; 17_PCREL */
|
||
bfd_putb32 (re_insn, contents + em_irel->r_offset);
|
||
reloc = R_NDS32_17_PCREL_RELA;
|
||
cond_removed = 1;
|
||
@@ -10383,7 +11822,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
/* Clear relocations. */
|
||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
|
||
|
||
- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
|
||
+ for (i = 0; i < ARRAY_SIZE (checked_types); i++)
|
||
{
|
||
cond_irel =
|
||
find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
@@ -10415,7 +11854,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Relax LONGJUMP7 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LONGJUMP7 relocation for nds32_elf_relax_section.*/
|
||
|
||
static bfd_boolean
|
||
nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
@@ -10435,7 +11874,6 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
bfd_vma laddr;
|
||
Elf_Internal_Rela *cond_irel, *irelend, *insn_irel;
|
||
- int pic_ext_target = 0;
|
||
bfd_signed_vma foff;
|
||
uint32_t insn, re_insn = 0;
|
||
uint16_t insn16;
|
||
@@ -10453,16 +11891,16 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
R_NDS32_15_PCREL_RELA, irel->r_addend);
|
||
if (cond_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP7",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LONGJUMP7 points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
/* Get the value of the symbol referred to by the reloc. */
|
||
- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
|
||
- &pic_ext_target);
|
||
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr);
|
||
|
||
- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_8BIT_S1
|
||
+ if (foff == 0 || foff < -CONSERVATIVE_8BIT_S1
|
||
|| foff >= CONSERVATIVE_8BIT_S1)
|
||
return FALSE;
|
||
|
||
@@ -10516,6 +11954,123 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
return TRUE;
|
||
}
|
||
|
||
+/* Record the offset to gp, and check if it changed after relaxing.
|
||
+ If the offset is fixed or the offset is near enough, try to relax
|
||
+ the pattern. This is avoid truncated to fit when relaxing fixed
|
||
+ address symbol. Ex: _stack. */
|
||
+static bfd_boolean
|
||
+nds32_elf_relax_guard (bfd_vma *access_addr, bfd_vma local_sda, asection *sec,
|
||
+ Elf_Internal_Rela *irel, bfd_boolean *again,
|
||
+ bfd_boolean init,
|
||
+ struct elf_nds32_link_hash_table *table,
|
||
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr)
|
||
+
|
||
+{
|
||
+ /* The default linker script value. */
|
||
+ int offset_to_gp;
|
||
+ static bfd_boolean sec_pass = FALSE;
|
||
+ static asection *first_sec = NULL, *sym_sec;
|
||
+ /* Record the number of instructions which may be removed. */
|
||
+ static int count = 0, record_count;
|
||
+ Elf_Internal_Sym *isym;
|
||
+ struct elf_link_hash_entry *h = NULL;
|
||
+ int indx;
|
||
+ unsigned long r_symndx;
|
||
+ bfd *abfd = sec->owner;
|
||
+ static bfd_vma record_sda = 0;
|
||
+ int sda_offset = 0;
|
||
+
|
||
+ /* Force doing relaxation when hyper-relax is high. */
|
||
+ if (table->hyper_relax == 2)
|
||
+ return TRUE;
|
||
+
|
||
+ /* Record the first section to get the round. */
|
||
+ if (init)
|
||
+ {
|
||
+ if (!first_sec)
|
||
+ first_sec = sec;
|
||
+ else if (first_sec == sec)
|
||
+ {
|
||
+ record_count = count;
|
||
+ count = 0;
|
||
+ sec_pass = TRUE;
|
||
+ }
|
||
+
|
||
+ if (!sec_pass)
|
||
+ *again = TRUE;
|
||
+
|
||
+ return TRUE;
|
||
+ }
|
||
+
|
||
+ if (record_sda == 0)
|
||
+ record_sda = local_sda;
|
||
+ else if (local_sda > record_sda)
|
||
+ /* In normal case, SDA is fixed or smaller except there is
|
||
+ DATA_SEGMENT_ALIGN in linker script.*/
|
||
+ sda_offset = local_sda - record_sda;
|
||
+
|
||
+ /* Although we doesn't delete all instructions here, counting all of
|
||
+ them to be conservative. */
|
||
+ count++;
|
||
+
|
||
+ r_symndx = ELF32_R_SYM (irel->r_info);
|
||
+ /* Global symbols. */
|
||
+ if (r_symndx >= symtab_hdr->sh_info)
|
||
+ {
|
||
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
||
+ h = elf_sym_hashes (abfd)[indx];
|
||
+ sym_sec = h->root.u.def.section;
|
||
+ if (NDS32_GUARD_SEC_P (sym_sec->flags)
|
||
+ || bfd_is_abs_section (sym_sec))
|
||
+ {
|
||
+ /* Forbid doing relaxation when hyper-relax is low. */
|
||
+ if (table->hyper_relax == 0)
|
||
+ return FALSE;
|
||
+
|
||
+ offset_to_gp = *access_addr - local_sda;
|
||
+ if (elf32_nds32_hash_entry (h)->offset_to_gp == 0)
|
||
+ elf32_nds32_hash_entry (h)->offset_to_gp = offset_to_gp;
|
||
+ else if (abs (elf32_nds32_hash_entry (h)->offset_to_gp)
|
||
+ < abs (offset_to_gp) - sda_offset)
|
||
+ {
|
||
+ if (*access_addr >= local_sda)
|
||
+ *access_addr += (record_count * 4);
|
||
+ else
|
||
+ *access_addr -= (record_count * 4);
|
||
+ }
|
||
+ return sec_pass;
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ if (!elf32_nds32_allocate_local_sym_info (abfd))
|
||
+ return FALSE;
|
||
+ isym = isymbuf + r_symndx;
|
||
+
|
||
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||
+ if (NDS32_GUARD_SEC_P (sym_sec->flags))
|
||
+ {
|
||
+ /* Forbid doing relaxation when hyper-relax is low. */
|
||
+ if (table->hyper_relax == 0)
|
||
+ return FALSE;
|
||
+
|
||
+ offset_to_gp = *access_addr - local_sda;
|
||
+ if (elf32_nds32_local_gp_offset (abfd)[r_symndx] == 0)
|
||
+ elf32_nds32_local_gp_offset (abfd)[r_symndx] = offset_to_gp;
|
||
+ else if (abs (elf32_nds32_local_gp_offset (abfd)[r_symndx])
|
||
+ < abs (offset_to_gp) - sda_offset)
|
||
+ {
|
||
+ if (*access_addr >= local_sda)
|
||
+ *access_addr += (record_count * 4);
|
||
+ else
|
||
+ *access_addr -= (record_count * 4);
|
||
+ }
|
||
+ return sec_pass;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return TRUE;
|
||
+}
|
||
#define GET_LOADSTORE_RANGE(addend) (((addend) >> 8) & 0x3f)
|
||
|
||
/* Relax LOADSTORE relocation for nds32_elf_relax_section. */
|
||
@@ -10525,21 +12080,24 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs, int *insn_len,
|
||
bfd_byte *contents, Elf_Internal_Sym *isymbuf,
|
||
- Elf_Internal_Shdr *symtab_hdr, int load_store_relax)
|
||
+ Elf_Internal_Shdr *symtab_hdr, int load_store_relax,
|
||
+ struct elf_nds32_link_hash_table *table)
|
||
{
|
||
- int eliminate_sethi = 0, range_type;
|
||
- unsigned int i;
|
||
+ int eliminate_sethi = 0, range_type, i;
|
||
bfd_vma local_sda, laddr;
|
||
int seq_len; /* Original length of instruction sequence. */
|
||
uint32_t insn;
|
||
Elf_Internal_Rela *hi_irelfn = NULL, *irelend;
|
||
bfd_vma access_addr = 0;
|
||
bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */
|
||
+ struct elf_link_hash_entry *h = NULL;
|
||
+ int indx;
|
||
enum elf_nds32_reloc_type checked_types[] =
|
||
{ R_NDS32_HI20_RELA, R_NDS32_GOT_HI20,
|
||
R_NDS32_GOTPC_HI20, R_NDS32_GOTOFF_HI20,
|
||
R_NDS32_PLTREL_HI20, R_NDS32_PLT_GOTREL_HI20,
|
||
- R_NDS32_TLS_LE_HI20
|
||
+ R_NDS32_TLS_LE_HI20, R_NDS32_TLS_IE_HI20,
|
||
+ R_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_DESC_HI20
|
||
};
|
||
|
||
irelend = internal_relocs + sec->reloc_count;
|
||
@@ -10548,7 +12106,7 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
*insn_len = seq_len;
|
||
|
||
/* Get the high part relocation. */
|
||
- for (i = 0; i < ARRAY_SIZE (checked_types); i++)
|
||
+ for (i = 0; (unsigned) i < ARRAY_SIZE (checked_types); i++)
|
||
{
|
||
hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend,
|
||
checked_types[i], laddr);
|
||
@@ -10558,9 +12116,12 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
if (hi_irelfn == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LOADSTORE",
|
||
- irel->r_offset);
|
||
- return FALSE;
|
||
+ /* Not R_NDS32_HI20_RELA. */
|
||
+ if (i != 0)
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_LOADSTORE points to unrecognized "
|
||
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
|
||
+ return FALSE;
|
||
}
|
||
|
||
range_type = GET_LOADSTORE_RANGE (irel->r_addend);
|
||
@@ -10574,39 +12135,41 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
access_addr =
|
||
calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
|
||
|
||
- if (range_type == NDS32_LOADSTORE_IMM)
|
||
+ if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info)
|
||
{
|
||
- struct elf_link_hash_entry *h = NULL;
|
||
- int indx;
|
||
-
|
||
- if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info)
|
||
- {
|
||
- indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
|
||
- h = elf_sym_hashes (abfd)[indx];
|
||
- }
|
||
+ indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
|
||
+ h = elf_sym_hashes (abfd)[indx];
|
||
+ }
|
||
|
||
+ /* Try movi. */
|
||
+ if (range_type == NDS32_LOADSTORE_IMM)
|
||
+ {
|
||
if ((access_addr < CONSERVATIVE_20BIT)
|
||
&& (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0)))
|
||
{
|
||
eliminate_sethi = 1;
|
||
break;
|
||
}
|
||
+ }
|
||
|
||
- /* This is avoid to relax symbol address which is fixed
|
||
- relocations. Ex: _stack. */
|
||
- if (h && bfd_is_abs_section (h->root.u.def.section))
|
||
- return FALSE;
|
||
+ if (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0)
|
||
+ {
|
||
+ eliminate_sethi = 1;
|
||
+ break;
|
||
}
|
||
+ else if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, hi_irelfn,
|
||
+ NULL, FALSE, table, isymbuf, symtab_hdr))
|
||
+ return FALSE;
|
||
|
||
if (!load_store_relax)
|
||
return FALSE;
|
||
|
||
/* Case for set gp register. */
|
||
if (N32_RT5 (insn) == REG_GP)
|
||
- break;
|
||
+ return FALSE;
|
||
|
||
if (range_type == NDS32_LOADSTORE_FLOAT_S
|
||
- || range_type == NDS32_LOADSTORE_FLOAT_D)
|
||
+ || range_type == NDS32_LOADSTORE_FLOAT_S)
|
||
{
|
||
range_l = sdata_range[0][0];
|
||
range_h = sdata_range[0][1];
|
||
@@ -10618,57 +12181,6 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
}
|
||
break;
|
||
|
||
- case R_NDS32_GOT_HI20:
|
||
- access_addr =
|
||
- calculate_got_memory_address (abfd, link_info, hi_irelfn, symtab_hdr);
|
||
-
|
||
- /* If this symbol is not in .got, the return value will be -1.
|
||
- Since the gp value is set to SDA_BASE but not GLOBAL_OFFSET_TABLE,
|
||
- a negative offset is allowed. */
|
||
- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
|
||
- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
|
||
- eliminate_sethi = 1;
|
||
- break;
|
||
-
|
||
- case R_NDS32_PLT_GOTREL_HI20:
|
||
- access_addr = calculate_plt_memory_address (abfd, link_info, isymbuf,
|
||
- hi_irelfn, symtab_hdr);
|
||
-
|
||
- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
|
||
- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
|
||
- eliminate_sethi = 1;
|
||
- break;
|
||
-
|
||
- case R_NDS32_GOTOFF_HI20:
|
||
- access_addr =
|
||
- calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
|
||
-
|
||
- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
|
||
- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
|
||
- eliminate_sethi = 1;
|
||
- break;
|
||
-
|
||
- case R_NDS32_GOTPC_HI20:
|
||
- /* The access_addr must consider r_addend of hi_irel. */
|
||
- access_addr = sec->output_section->vma + sec->output_offset
|
||
- + irel->r_offset + hi_irelfn->r_addend;
|
||
-
|
||
- if ((bfd_signed_vma) (local_sda - access_addr) < CONSERVATIVE_20BIT
|
||
- && (bfd_signed_vma) (local_sda - access_addr) >= -CONSERVATIVE_20BIT)
|
||
- eliminate_sethi = 1;
|
||
- break;
|
||
-
|
||
- case R_NDS32_TLS_LE_HI20:
|
||
- access_addr =
|
||
- calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
|
||
- BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL);
|
||
- access_addr -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET);
|
||
- if ((range_type == NDS32_LOADSTORE_IMM)
|
||
- && (bfd_signed_vma) (access_addr) < CONSERVATIVE_20BIT
|
||
- && (bfd_signed_vma) (access_addr) >= -CONSERVATIVE_20BIT)
|
||
- eliminate_sethi = 1;
|
||
- break;
|
||
-
|
||
default:
|
||
return FALSE;
|
||
}
|
||
@@ -10683,17 +12195,20 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
|
||
irel->r_info =
|
||
ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
|
||
*insn_len = 0;
|
||
+ return TRUE;
|
||
}
|
||
- return TRUE;
|
||
+
|
||
+ return FALSE;
|
||
}
|
||
|
||
-/* Relax LO12 relocation for nds32_elf_relax_section. */
|
||
+/* Relax LO12 relocation for nds32_elf_relax_section.*/
|
||
|
||
static void
|
||
nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs, bfd_byte *contents,
|
||
- Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr)
|
||
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr,
|
||
+ struct elf_nds32_link_hash_table *table)
|
||
{
|
||
uint32_t insn;
|
||
bfd_vma local_sda, laddr;
|
||
@@ -10723,6 +12238,7 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
h = elf_sym_hashes (abfd)[indx];
|
||
}
|
||
|
||
+ /* Try movi. */
|
||
if (N32_OP6 (insn) == N32_OP6_ORI && access_addr < CONSERVATIVE_20BIT
|
||
&& (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0)))
|
||
{
|
||
@@ -10731,13 +12247,14 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0);
|
||
bfd_putb32 (insn, contents + laddr);
|
||
}
|
||
- /* This is avoid to relax symbol address which is fixed
|
||
- relocations. Ex: _stack. */
|
||
- else if (N32_OP6 (insn) == N32_OP6_ORI
|
||
- && h && bfd_is_abs_section (h->root.u.def.section))
|
||
- return;
|
||
else
|
||
{
|
||
+ if (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0)
|
||
+ { /* Fall through. */ }
|
||
+ else if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, irel, NULL,
|
||
+ FALSE, table, isymbuf, symtab_hdr))
|
||
+ return;
|
||
+
|
||
range_l = sdata_range[1][0];
|
||
range_h = sdata_range[1][1];
|
||
switch (ELF32_R_TYPE (irel->r_info))
|
||
@@ -10768,7 +12285,8 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
/* There are range_h and range_l because linker has to promise
|
||
all sections move cross one page together. */
|
||
if ((local_sda <= access_addr && (access_addr - local_sda) < range_h)
|
||
- || (local_sda > access_addr && (local_sda - access_addr) <= range_l))
|
||
+ || (local_sda > access_addr && (local_sda - access_addr) <= range_l)
|
||
+ || (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0))
|
||
{
|
||
if (N32_OP6 (insn) == N32_OP6_ORI && N32_RT5 (insn) == REG_GP)
|
||
{
|
||
@@ -10790,7 +12308,6 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
if (irelfn != irelend && reloc != R_NDS32_SDA17S2_RELA)
|
||
irelfn->r_info =
|
||
ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_NDS32_NONE);
|
||
-
|
||
}
|
||
}
|
||
return;
|
||
@@ -10798,7 +12315,7 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax low part of PIC instruction pattern. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
bfd_byte *contents, Elf_Internal_Sym *isymbuf,
|
||
@@ -10855,7 +12372,7 @@ nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax low part of LE TLS instruction pattern. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
Elf_Internal_Rela *irel,
|
||
bfd_byte *contents, Elf_Internal_Sym *isymbuf,
|
||
@@ -10885,7 +12402,7 @@ nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax LE TLS calculate address instruction pattern. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
@@ -10893,9 +12410,9 @@ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd,
|
||
Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
|
||
{
|
||
/* Local TLS non-pic
|
||
- sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20
|
||
+ sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20
|
||
ori ta, ta, lo12(symbol@tpoff) ; TLS_LE_LO12
|
||
- add ra, ta, tp ; TLS_LE_ADD */
|
||
+ add ra, ta, tp ; TLS_LE_ADD */
|
||
|
||
uint32_t insn;
|
||
bfd_vma laddr;
|
||
@@ -10931,14 +12448,13 @@ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax LE TLS load store instruction pattern. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
bfd_byte *contents, Elf_Internal_Sym *isymbuf,
|
||
Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
|
||
{
|
||
-
|
||
uint32_t insn;
|
||
bfd_vma laddr;
|
||
bfd_signed_vma foff;
|
||
@@ -10970,7 +12486,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
|
||
success = 1;
|
||
break;
|
||
}
|
||
- /* Fall through. */
|
||
case (N32_OP6_MEM << 8) | N32_MEM_LH:
|
||
case (N32_OP6_MEM << 8) | N32_MEM_SH:
|
||
case (N32_OP6_MEM << 8) | N32_MEM_LHS:
|
||
@@ -10985,7 +12500,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
|
||
success = 1;
|
||
break;
|
||
}
|
||
- /* Fall through. */
|
||
case (N32_OP6_MEM << 8) | N32_MEM_LW:
|
||
case (N32_OP6_MEM << 8) | N32_MEM_SW:
|
||
/* The range is +/-64k. */
|
||
@@ -10999,7 +12513,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
|
||
success = 1;
|
||
break;
|
||
}
|
||
- /* Fall through. */
|
||
default:
|
||
break;
|
||
}
|
||
@@ -11032,8 +12545,9 @@ nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
if (re_irel == irelend)
|
||
{
|
||
- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_PTR",
|
||
- irel->r_offset);
|
||
+ _bfd_error_handler
|
||
+ ("%B: warning: R_NDS32_PTR points to unrecognized reloc at 0x%lx.",
|
||
+ abfd, (long) irel->r_offset);
|
||
return FALSE;
|
||
}
|
||
|
||
@@ -11068,7 +12582,7 @@ nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
|
||
|
||
/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
@@ -11123,7 +12637,7 @@ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
return;
|
||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
||
R_NDS32_PLT_GOTREL_LO19);
|
||
- /* addi.gp */
|
||
+ /* addi.gp */
|
||
insn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19));
|
||
}
|
||
else if (N32_OP6 (insn) == N32_OP6_JREG
|
||
@@ -11153,7 +12667,7 @@ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax GOT_SUFF relocation for nds32_elf_relax_section. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
@@ -11200,7 +12714,7 @@ nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
asection *sec, Elf_Internal_Rela *irel,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
@@ -11303,6 +12817,85 @@ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
|
||
|
||
}
|
||
|
||
+/* Relax LWC relocation for nds32_elf_relax_section. */
|
||
+
|
||
+static void
|
||
+nds32_elf_relax_flsi (struct bfd_link_info *link_info, bfd *abfd,
|
||
+ asection *sec, Elf_Internal_Rela *irel,
|
||
+ Elf_Internal_Rela *internal_relocs,
|
||
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
|
||
+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
|
||
+{
|
||
+ /* Pattern for bug-12566
|
||
+ sethi ra, hi20(symbol) ; HI20/LOADSTORE
|
||
+ ori ra, ra, lo12(symbol) ; LO12S0/PTR/PTR/.../INSN16
|
||
+ flsi fsa, [ra + offset1] ; LSI/PTR_RESOLVED/INSN16
|
||
+ flsi fsb, [ra + offset2] ; LSI/PTR_RESOLVED/INSN16
|
||
+ ... */
|
||
+
|
||
+ uint32_t insn;
|
||
+ bfd_vma local_sda, laddr;
|
||
+ unsigned long reloc;
|
||
+ bfd_vma access_addr, flsi_offset;
|
||
+ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */
|
||
+ Elf_Internal_Rela *irelend, *re_irel;
|
||
+ unsigned int opcode;
|
||
+
|
||
+ irelend = internal_relocs + sec->reloc_count;
|
||
+ laddr = irel->r_offset;
|
||
+ insn = bfd_getb32 (contents + laddr);
|
||
+
|
||
+ if ((insn & 0x80000000) || !is_sda_access_insn (insn))
|
||
+ return;
|
||
+
|
||
+ /* Can not do relaxation for bi format. */
|
||
+ if ((insn & 0x1000))
|
||
+ return;
|
||
+
|
||
+ /* Only deal with flsi, fssi, fldi, fsdi, so far. */
|
||
+ opcode = N32_OP6 (insn);
|
||
+ if ((opcode == N32_OP6_LWC) || (opcode == N32_OP6_SWC))
|
||
+ reloc = R_NDS32_SDA12S2_SP_RELA;
|
||
+ else if ((opcode == N32_OP6_LDC) || (opcode == N32_OP6_SDC))
|
||
+ reloc = R_NDS32_SDA12S2_DP_RELA;
|
||
+ else
|
||
+ return;
|
||
+
|
||
+ re_irel = find_relocs_at_address (irel, internal_relocs, irelend,
|
||
+ R_NDS32_PTR_RESOLVED);
|
||
+ if (re_irel == irelend)
|
||
+ {
|
||
+ _bfd_error_handler
|
||
+ ("%pB: warning: R_NDS32_LSI has no R_NDS32_PTR_RESOLVED at 0x%lx.",
|
||
+ abfd, (long) irel->r_offset);
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ /* For SDA base relative relaxation. */
|
||
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
|
||
+ &local_sda, FALSE);
|
||
+ access_addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
|
||
+ flsi_offset = (insn & 0xfff) << 2;
|
||
+ access_addr += flsi_offset;
|
||
+ range_l = sdata_range[0][0];
|
||
+ range_h = sdata_range[0][1];
|
||
+
|
||
+ if ((local_sda <= access_addr && (access_addr - local_sda) < range_h)
|
||
+ || (local_sda > access_addr && (local_sda - access_addr) <= range_l))
|
||
+ {
|
||
+ /* Turn flsi instruction into sda access format. */
|
||
+ insn = (insn & 0x7ff07000) | (REG_GP << 15);
|
||
+
|
||
+ /* Add relocation type to flsi. */
|
||
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
|
||
+ irel->r_addend += flsi_offset;
|
||
+ bfd_putb32 (insn, contents + re_irel->r_offset);
|
||
+
|
||
+ re_irel->r_addend |= 1;
|
||
+ *again = TRUE;
|
||
+ }
|
||
+}
|
||
+
|
||
static bfd_boolean
|
||
nds32_relax_adjust_label (bfd *abfd, asection *sec,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
@@ -11387,9 +12980,11 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec,
|
||
{
|
||
/* Remove all LABEL relocation from label_rel to tmp_rel
|
||
including relocations with same offset as tmp_rel. */
|
||
- for (tmp2_rel = label_rel; tmp2_rel < tmp_rel
|
||
- || tmp2_rel->r_offset == tmp_rel->r_offset; tmp2_rel++)
|
||
+ for (tmp2_rel = label_rel; tmp2_rel < tmp_rel; tmp2_rel++)
|
||
{
|
||
+ if (tmp2_rel->r_offset == tmp_rel->r_offset)
|
||
+ break;
|
||
+
|
||
if (ELF32_R_TYPE (tmp2_rel->r_info) == R_NDS32_LABEL
|
||
&& tmp2_rel->r_addend < 2)
|
||
tmp2_rel->r_info =
|
||
@@ -11416,7 +13011,8 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec,
|
||
We may convert a 16-bit instruction right before a label to
|
||
32-bit, in order to align the label if necessary
|
||
all reloc entries has been sorted by r_offset. */
|
||
- for (irel = internal_relocs; irel < irelend; irel++)
|
||
+ for (irel = internal_relocs;
|
||
+ irel < irelend && irel->r_offset < sec->size; irel++)
|
||
{
|
||
if (ELF32_R_TYPE (irel->r_info) != R_NDS32_INSN16
|
||
&& ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL)
|
||
@@ -11568,118 +13164,6 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec,
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Pick relaxation round. */
|
||
-
|
||
-static int
|
||
-nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
|
||
- struct elf_nds32_link_hash_table *table,
|
||
- struct bfd_link_info *link_info)
|
||
-{
|
||
- static asection *final_sec, *first_sec = NULL;
|
||
- static bfd_boolean normal_again = FALSE;
|
||
- static bfd_boolean set = FALSE;
|
||
- static bfd_boolean first = TRUE;
|
||
- int round_table[] = {
|
||
- NDS32_RELAX_NORMAL_ROUND,
|
||
- NDS32_RELAX_JUMP_IFC_ROUND,
|
||
- NDS32_RELAX_EX9_BUILD_ROUND,
|
||
- NDS32_RELAX_EX9_REPLACE_ROUND,
|
||
- };
|
||
- static int pass = 0;
|
||
- static int relax_round;
|
||
-
|
||
- /* The new round. */
|
||
- if (init && first_sec == sec)
|
||
- {
|
||
- set = TRUE;
|
||
- normal_again = FALSE;
|
||
- }
|
||
-
|
||
- if (first)
|
||
- {
|
||
- /* Run an empty run to get the final section. */
|
||
- relax_round = NDS32_RELAX_EMPTY_ROUND;
|
||
-
|
||
- /* It has to enter relax again because we can
|
||
- not make sure what the final turn is. */
|
||
- *again = TRUE;
|
||
-
|
||
- first = FALSE;
|
||
- first_sec = sec;
|
||
- }
|
||
-
|
||
- if (!set)
|
||
- {
|
||
- /* Not reenter yet. */
|
||
- final_sec = sec;
|
||
- return relax_round;
|
||
- }
|
||
-
|
||
- relax_round = round_table[pass];
|
||
-
|
||
- if (!init && relax_round == NDS32_RELAX_NORMAL_ROUND && *again)
|
||
- normal_again = TRUE;
|
||
-
|
||
- if (!init && final_sec == sec)
|
||
- {
|
||
- switch (relax_round)
|
||
- {
|
||
- case NDS32_RELAX_NORMAL_ROUND:
|
||
- if (!normal_again)
|
||
- {
|
||
- /* Normal relaxation done. */
|
||
- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
|
||
- {
|
||
- pass++;
|
||
- *again = TRUE;
|
||
- }
|
||
- else if (table->target_optimize & NDS32_RELAX_EX9_ON)
|
||
- {
|
||
- pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */
|
||
- *again = TRUE;
|
||
- }
|
||
- else if (table->ex9_import_file)
|
||
- {
|
||
- /* Import ex9 table. */
|
||
- if (table->update_ex9_table)
|
||
- pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */
|
||
- else
|
||
- pass += 3; /* NDS32_RELAX_EX9_REPLACE_ROUND */
|
||
- nds32_elf_ex9_import_table (link_info);
|
||
- *again = TRUE;
|
||
- }
|
||
- }
|
||
- break;
|
||
- case NDS32_RELAX_JUMP_IFC_ROUND:
|
||
- if (!nds32_elf_ifc_finish (link_info))
|
||
- _bfd_error_handler (_("error: Jump IFC Fail."));
|
||
- if (table->target_optimize & NDS32_RELAX_EX9_ON)
|
||
- {
|
||
- pass++;
|
||
- *again = TRUE;
|
||
- }
|
||
- break;
|
||
- case NDS32_RELAX_EX9_BUILD_ROUND:
|
||
- nds32_elf_ex9_finish (link_info);
|
||
- pass++;
|
||
- *again = TRUE;
|
||
- break;
|
||
- case NDS32_RELAX_EX9_REPLACE_ROUND:
|
||
- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
|
||
- {
|
||
- /* Do jump IFC optimization again. */
|
||
- if (!nds32_elf_ifc_finish (link_info))
|
||
- _bfd_error_handler (_("error: Jump IFC Fail."));
|
||
- }
|
||
- break;
|
||
- default:
|
||
- break;
|
||
- }
|
||
- }
|
||
-
|
||
- return relax_round;
|
||
-}
|
||
-
|
||
static bfd_boolean
|
||
nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
struct bfd_link_info *link_info, bfd_boolean *again)
|
||
@@ -11697,26 +13181,25 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
uint32_t insn;
|
||
uint16_t insn16;
|
||
|
||
- /* Target dependnet option. */
|
||
+ /* Target dependent option. */
|
||
struct elf_nds32_link_hash_table *table;
|
||
int load_store_relax;
|
||
- int relax_round;
|
||
|
||
relax_blank_list = NULL;
|
||
-
|
||
*again = FALSE;
|
||
|
||
/* Nothing to do for
|
||
- * relocatable link or
|
||
- * non-relocatable section or
|
||
- * non-code section or
|
||
- * empty content or
|
||
- * no reloc entry. */
|
||
+ relocatable link or
|
||
+ non-relocatable section or
|
||
+ non-code section or
|
||
+ empty content or
|
||
+ no reloc entry. */
|
||
if (bfd_link_relocatable (link_info)
|
||
|| (sec->flags & SEC_RELOC) == 0
|
||
- || (sec->flags & SEC_EXCLUDE) != 0
|
||
+ || (sec->flags & SEC_EXCLUDE) == 1
|
||
|| (sec->flags & SEC_CODE) == 0
|
||
- || sec->size == 0)
|
||
+ || sec->size == 0
|
||
+ || sec->reloc_count == 0)
|
||
return TRUE;
|
||
|
||
/* 09.12.11 Workaround. */
|
||
@@ -11725,44 +13208,14 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
if (sec->alignment_power > 2)
|
||
return TRUE;
|
||
|
||
+#ifdef NDS32_LINUX_TOOLCHAIN
|
||
+ /* Do TLS model conversion once at first. */
|
||
+ nds32_elf_unify_tls_model (abfd, sec, contents, link_info);
|
||
+#endif
|
||
+
|
||
/* The optimization type to do. */
|
||
|
||
table = nds32_elf_hash_table (link_info);
|
||
- relax_round = nds32_elf_pick_relax (TRUE, sec, again, table, link_info);
|
||
- switch (relax_round)
|
||
- {
|
||
- case NDS32_RELAX_JUMP_IFC_ROUND:
|
||
- /* Here is the entrance of ifc jump relaxation. */
|
||
- if (!nds32_elf_ifc_calc (link_info, abfd, sec))
|
||
- return FALSE;
|
||
- nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
|
||
- return TRUE;
|
||
-
|
||
- case NDS32_RELAX_EX9_BUILD_ROUND:
|
||
- /* Here is the entrance of ex9 relaxation. There are two pass of
|
||
- ex9 relaxation. The one is to traverse all instructions and build
|
||
- the hash table. The other one is to compare instructions and replace
|
||
- it by ex9.it. */
|
||
- if (!nds32_elf_ex9_build_hash_table (abfd, sec, link_info))
|
||
- return FALSE;
|
||
- nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
|
||
- return TRUE;
|
||
-
|
||
- case NDS32_RELAX_EX9_REPLACE_ROUND:
|
||
- if (!nds32_elf_ex9_replace_instruction (link_info, abfd, sec))
|
||
- return FALSE;
|
||
- return TRUE;
|
||
-
|
||
- case NDS32_RELAX_EMPTY_ROUND:
|
||
- nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
|
||
- return TRUE;
|
||
-
|
||
- case NDS32_RELAX_NORMAL_ROUND:
|
||
- default:
|
||
- if (sec->reloc_count == 0)
|
||
- return TRUE;
|
||
- break;
|
||
- }
|
||
|
||
/* The begining of general relaxation. */
|
||
|
||
@@ -11775,20 +13228,10 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
relax_range_measurement (abfd);
|
||
}
|
||
|
||
- if (is_ITB_BASE_set == 0)
|
||
- {
|
||
- /* Set the _ITB_BASE_. */
|
||
- if (!nds32_elf_ex9_itb_base (link_info))
|
||
- {
|
||
- _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"), abfd);
|
||
- bfd_set_error (bfd_error_bad_value);
|
||
- }
|
||
- }
|
||
-
|
||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||
/* Relocations MUST be kept in memory, because relaxation adjust them. */
|
||
internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
|
||
- TRUE /* keep_memory */);
|
||
+ TRUE /* keep_memory */);
|
||
if (internal_relocs == NULL)
|
||
goto error_return;
|
||
|
||
@@ -11802,10 +13245,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY)
|
||
{
|
||
if (irel->r_addend & R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG)
|
||
- {
|
||
- nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
|
||
- return TRUE;
|
||
- }
|
||
+ return TRUE;
|
||
|
||
if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG)
|
||
optimize = 1;
|
||
@@ -11888,7 +13328,8 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
|| ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA
|
||
|| ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LO12
|
||
|| ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_ADD
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS)
|
||
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS
|
||
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LSI)
|
||
seq_len = 0;
|
||
else
|
||
continue;
|
||
@@ -11967,71 +13408,41 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
removed = nds32_elf_relax_loadstore (link_info, abfd, sec, irel,
|
||
internal_relocs, &insn_len,
|
||
contents, isymbuf, symtab_hdr,
|
||
- load_store_relax);
|
||
+ load_store_relax, table);
|
||
break;
|
||
case R_NDS32_LO12S0_RELA:
|
||
case R_NDS32_LO12S1_RELA:
|
||
+ case R_NDS32_LO12S2_RELA:
|
||
case R_NDS32_LO12S2_DP_RELA:
|
||
case R_NDS32_LO12S2_SP_RELA:
|
||
- case R_NDS32_LO12S2_RELA:
|
||
/* Relax for low part. */
|
||
nds32_elf_relax_lo12 (link_info, abfd, sec, irel, internal_relocs,
|
||
- contents, isymbuf, symtab_hdr);
|
||
+ contents, isymbuf, symtab_hdr, table);
|
||
|
||
/* It is impossible to delete blank, so just continue. */
|
||
continue;
|
||
+ case R_NDS32_PTR:
|
||
+ removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs,
|
||
+ &insn_len, &seq_len, contents);
|
||
+ break;
|
||
+ case R_NDS32_LSI:
|
||
+ nds32_elf_relax_flsi (link_info, abfd, sec, irel, internal_relocs,
|
||
+ contents, isymbuf, symtab_hdr, again);
|
||
+ continue;
|
||
case R_NDS32_GOT_LO12:
|
||
case R_NDS32_GOTOFF_LO12:
|
||
case R_NDS32_PLTREL_LO12:
|
||
case R_NDS32_PLT_GOTREL_LO12:
|
||
case R_NDS32_GOTPC_LO12:
|
||
- /* Relax for PIC gp-relative low part. */
|
||
- nds32_elf_relax_piclo12 (link_info, abfd, sec, irel, contents,
|
||
- isymbuf, symtab_hdr);
|
||
-
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
- continue;
|
||
case R_NDS32_TLS_LE_LO12:
|
||
- /* Relax for LE TLS low part. */
|
||
- nds32_elf_relax_letlslo12 (link_info, abfd, irel, contents,
|
||
- isymbuf, symtab_hdr);
|
||
-
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
- continue;
|
||
case R_NDS32_TLS_LE_ADD:
|
||
- nds32_elf_relax_letlsadd (link_info, abfd, sec, irel, internal_relocs,
|
||
- contents, isymbuf, symtab_hdr, again);
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
- continue;
|
||
case R_NDS32_TLS_LE_LS:
|
||
- nds32_elf_relax_letlsls (link_info, abfd, sec, irel, internal_relocs,
|
||
- contents, isymbuf, symtab_hdr, again);
|
||
- continue;
|
||
- case R_NDS32_PTR:
|
||
- removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs,
|
||
- &insn_len, &seq_len, contents);
|
||
- break;
|
||
case R_NDS32_PLT_GOT_SUFF:
|
||
- nds32_elf_relax_pltgot_suff (link_info, abfd, sec, irel,
|
||
- internal_relocs, contents,
|
||
- isymbuf, symtab_hdr, again);
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
- continue;
|
||
case R_NDS32_GOT_SUFF:
|
||
- nds32_elf_relax_got_suff (link_info, abfd, sec, irel,
|
||
- internal_relocs, contents,
|
||
- symtab_hdr, again);
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
- continue;
|
||
case R_NDS32_GOTOFF_SUFF:
|
||
- nds32_elf_relax_gotoff_suff (link_info, abfd, sec, irel,
|
||
- internal_relocs, contents,
|
||
- isymbuf, symtab_hdr, again);
|
||
- /* It is impossible to delete blank, so just continue. */
|
||
continue;
|
||
default:
|
||
continue;
|
||
-
|
||
}
|
||
if (removed && seq_len - insn_len > 0)
|
||
{
|
||
@@ -12051,7 +13462,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
irelend, isymbuf))
|
||
goto error_return;
|
||
|
||
- if (!*again)
|
||
+ if (*again == FALSE)
|
||
{
|
||
if (!nds32_fag_remove_unused_fpbase (abfd, sec, internal_relocs,
|
||
irelend))
|
||
@@ -12059,9 +13470,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
}
|
||
}
|
||
|
||
- nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
|
||
-
|
||
- if (!*again)
|
||
+ if (*again == FALSE)
|
||
{
|
||
if (!nds32_relax_adjust_label (abfd, sec, internal_relocs, contents,
|
||
&relax_blank_list, optimize, opt_size))
|
||
@@ -12078,15 +13487,15 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
|
||
relax_blank_list = NULL;
|
||
}
|
||
|
||
- if (!*again)
|
||
+ if (*again == FALSE)
|
||
{
|
||
/* Closing the section, so we don't relax it anymore. */
|
||
bfd_vma sec_size_align;
|
||
Elf_Internal_Rela *tmp_rel;
|
||
|
||
/* Pad to alignment boundary. Only handle current section alignment. */
|
||
- sec_size_align = (sec->size + (~((-1U) << sec->alignment_power)))
|
||
- & ((-1U) << sec->alignment_power);
|
||
+ sec_size_align = (sec->size + (~((bfd_vma)(-1) << sec->alignment_power)))
|
||
+ & ((bfd_vma)(-1) << sec->alignment_power);
|
||
if ((sec_size_align - sec->size) & 0x2)
|
||
{
|
||
insn16 = NDS32_NOP16;
|
||
@@ -12128,8 +13537,7 @@ error_return:
|
||
goto finish;
|
||
}
|
||
|
||
-static struct bfd_elf_special_section const nds32_elf_special_sections[] =
|
||
-{
|
||
+static struct bfd_elf_special_section const nds32_elf_special_sections[] = {
|
||
{".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE},
|
||
{".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE},
|
||
{NULL, 0, 0, 0, 0}
|
||
@@ -12182,14 +13590,14 @@ bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info,
|
||
int eliminate_gc_relocs,
|
||
FILE * sym_ld_script, int load_store_relax,
|
||
int target_optimize, int relax_status,
|
||
- int relax_round, FILE * ex9_export_file,
|
||
- FILE * ex9_import_file,
|
||
- int update_ex9_table, int ex9_limit,
|
||
- bfd_boolean ex9_loop_aware,
|
||
- bfd_boolean ifc_loop_aware)
|
||
+ int relax_round, int hyper_relax,
|
||
+ int tls_desc_trampoline, char *abi)
|
||
{
|
||
struct elf_nds32_link_hash_table *table;
|
||
|
||
+ /* Initialize indirect call hash table. */
|
||
+ nds32_elf_ict_hash_init ();
|
||
+
|
||
table = nds32_elf_hash_table (link_info);
|
||
if (table == NULL)
|
||
return;
|
||
@@ -12201,12 +13609,81 @@ bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info,
|
||
table->target_optimize = target_optimize;
|
||
table->relax_status = relax_status;
|
||
table->relax_round = relax_round;
|
||
- table->ex9_export_file = ex9_export_file;
|
||
- table->ex9_import_file = ex9_import_file;
|
||
- table->update_ex9_table = update_ex9_table;
|
||
- table->ex9_limit = ex9_limit;
|
||
- table->ex9_loop_aware = ex9_loop_aware;
|
||
- table->ifc_loop_aware = ifc_loop_aware;
|
||
+ table->hyper_relax = hyper_relax;
|
||
+ table->tls_desc_trampoline = tls_desc_trampoline;
|
||
+ output_abi = abi;
|
||
+}
|
||
+
|
||
+void
|
||
+bfd_elf32_nds32_append_section (struct bfd_link_info *link_info, bfd *abfd)
|
||
+{
|
||
+ asection *itable;
|
||
+ struct bfd_link_hash_entry *h;
|
||
+ unsigned int i, count = 0;
|
||
+
|
||
+ /* Count number of indirect call function. */
|
||
+ indirect_call_table.frozen = 1;
|
||
+ for (i = 0; i < indirect_call_table.size; i++)
|
||
+ {
|
||
+ struct bfd_hash_entry *p;
|
||
+ struct elf_nds32_ict_hash_entry *entry;
|
||
+
|
||
+ for (p = indirect_call_table.table[i]; p != NULL; p = p->next)
|
||
+ {
|
||
+ entry = (struct elf_nds32_ict_hash_entry *) p;
|
||
+ entry->order = count;
|
||
+ count++;
|
||
+ }
|
||
+ }
|
||
+ indirect_call_table.frozen = 0;
|
||
+
|
||
+ if (count)
|
||
+ {
|
||
+ h = bfd_link_hash_lookup (link_info->hash, "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ if (h && (h->type == bfd_link_hash_defined
|
||
+ || h->type == bfd_link_hash_defweak
|
||
+ || h->type == bfd_link_hash_common))
|
||
+ {
|
||
+ _bfd_error_handler (_("Warning: _INDIRECT_CALL_TABLE_BASE_ has already"
|
||
+ "be defined. All ICT suffix is ignored."));
|
||
+ ignore_indirect_call = TRUE;
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ itable = bfd_make_section_with_flags (abfd, NDS32_ICT_SECTION,
|
||
+ SEC_DATA | SEC_ALLOC | SEC_LOAD
|
||
+ | SEC_HAS_CONTENTS | SEC_READONLY
|
||
+ | SEC_IN_MEMORY | SEC_KEEP
|
||
+ | SEC_RELOC);
|
||
+ else
|
||
+ itable = bfd_make_section_with_flags (abfd, NDS32_ICT_SECTION,
|
||
+ SEC_CODE | SEC_ALLOC | SEC_LOAD
|
||
+ | SEC_HAS_CONTENTS | SEC_READONLY
|
||
+ | SEC_IN_MEMORY | SEC_KEEP
|
||
+ | SEC_RELOC);
|
||
+ if (itable)
|
||
+ {
|
||
+ itable->gc_mark = 1;
|
||
+ itable->alignment_power = 2;
|
||
+ itable->size = count * 4;
|
||
+ itable->contents = bfd_zalloc (abfd, itable->size);
|
||
+
|
||
+ /* Add a symbol in the head of .nds32.ict to objdump clearly. */
|
||
+ h = bfd_link_hash_lookup (link_info->hash,
|
||
+ "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ _bfd_generic_link_add_one_symbol
|
||
+ (link_info, link_info->output_bfd, "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE,
|
||
+ get_elf_backend_data (link_info->output_bfd)->collect, &h);
|
||
+ }
|
||
+
|
||
+ ict_file = fopen ("nds32_ict.s", FOPEN_WT);
|
||
+ if(ict_file == NULL)
|
||
+ _bfd_error_handler (_("Warning: Fail to build nds32_ict.s."));
|
||
+ }
|
||
}
|
||
|
||
/* These functions and data-structures are used for fp-as-gp
|
||
@@ -12394,7 +13871,7 @@ nds32_fag_find_base (struct nds32_fag *head, struct nds32_fag **bestpp)
|
||
|
||
static bfd_boolean
|
||
nds32_fag_mark_relax (struct bfd_link_info *link_info,
|
||
- bfd *abfd, struct nds32_fag *best_fag,
|
||
+ asection *sec, struct nds32_fag *best_fag,
|
||
Elf_Internal_Rela *internal_relocs,
|
||
Elf_Internal_Rela *irelend)
|
||
{
|
||
@@ -12402,7 +13879,7 @@ nds32_fag_mark_relax (struct bfd_link_info *link_info,
|
||
bfd_vma best_fpbase, gp;
|
||
bfd *output_bfd;
|
||
|
||
- output_bfd = abfd->sections->output_section->owner;
|
||
+ output_bfd = sec->output_section->owner;
|
||
nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
|
||
best_fpbase = best_fag->addr;
|
||
|
||
@@ -12525,7 +14002,6 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
|
||
{
|
||
/* Begin of the region. */
|
||
if (begin_rel)
|
||
- /* xgettext:c-format */
|
||
_bfd_error_handler (_("%B: Nested OMIT_FP in %A."), abfd, sec);
|
||
|
||
begin_rel = irel;
|
||
@@ -12544,7 +14020,6 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
|
||
|
||
if (begin_rel == NULL)
|
||
{
|
||
- /* xgettext:c-format */
|
||
_bfd_error_handler (_("%B: Unmatched OMIT_FP in %A."), abfd, sec);
|
||
continue;
|
||
}
|
||
@@ -12557,7 +14032,7 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
|
||
|
||
/* Check if it is worth, and FP_BASE is near enough to SDA_BASE. */
|
||
if (accu < FAG_THRESHOLD
|
||
- || !nds32_fag_mark_relax (link_info, abfd, best_fag,
|
||
+ || !nds32_fag_mark_relax (link_info, sec, best_fag,
|
||
internal_relocs, irelend))
|
||
{
|
||
/* Not worth to do fp-as-gp. */
|
||
@@ -12811,9 +14286,9 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
|
||
case bfd_reloc_dangerous:
|
||
BFD_ASSERT (error_message != NULL);
|
||
(*link_info->callbacks->reloc_dangerous)
|
||
- (link_info, error_message,
|
||
- input_bfd, input_section, (*parent)->address);
|
||
- break;
|
||
+ (link_info, error_message, input_bfd, input_section,
|
||
+ (*parent)->address);
|
||
+ break;
|
||
case bfd_reloc_overflow:
|
||
(*link_info->callbacks->reloc_overflow)
|
||
(link_info, NULL,
|
||
@@ -12827,9 +14302,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
|
||
complete binaries. Do not abort, but issue an error
|
||
message instead. */
|
||
link_info->callbacks->einfo
|
||
- /* xgettext:c-format */
|
||
(_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"),
|
||
- abfd, input_section, * parent);
|
||
+ abfd, input_section, *parent);
|
||
goto error_return;
|
||
|
||
default:
|
||
@@ -12847,745 +14321,807 @@ error_return:
|
||
free (reloc_vector);
|
||
return NULL;
|
||
}
|
||
-
|
||
-/* Link-time IFC relaxation.
|
||
- In this optimization, we chains jump instructions
|
||
- of the same destination with ifcall. */
|
||
|
||
+/* Check target symbol. */
|
||
|
||
-/* List to save jal and j relocation. */
|
||
-struct elf_nds32_ifc_symbol_entry
|
||
+static bfd_boolean
|
||
+nds32_elf_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
|
||
{
|
||
- asection *sec;
|
||
- struct elf_link_hash_entry *h;
|
||
- struct elf_nds32_ifc_irel_list *irel_head;
|
||
- unsigned long insn;
|
||
- int times;
|
||
- int enable; /* Apply ifc. */
|
||
- int ex9_enable; /* Apply ifc after ex9. */
|
||
- struct elf_nds32_ifc_symbol_entry *next;
|
||
-};
|
||
+ if (!sym || !sym->name || sym->name[0] != '$')
|
||
+ return FALSE;
|
||
+ return TRUE;
|
||
+}
|
||
|
||
-struct elf_nds32_ifc_irel_list
|
||
+/* nds32 find maybe function sym. Ignore target special symbol
|
||
+ first, and then go the general function. */
|
||
+
|
||
+static bfd_size_type
|
||
+nds32_elf_maybe_function_sym (const asymbol *sym, asection *sec,
|
||
+ bfd_vma *code_off)
|
||
{
|
||
- Elf_Internal_Rela *irel;
|
||
- asection *sec;
|
||
- bfd_vma addr;
|
||
- /* If this is set, then it is the last instruction for
|
||
- ifc-chain, so it must be keep for the actual branching. */
|
||
- int keep;
|
||
- struct elf_nds32_ifc_irel_list *next;
|
||
-};
|
||
+ if (nds32_elf_is_target_special_symbol (NULL, (asymbol *) sym))
|
||
+ return 0;
|
||
|
||
-static struct elf_nds32_ifc_symbol_entry *ifc_symbol_head = NULL;
|
||
+ return _bfd_elf_maybe_function_sym (sym, sec, code_off);
|
||
+}
|
||
|
||
-/* Insert symbol of jal and j for ifc. */
|
||
+
|
||
+/* Do TLS model conversion. */
|
||
|
||
-static void
|
||
-nds32_elf_ifc_insert_symbol (asection *sec,
|
||
- struct elf_link_hash_entry *h,
|
||
- Elf_Internal_Rela *irel,
|
||
- unsigned long insn)
|
||
+typedef struct relax_group_list_t
|
||
{
|
||
- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
|
||
+ Elf_Internal_Rela *relo;
|
||
+ struct relax_group_list_t *next;
|
||
+ struct relax_group_list_t *next_sibling;
|
||
+ int id;
|
||
+} relax_group_list_t;
|
||
|
||
- /* Check there is target of existing entry the same as the new one. */
|
||
- while (ptr != NULL)
|
||
- {
|
||
- if (((h == NULL && ptr->sec == sec
|
||
- && ELF32_R_SYM (ptr->irel_head->irel->r_info) == ELF32_R_SYM (irel->r_info)
|
||
- && ptr->irel_head->irel->r_addend == irel->r_addend)
|
||
- || h != NULL)
|
||
- && ptr->h == h
|
||
- && ptr->insn == insn)
|
||
- {
|
||
- /* The same target exist, so insert into list. */
|
||
- struct elf_nds32_ifc_irel_list *irel_list = ptr->irel_head;
|
||
+int
|
||
+list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem);
|
||
|
||
- while (irel_list->next != NULL)
|
||
- irel_list = irel_list->next;
|
||
- irel_list->next = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list));
|
||
- irel_list = irel_list->next;
|
||
- irel_list->irel = irel;
|
||
- irel_list->keep = 1;
|
||
+int
|
||
+list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem);
|
||
|
||
- if (h == NULL)
|
||
- irel_list->sec = NULL;
|
||
- else
|
||
- irel_list->sec = sec;
|
||
- irel_list->next = NULL;
|
||
- return;
|
||
- }
|
||
- if (ptr->next == NULL)
|
||
- break;
|
||
- ptr = ptr->next;
|
||
- }
|
||
+void
|
||
+dump_chain (relax_group_list_t *pHead);
|
||
|
||
- /* There is no same target entry, so build a new one. */
|
||
- if (ifc_symbol_head == NULL)
|
||
- {
|
||
- ifc_symbol_head = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry));
|
||
- ptr = ifc_symbol_head;
|
||
- }
|
||
- else
|
||
+int
|
||
+list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem)
|
||
+{
|
||
+ relax_group_list_t *pNext = pHead;
|
||
+
|
||
+ /* find place */
|
||
+ while (pNext->next)
|
||
{
|
||
- ptr->next = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry));
|
||
- ptr = ptr->next;
|
||
+ if (pNext->next->id > (int) pElem->r_addend)
|
||
+ break;
|
||
+
|
||
+ pNext = pNext->next;
|
||
}
|
||
|
||
- ptr->h = h;
|
||
- ptr->irel_head = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list));
|
||
- ptr->irel_head->irel = irel;
|
||
- ptr->insn = insn;
|
||
- ptr->irel_head->keep = 1;
|
||
+ /* insert node */
|
||
+ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t));
|
||
+ if (!pNew)
|
||
+ return FALSE;
|
||
+
|
||
+ relax_group_list_t *tmp = pNext->next;
|
||
+ pNext->next = pNew;
|
||
|
||
- if (h == NULL)
|
||
- {
|
||
- /* Local symbols. */
|
||
- ptr->sec = sec;
|
||
- ptr->irel_head->sec = NULL;
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Global symbol. */
|
||
- ptr->sec = NULL;
|
||
- ptr->irel_head->sec = sec;
|
||
- }
|
||
+ pNew->id = pElem->r_addend;
|
||
+ pNew->relo = pElem;
|
||
+ pNew->next = tmp;
|
||
+ pNew->next_sibling = NULL;
|
||
|
||
- ptr->irel_head->next = NULL;
|
||
- ptr->times = 0;
|
||
- ptr->enable = 0;
|
||
- ptr->ex9_enable = 0;
|
||
- ptr->next = NULL;
|
||
+ return TRUE;
|
||
}
|
||
|
||
-/* Gather all jal and j instructions. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ifc_calc (struct bfd_link_info *info,
|
||
- bfd *abfd, asection *sec)
|
||
+int
|
||
+list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem)
|
||
{
|
||
- Elf_Internal_Rela *internal_relocs;
|
||
- Elf_Internal_Rela *irelend;
|
||
- Elf_Internal_Rela *irel;
|
||
- Elf_Internal_Shdr *symtab_hdr;
|
||
- bfd_byte *contents = NULL;
|
||
- uint32_t insn, insn_with_reg;
|
||
- unsigned long r_symndx;
|
||
- struct elf_link_hash_entry *h;
|
||
- struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- bfd_boolean ifc_loop_aware;
|
||
+ relax_group_list_t *pNext = pNode;
|
||
|
||
- internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
|
||
- TRUE /* keep_memory */);
|
||
- irelend = internal_relocs + sec->reloc_count;
|
||
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||
+ /* find place */
|
||
+ while (pNext->next_sibling)
|
||
+ {
|
||
+ pNext = pNext->next_sibling;
|
||
+ }
|
||
+
|
||
+ /* insert node */
|
||
+ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t));
|
||
+ if (!pNew)
|
||
+ return FALSE;
|
||
|
||
- /* Check if the object enable ifc. */
|
||
- irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend,
|
||
- R_NDS32_RELAX_ENTRY);
|
||
+ relax_group_list_t *tmp = pNext->next_sibling;
|
||
+ pNext->next_sibling = pNew;
|
||
|
||
- if (irel == NULL
|
||
- || irel >= irelend
|
||
- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
|
||
- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
|
||
- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG)))
|
||
- return TRUE;
|
||
+ pNew->id = -1;
|
||
+ pNew->relo = pElem;
|
||
+ pNew->next = NULL;
|
||
+ pNew->next_sibling = tmp;
|
||
|
||
- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE))
|
||
- return FALSE;
|
||
+ return TRUE;
|
||
+}
|
||
|
||
- table = nds32_elf_hash_table (info);
|
||
- ifc_loop_aware = table->ifc_loop_aware;
|
||
- while (irel != NULL && irel < irelend)
|
||
+void
|
||
+dump_chain (relax_group_list_t *pHead)
|
||
+{
|
||
+ relax_group_list_t *pNext = pHead->next;
|
||
+ while (pNext)
|
||
{
|
||
- /* Traverse all relocation and gather all of them to build the list. */
|
||
-
|
||
- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN)
|
||
+ printf("group %d @ 0x%08x", pNext->id, (unsigned)pNext->relo->r_offset);
|
||
+ relax_group_list_t *pNextSib = pNext->next_sibling;
|
||
+ while (pNextSib)
|
||
{
|
||
- if (ifc_loop_aware == 1
|
||
- && (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0)
|
||
- {
|
||
- /* Check the region if loop or not. If it is true and
|
||
- ifc-loop-aware is true, ignore the region till region end. */
|
||
- while (irel != NULL
|
||
- && irel < irelend
|
||
- && (ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_END
|
||
- || (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0))
|
||
- irel++;
|
||
- }
|
||
+ printf(", %d", (unsigned) ELF32_R_TYPE (pNextSib->relo->r_info));
|
||
+ pNextSib = pNextSib->next_sibling;
|
||
}
|
||
+ pNext = pNext->next;
|
||
+ printf("\n");
|
||
+ }
|
||
+}
|
||
+
|
||
+/* check R_NDS32_RELAX_GROUP of each section.
|
||
+ there might be multiple sections in one object file. */
|
||
+int
|
||
+elf32_nds32_check_relax_group (bfd *abfd, asection *asec)
|
||
+{
|
||
+ elf32_nds32_relax_group_t *relax_group_ptr =
|
||
+ elf32_nds32_relax_group_ptr (abfd);
|
||
+
|
||
+ int min_id = relax_group_ptr->min_id;
|
||
+ int max_id = relax_group_ptr->max_id;
|
||
+
|
||
+ Elf_Internal_Rela *rel;
|
||
+ Elf_Internal_Rela *relend;
|
||
+ Elf_Internal_Rela *relocs;
|
||
+ enum elf_nds32_reloc_type rtype;
|
||
+
|
||
+ do
|
||
+ {
|
||
+ /* Relocations MUST be kept in memory, because relaxation adjust them. */
|
||
+ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL,
|
||
+ TRUE /* keep_memory */);
|
||
+ if (relocs == NULL)
|
||
+ break;
|
||
|
||
- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA)
|
||
+ /* check R_NDS32_RELAX_GROUP */
|
||
+ relend = relocs + asec->reloc_count;
|
||
+ for (rel = relocs; rel < relend; rel++)
|
||
{
|
||
- insn = bfd_getb32 (contents + irel->r_offset);
|
||
- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
|
||
- r_symndx = ELF32_R_SYM (irel->r_info);
|
||
- if (r_symndx < symtab_hdr->sh_info)
|
||
- {
|
||
- /* Local symbol. */
|
||
- nds32_elf_ifc_insert_symbol (sec, NULL, irel, insn_with_reg);
|
||
- }
|
||
- else
|
||
- {
|
||
- /* External symbol. */
|
||
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||
- nds32_elf_ifc_insert_symbol (sec, h, irel, insn_with_reg);
|
||
- }
|
||
+ int id;
|
||
+ rtype = ELF32_R_TYPE (rel->r_info);
|
||
+ if (rtype != R_NDS32_RELAX_GROUP)
|
||
+ continue;
|
||
+
|
||
+ id = rel->r_addend;
|
||
+ if (id < min_id)
|
||
+ min_id = id;
|
||
+ else if (id > max_id)
|
||
+ max_id = id;
|
||
}
|
||
- irel++;
|
||
}
|
||
- return TRUE;
|
||
+ while (FALSE);
|
||
+
|
||
+ if ((relocs != NULL) && (elf_section_data (asec)->relocs != relocs))
|
||
+ free (relocs);
|
||
+
|
||
+ if ((min_id != relax_group_ptr->min_id)
|
||
+ || (max_id != relax_group_ptr->max_id))
|
||
+ {
|
||
+ relax_group_ptr->count = max_id - min_id + 1;
|
||
+ BFD_ASSERT(min_id <= relax_group_ptr->min_id);
|
||
+ relax_group_ptr->min_id = min_id;
|
||
+ BFD_ASSERT(max_id >= relax_group_ptr->max_id);
|
||
+ relax_group_ptr->max_id = max_id;
|
||
+ }
|
||
+
|
||
+ return relax_group_ptr->count;
|
||
}
|
||
|
||
-/* Determine whether j and jal should be substituted. */
|
||
+/* Reorder RELAX_GROUP ID when command line option '-r' is applied. */
|
||
+/* TODO: find a way to free me. */
|
||
+struct section_id_list_t *relax_group_section_id_list = NULL;
|
||
|
||
-static void
|
||
-nds32_elf_ifc_filter (struct bfd_link_info *info)
|
||
+struct section_id_list_t *
|
||
+elf32_nds32_lookup_section_id (int id, struct section_id_list_t **lst_ptr)
|
||
{
|
||
- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
|
||
- struct elf_nds32_ifc_irel_list *irel_keeper = NULL;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- int target_optimize;
|
||
- bfd_vma address;
|
||
+ struct section_id_list_t *result = NULL;
|
||
+ struct section_id_list_t *lst = *lst_ptr;
|
||
|
||
- table = nds32_elf_hash_table (info);
|
||
- target_optimize = table->target_optimize;
|
||
- while (ptr)
|
||
+ if (NULL == lst)
|
||
+ {
|
||
+ result = (struct section_id_list_t *) calloc (
|
||
+ 1, sizeof (struct section_id_list_t));
|
||
+ BFD_ASSERT (result); /* feed me */
|
||
+ result->id = id;
|
||
+ *lst_ptr = result;
|
||
+ }
|
||
+ else
|
||
{
|
||
- irel_ptr = ptr->irel_head;
|
||
- if (ptr->h == NULL)
|
||
+ struct section_id_list_t *cur = lst;
|
||
+ struct section_id_list_t *prv = NULL;
|
||
+ struct section_id_list_t *sec = NULL;
|
||
+ while (cur)
|
||
{
|
||
- /* Local symbol. */
|
||
- irel_keeper = irel_ptr;
|
||
- while (irel_ptr && irel_ptr->next)
|
||
+ if (cur->id < id)
|
||
{
|
||
- /* Check there is jump target can be used. */
|
||
- if ((irel_ptr->next->irel->r_offset
|
||
- - irel_keeper->irel->r_offset) > 1022)
|
||
- irel_keeper = irel_ptr->next;
|
||
- else
|
||
- {
|
||
- ptr->enable = 1;
|
||
- irel_ptr->keep = 0;
|
||
- }
|
||
- irel_ptr = irel_ptr->next;
|
||
+ prv = cur;
|
||
+ cur = cur->next;
|
||
+ continue;
|
||
}
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Global symbol. */
|
||
- /* We have to get the absolute address and decide
|
||
- whether to keep it or not. */
|
||
- while (irel_ptr)
|
||
+
|
||
+ if (cur->id > id)
|
||
{
|
||
- address = (irel_ptr->irel->r_offset
|
||
- + irel_ptr->sec->output_section->vma
|
||
- + irel_ptr->sec->output_offset);
|
||
- irel_ptr->addr = address;
|
||
- irel_ptr = irel_ptr->next;
|
||
+ cur = NULL; /* to insert after prv */
|
||
+ sec = cur; /* in case prv == NULL */
|
||
}
|
||
|
||
- irel_ptr = ptr->irel_head;
|
||
- while (irel_ptr)
|
||
- {
|
||
- /* Sort by address. */
|
||
- struct elf_nds32_ifc_irel_list *irel_dest = irel_ptr;
|
||
- struct elf_nds32_ifc_irel_list *irel_temp = irel_ptr;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr_prev = NULL;
|
||
- struct elf_nds32_ifc_irel_list *irel_dest_prev = NULL;
|
||
-
|
||
- /* Get the smallest one. */
|
||
- while (irel_temp->next)
|
||
- {
|
||
- if (irel_temp->next->addr < irel_dest->addr)
|
||
- {
|
||
- irel_dest_prev = irel_temp;
|
||
- irel_dest = irel_temp->next;
|
||
- }
|
||
- irel_temp = irel_temp->next;
|
||
- }
|
||
+ break;
|
||
+ }
|
||
|
||
- if (irel_dest != irel_ptr)
|
||
- {
|
||
- if (irel_ptr_prev)
|
||
- irel_ptr_prev->next = irel_dest;
|
||
- if (irel_dest_prev)
|
||
- irel_dest_prev->next = irel_ptr;
|
||
- irel_temp = irel_ptr->next;
|
||
- irel_ptr->next = irel_dest->next;
|
||
- irel_dest->next = irel_temp;
|
||
- }
|
||
- irel_ptr_prev = irel_ptr;
|
||
- irel_ptr = irel_ptr->next;
|
||
+ if (NULL == cur)
|
||
+ {
|
||
+ /* insert after prv */
|
||
+ result = (struct section_id_list_t *) calloc (
|
||
+ 1, sizeof (struct section_id_list_t));
|
||
+ BFD_ASSERT (result); /* feed me */
|
||
+ result->id = id;
|
||
+ if (NULL != prv)
|
||
+ {
|
||
+ result->next = prv->next;
|
||
+ prv->next = result;
|
||
}
|
||
-
|
||
- irel_ptr = ptr->irel_head;
|
||
- irel_keeper = irel_ptr;
|
||
- while (irel_ptr && irel_ptr->next)
|
||
+ else
|
||
{
|
||
- if ((irel_ptr->next->addr - irel_keeper->addr) > 1022)
|
||
- irel_keeper = irel_ptr->next;
|
||
- else
|
||
- {
|
||
- ptr->enable = 1;
|
||
- irel_ptr->keep = 0;
|
||
- }
|
||
- irel_ptr = irel_ptr->next;
|
||
+ *lst_ptr = result;
|
||
+ result->next = sec;
|
||
}
|
||
}
|
||
-
|
||
- /* Ex9 enable. Reserve it for ex9. */
|
||
- if ((target_optimize & NDS32_RELAX_EX9_ON)
|
||
- && ptr->irel_head != irel_keeper)
|
||
- ptr->enable = 0;
|
||
- ptr = ptr->next;
|
||
}
|
||
-}
|
||
|
||
-/* Determine whether j and jal should be substituted after ex9 done. */
|
||
+ return result;
|
||
+}
|
||
|
||
-static void
|
||
-nds32_elf_ifc_filter_after_ex9 (void)
|
||
+int
|
||
+elf32_nds32_unify_relax_group (bfd *abfd, asection *asec)
|
||
{
|
||
- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
|
||
+ static int next_relax_group_bias = 0;
|
||
|
||
- while (ptr)
|
||
+ elf32_nds32_relax_group_t *relax_group_ptr =
|
||
+ elf32_nds32_relax_group_ptr (abfd);
|
||
+
|
||
+ bfd_boolean result = TRUE;
|
||
+ Elf_Internal_Rela *rel;
|
||
+ Elf_Internal_Rela *relend;
|
||
+ Elf_Internal_Rela *relocs = NULL;
|
||
+ enum elf_nds32_reloc_type rtype;
|
||
+ struct section_id_list_t *node = NULL;
|
||
+ int count = 0;
|
||
+
|
||
+ do
|
||
{
|
||
- if (ptr->enable == 0)
|
||
+ if (0 == relax_group_ptr->count)
|
||
+ break;
|
||
+
|
||
+ /* check if this section has handled */
|
||
+ node = elf32_nds32_lookup_section_id (asec->id, &relax_group_section_id_list);
|
||
+ if (NULL == node)
|
||
+ break; /* hit, the section id has handled. */
|
||
+
|
||
+ /* Relocations MUST be kept in memory, because relaxation adjust them. */
|
||
+ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL,
|
||
+ TRUE /* keep_memory */);
|
||
+ if (relocs == NULL)
|
||
{
|
||
- /* Check whether ifc is applied or not. */
|
||
- irel_ptr = ptr->irel_head;
|
||
- ptr->ex9_enable = 1;
|
||
- while (irel_ptr)
|
||
- {
|
||
- if (ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_TRAN)
|
||
- {
|
||
- /* Ex9 already. */
|
||
- ptr->ex9_enable = 0;
|
||
- break;
|
||
- }
|
||
- irel_ptr = irel_ptr->next;
|
||
- }
|
||
+ BFD_ASSERT (0); /* feed me */
|
||
+ break;
|
||
}
|
||
- ptr = ptr->next;
|
||
- }
|
||
-}
|
||
-
|
||
-/* Wrapper to do ifc relaxation. */
|
||
|
||
-bfd_boolean
|
||
-nds32_elf_ifc_finish (struct bfd_link_info *info)
|
||
-{
|
||
- int relax_status;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
+ /* allocate group id bias for this bfd! */
|
||
+ if (0 == relax_group_ptr->init)
|
||
+ {
|
||
+ relax_group_ptr->bias = next_relax_group_bias;
|
||
+ next_relax_group_bias += relax_group_ptr->count;
|
||
+ relax_group_ptr->init = 1;
|
||
+ }
|
||
|
||
- table = nds32_elf_hash_table (info);
|
||
- relax_status = table->relax_status;
|
||
+ /* reorder relax group groups */
|
||
+ relend = relocs + asec->reloc_count;
|
||
+ for (rel = relocs; rel < relend; rel++)
|
||
+ {
|
||
+ rtype = ELF32_R_TYPE(rel->r_info);
|
||
+ if (rtype != R_NDS32_RELAX_GROUP)
|
||
+ continue;
|
||
|
||
- if (!(relax_status & NDS32_RELAX_JUMP_IFC_DONE))
|
||
- nds32_elf_ifc_filter (info);
|
||
- else
|
||
- nds32_elf_ifc_filter_after_ex9 ();
|
||
+ /* change it */
|
||
+ rel->r_addend += relax_group_ptr->bias;
|
||
+ /* debugging count */
|
||
+ count++;
|
||
+ }
|
||
+ }
|
||
+ while (FALSE);
|
||
|
||
- if (!nds32_elf_ifc_replace (info))
|
||
- return FALSE;
|
||
+ if (relocs != NULL && elf_section_data (asec)->relocs != relocs)
|
||
+ free (relocs);
|
||
|
||
- if (table)
|
||
- table->relax_status |= NDS32_RELAX_JUMP_IFC_DONE;
|
||
- return TRUE;
|
||
+ return result;
|
||
}
|
||
|
||
-/* Traverse the result of ifc filter and replace it with ifcall9. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ifc_replace (struct bfd_link_info *info)
|
||
+int
|
||
+nds32_elf_unify_tls_model (bfd *inbfd, asection *insec, bfd_byte *incontents,
|
||
+ struct bfd_link_info *lnkinfo)
|
||
{
|
||
- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
|
||
- nds32_elf_blank_t *relax_blank_list = NULL;
|
||
- bfd_byte *contents = NULL;
|
||
- Elf_Internal_Rela *internal_relocs;
|
||
+ bfd_boolean result = TRUE;
|
||
Elf_Internal_Rela *irel;
|
||
Elf_Internal_Rela *irelend;
|
||
- unsigned short insn16 = INSN_IFCALL9;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- int relax_status;
|
||
+ Elf_Internal_Rela *internal_relocs;
|
||
+ unsigned long r_symndx;
|
||
+ enum elf_nds32_reloc_type r_type;
|
||
|
||
- table = nds32_elf_hash_table (info);
|
||
- relax_status = table->relax_status;
|
||
+ Elf_Internal_Sym *local_syms = NULL;
|
||
+ bfd_byte *contents = NULL;
|
||
+
|
||
+ relax_group_list_t chain = { .id = -1, .next = NULL, .next_sibling = NULL };
|
||
+
|
||
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (inbfd)->symtab_hdr;
|
||
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
||
+ sym_hashes = elf_sym_hashes (inbfd);
|
||
+ sym_hashes_end =
|
||
+ sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
|
||
+ if (!elf_bad_symtab (inbfd))
|
||
+ sym_hashes_end -= symtab_hdr->sh_info;
|
||
+
|
||
+ /* reorder RELAX_GROUP when command line option '-r' is applied */
|
||
+ if (bfd_link_relocatable (lnkinfo))
|
||
+ {
|
||
+ elf32_nds32_unify_relax_group (inbfd, insec);
|
||
+ /* goto finish; */
|
||
+ return result;
|
||
+ }
|
||
+
|
||
+ /* Relocations MUST be kept in memory, because relaxation adjust them. */
|
||
+ internal_relocs = _bfd_elf_link_read_relocs (inbfd, insec, NULL, NULL,
|
||
+ TRUE /* keep_memory */);
|
||
+ if (internal_relocs == NULL)
|
||
+ goto error_return;
|
||
+
|
||
+ irelend = internal_relocs + insec->reloc_count;
|
||
+ irel = find_relocs_at_address (internal_relocs, internal_relocs,
|
||
+ irelend, R_NDS32_RELAX_ENTRY);
|
||
+ if (irel == irelend)
|
||
+ goto finish;
|
||
+
|
||
+ /* chain/remove groups */
|
||
+ for (irel = internal_relocs; irel < irelend; irel++)
|
||
+ {
|
||
+ r_symndx = ELF32_R_SYM (irel->r_info);
|
||
+ r_type = ELF32_R_TYPE (irel->r_info);
|
||
+ if (r_type != R_NDS32_RELAX_GROUP)
|
||
+ continue;
|
||
+
|
||
+ /* remove it */
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_NONE);
|
||
+ /* chain it now */
|
||
+ if (!list_insert (&chain, irel))
|
||
+ goto error_return;
|
||
+ }
|
||
|
||
- while (ptr)
|
||
+ /* collect group relocations */
|
||
+ /* presume relocations are sorted */
|
||
+ relax_group_list_t *pNext = chain.next;
|
||
+ while (pNext)
|
||
{
|
||
- /* Traverse the ifc gather list, and replace the
|
||
- filter entries by ifcall9. */
|
||
- if ((!(relax_status & NDS32_RELAX_JUMP_IFC_DONE) && ptr->enable == 1)
|
||
- || ((relax_status & NDS32_RELAX_JUMP_IFC_DONE)
|
||
- && ptr->ex9_enable == 1))
|
||
+ for (irel = internal_relocs; irel < irelend; irel++)
|
||
{
|
||
- irel_ptr = ptr->irel_head;
|
||
- if (ptr->h == NULL)
|
||
+ if (irel->r_offset == pNext->relo->r_offset)
|
||
{
|
||
- /* Local symbol. */
|
||
- internal_relocs = _bfd_elf_link_read_relocs
|
||
- (ptr->sec->owner, ptr->sec, NULL, NULL, TRUE /* keep_memory */);
|
||
- irelend = internal_relocs + ptr->sec->reloc_count;
|
||
-
|
||
- if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec,
|
||
- &contents, TRUE))
|
||
- return FALSE;
|
||
+ /* ignore Non-TLS relocation types */
|
||
+ r_type = ELF32_R_TYPE (irel->r_info);
|
||
+ if ((R_NDS32_TLS_LE_HI20 > r_type)
|
||
+ || (R_NDS32_RELAX_ENTRY == r_type))
|
||
+ continue;
|
||
|
||
- while (irel_ptr)
|
||
- {
|
||
- if (irel_ptr->keep == 0 && irel_ptr->next)
|
||
- {
|
||
- /* The one can be replaced. We have to check whether
|
||
- there is any alignment point in the region. */
|
||
- irel = irel_ptr->irel;
|
||
- while (((irel_ptr->next->keep == 0
|
||
- && irel < irel_ptr->next->irel)
|
||
- || (irel_ptr->next->keep == 1 && irel < irelend))
|
||
- && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
|
||
- && (irel->r_addend & 0x1f) == 2))
|
||
- irel++;
|
||
- if (irel >= irelend
|
||
- || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
|
||
- && (irel->r_addend & 0x1f) == 2
|
||
- && ((irel->r_offset - get_nds32_elf_blank_total
|
||
- (&relax_blank_list, irel->r_offset, 1))
|
||
- & 0x02) == 0))
|
||
- {
|
||
- /* Replace by ifcall9. */
|
||
- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
|
||
- if (!insert_nds32_elf_blank_recalc_total
|
||
- (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2))
|
||
- return FALSE;
|
||
- irel_ptr->irel->r_info =
|
||
- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
|
||
- R_NDS32_10IFCU_PCREL_RELA);
|
||
- }
|
||
- }
|
||
- irel_ptr = irel_ptr->next;
|
||
- }
|
||
+ if (!list_insert_sibling (pNext, irel))
|
||
+ goto error_return;
|
||
+ }
|
||
+ else if (irel->r_offset > pNext->relo->r_offset)
|
||
+ {
|
||
+ pNext = pNext->next;
|
||
+ if (!pNext)
|
||
+ break;
|
||
|
||
- /* Delete the redundant code. */
|
||
- if (relax_blank_list)
|
||
- {
|
||
- nds32_elf_relax_delete_blanks (ptr->sec->owner, ptr->sec,
|
||
- relax_blank_list);
|
||
- relax_blank_list = NULL;
|
||
- }
|
||
+ bfd_vma current_offset = pNext->relo->r_offset;
|
||
+ if (irel->r_offset > current_offset)
|
||
+ irel = internal_relocs; /* restart from head */
|
||
+ else
|
||
+ --irel; /* check current irel again */
|
||
+ continue;
|
||
}
|
||
else
|
||
{
|
||
- /* Global symbol. */
|
||
- while (irel_ptr)
|
||
- {
|
||
- if (irel_ptr->keep == 0 && irel_ptr->next)
|
||
- {
|
||
- /* The one can be replaced, and we have to check
|
||
- whether there is any alignment point in the region. */
|
||
- internal_relocs = _bfd_elf_link_read_relocs
|
||
- (irel_ptr->sec->owner, irel_ptr->sec, NULL, NULL,
|
||
- TRUE /* keep_memory */);
|
||
- irelend = internal_relocs + irel_ptr->sec->reloc_count;
|
||
- if (!nds32_get_section_contents (irel_ptr->sec->owner,
|
||
- irel_ptr->sec, &contents,
|
||
- TRUE))
|
||
- return FALSE;
|
||
-
|
||
- irel = irel_ptr->irel;
|
||
- while (((irel_ptr->sec == irel_ptr->next->sec
|
||
- && irel_ptr->next->keep == 0
|
||
- && irel < irel_ptr->next->irel)
|
||
- || ((irel_ptr->sec != irel_ptr->next->sec
|
||
- || irel_ptr->next->keep == 1)
|
||
- && irel < irelend))
|
||
- && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
|
||
- && (irel->r_addend & 0x1f) == 2))
|
||
- irel++;
|
||
- if (irel >= irelend
|
||
- || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
|
||
- && (irel->r_addend & 0x1f) == 2
|
||
- && ((irel->r_offset
|
||
- - get_nds32_elf_blank_total (&relax_blank_list,
|
||
- irel->r_offset, 1)) & 0x02) == 0))
|
||
- {
|
||
- /* Replace by ifcall9. */
|
||
- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
|
||
- if (!insert_nds32_elf_blank_recalc_total
|
||
- (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2))
|
||
- return FALSE;
|
||
-
|
||
- /* Delete the redundant code, and clear the relocation. */
|
||
- nds32_elf_relax_delete_blanks (irel_ptr->sec->owner,
|
||
- irel_ptr->sec,
|
||
- relax_blank_list);
|
||
- irel_ptr->irel->r_info =
|
||
- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
|
||
- R_NDS32_10IFCU_PCREL_RELA);
|
||
- relax_blank_list = NULL;
|
||
- }
|
||
- }
|
||
-
|
||
- irel_ptr = irel_ptr->next;
|
||
- }
|
||
+ //printf("irel->off = 0x%08x, pNext->relo->off = 0x%08x (0x%08x)\n", (unsigned)irel->r_offset, (unsigned)pNext->relo->r_offset, (unsigned)first_offset);
|
||
}
|
||
}
|
||
- ptr = ptr->next;
|
||
+ if (pNext)
|
||
+ pNext = pNext->next;
|
||
}
|
||
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Relocate ifcall. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ifc_reloc (void)
|
||
-{
|
||
- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
|
||
- struct elf_nds32_ifc_irel_list *irel_keeper = NULL;
|
||
- bfd_vma relocation, address;
|
||
- unsigned short insn16;
|
||
- bfd_byte *contents = NULL;
|
||
- static bfd_boolean done = FALSE;
|
||
+#ifdef DUBUG_VERBOSE
|
||
+ dump_chain(&chain);
|
||
+#endif
|
||
|
||
- if (done)
|
||
- return TRUE;
|
||
+ /* Get symbol table and section content. */
|
||
+ if (incontents)
|
||
+ contents = incontents;
|
||
+ else if (!nds32_get_section_contents (inbfd, insec, &contents, TRUE)
|
||
+ || !nds32_get_local_syms (inbfd, insec, &local_syms))
|
||
+ goto error_return;
|
||
|
||
- done = TRUE;
|
||
+ char *local_got_tls_type = elf32_nds32_local_got_tls_type (inbfd);
|
||
|
||
- while (ptr)
|
||
+ /* convert TLS model each group if necessary */
|
||
+ pNext = chain.next;
|
||
+ int cur_grp_id = -1;
|
||
+ int sethi_rt = -1;
|
||
+ int add_rt = -1;
|
||
+ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type;
|
||
+ tls_type = org_tls_type = eff_tls_type = 0;
|
||
+ while (pNext)
|
||
{
|
||
- /* Check the entry is enable ifcall. */
|
||
- if (ptr->enable == 1 || ptr->ex9_enable == 1)
|
||
+ relax_group_list_t *pNextSig = pNext->next_sibling;
|
||
+ while (pNextSig)
|
||
{
|
||
- /* Get the reserve jump. */
|
||
- irel_ptr = ptr->irel_head;
|
||
- while (irel_ptr)
|
||
+ struct elf_link_hash_entry *h = NULL;
|
||
+ irel = pNextSig->relo;
|
||
+ r_symndx = ELF32_R_SYM(irel->r_info);
|
||
+ r_type = ELF32_R_TYPE(irel->r_info);
|
||
+
|
||
+ if (pNext->id != cur_grp_id)
|
||
{
|
||
- if (irel_ptr->keep == 1)
|
||
+ cur_grp_id = pNext->id;
|
||
+ org_tls_type = get_tls_type (r_type, NULL);
|
||
+ if (r_symndx >= symtab_hdr->sh_info)
|
||
{
|
||
- irel_keeper = irel_ptr;
|
||
- break;
|
||
+ 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;
|
||
+ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* TODO: find local symbol hash if necessary? */
|
||
+ tls_type = local_got_tls_type ? local_got_tls_type[r_symndx] : GOT_NORMAL;
|
||
}
|
||
- irel_ptr = irel_ptr->next;
|
||
+
|
||
+ eff_tls_type = 1 << (fls (tls_type) - 1);
|
||
+ sethi_rt = N32_RT5(bfd_getb32 (contents + irel->r_offset));
|
||
}
|
||
|
||
- irel_ptr = ptr->irel_head;
|
||
- if (ptr->h == NULL)
|
||
+ if (eff_tls_type != org_tls_type)
|
||
{
|
||
- /* Local symbol. */
|
||
- if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec,
|
||
- &contents, TRUE))
|
||
- return FALSE;
|
||
-
|
||
- while (irel_ptr)
|
||
+ switch (org_tls_type)
|
||
{
|
||
- if (irel_ptr->keep == 0
|
||
- && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA)
|
||
+ /* DESC to IEGP/IE/LE. */
|
||
+ case GOT_TLS_DESC:
|
||
+ switch (eff_tls_type)
|
||
{
|
||
- relocation = irel_keeper->irel->r_offset;
|
||
- relocation = relocation - irel_ptr->irel->r_offset;
|
||
- while (irel_keeper && relocation > 1022)
|
||
+ case GOT_TLS_IE:
|
||
+ switch (r_type)
|
||
{
|
||
- irel_keeper = irel_keeper->next;
|
||
- if (irel_keeper && irel_keeper->keep == 1)
|
||
- {
|
||
- relocation = irel_keeper->irel->r_offset;
|
||
- relocation = relocation - irel_ptr->irel->r_offset;
|
||
- }
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IE_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IE_LO12);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_ADD:
|
||
+ {
|
||
+ uint32_t insn = bfd_getb32 (
|
||
+ contents + irel->r_offset);
|
||
+ add_rt = N32_RT5 (insn);
|
||
+ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE);
|
||
+/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IE_LW);
|
||
+*/
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_FUNC:
|
||
+ bfd_putb32 (INSN_NOP, contents + irel->r_offset);
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_RELAX_REMOVE);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_CALL:
|
||
+ {
|
||
+ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt,
|
||
+ REG_TP);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE);
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_PTR_RESOLVED:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
}
|
||
- if (relocation > 1022)
|
||
+ break;
|
||
+ case GOT_TLS_IEGP:
|
||
+ switch (r_type)
|
||
{
|
||
- /* Double check. */
|
||
- irel_keeper = ptr->irel_head;
|
||
- while (irel_keeper)
|
||
- {
|
||
- if (irel_keeper->keep == 1)
|
||
- {
|
||
- relocation = irel_keeper->irel->r_offset;
|
||
- relocation = relocation - irel_ptr->irel->r_offset;
|
||
- }
|
||
- if (relocation <= 1022)
|
||
- break;
|
||
- irel_keeper = irel_keeper->next;
|
||
- }
|
||
- if (!irel_keeper)
|
||
- return FALSE;
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IEGP_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IEGP_LO12);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_ADD:
|
||
+ {
|
||
+ uint32_t insn = bfd_getb32 (
|
||
+ contents + irel->r_offset);
|
||
+ add_rt = N32_RT5 (insn);
|
||
+ insn = N32_MEM(LW, add_rt, sethi_rt, REG_GP, 0);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE);
|
||
+/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IEGP_LW);
|
||
+*/
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_FUNC:
|
||
+ bfd_putb32 (INSN_NOP, contents + irel->r_offset);
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_RELAX_REMOVE);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_CALL:
|
||
+ {
|
||
+ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt,
|
||
+ REG_TP);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE);
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_PTR_RESOLVED:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
}
|
||
- irel_ptr->irel->r_info =
|
||
- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
|
||
- R_NDS32_NONE);
|
||
- insn16 = INSN_IFCALL9 | (relocation >> 1);
|
||
- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
|
||
+ break;
|
||
+ case GOT_TLS_LE:
|
||
+ switch (r_type)
|
||
+ {
|
||
+ case R_NDS32_TLS_DESC_HI20:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_LO12:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_ADD:
|
||
+ {
|
||
+ uint32_t insn = bfd_getb32 (contents + irel->r_offset);
|
||
+ add_rt = N32_RT5 (insn);
|
||
+ insn = N32_ALU1 (ADD, REG_R0, sethi_rt, REG_TP);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_ADD);
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_FUNC:
|
||
+ bfd_putb32 (INSN_NOP, contents + irel->r_offset);
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE);
|
||
+ break;
|
||
+ case R_NDS32_TLS_DESC_CALL:
|
||
+ bfd_putb32 (INSN_NOP, contents + irel->r_offset);
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE);
|
||
+ break;
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_PTR_RESOLVED:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
+ }
|
||
+ break;
|
||
+ default:
|
||
+#ifdef DEBUG_VERBOSE
|
||
+ printf (
|
||
+ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n",
|
||
+ inbfd->filename, h ? h->root.root.string : "local",
|
||
+ (unsigned) irel->r_offset, tls_type, eff_tls_type,
|
||
+ org_tls_type);
|
||
+#endif
|
||
+ break;
|
||
}
|
||
- irel_ptr = irel_ptr->next;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Global symbol. */
|
||
- while (irel_ptr)
|
||
- {
|
||
- if (irel_ptr->keep == 0
|
||
- && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA)
|
||
+ break;
|
||
+ /* IEGP to IE/LE. */
|
||
+ case GOT_TLS_IEGP:
|
||
+ switch (eff_tls_type)
|
||
{
|
||
- /* Get the distance between ifcall and jump. */
|
||
- relocation = (irel_keeper->irel->r_offset
|
||
- + irel_keeper->sec->output_section->vma
|
||
- + irel_keeper->sec->output_offset);
|
||
- address = (irel_ptr->irel->r_offset
|
||
- + irel_ptr->sec->output_section->vma
|
||
- + irel_ptr->sec->output_offset);
|
||
- relocation = relocation - address;
|
||
-
|
||
- /* The distance is over ragne, find callee again. */
|
||
- while (irel_keeper && relocation > 1022)
|
||
+ case GOT_TLS_IE:
|
||
+ switch (r_type)
|
||
{
|
||
- irel_keeper = irel_keeper->next;
|
||
- if (irel_keeper && irel_keeper->keep ==1)
|
||
- {
|
||
- relocation = (irel_keeper->irel->r_offset
|
||
- + irel_keeper->sec->output_section->vma
|
||
- + irel_keeper->sec->output_offset);
|
||
- relocation = relocation - address;
|
||
- }
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IE_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ irel->r_info = ELF32_R_INFO(r_symndx,
|
||
+ R_NDS32_TLS_IE_LO12);
|
||
+ break;
|
||
+ case R_NDS32_PTR_RESOLVED:
|
||
+ {
|
||
+ uint32_t insn = bfd_getb32 (
|
||
+ contents + irel->r_offset);
|
||
+ add_rt = N32_RT5 (insn);
|
||
+ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+ }
|
||
+ break;
|
||
+ case R_NDS32_TLS_IEGP_LW:
|
||
+ break;
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
}
|
||
-
|
||
- if (relocation > 1022)
|
||
+ break;
|
||
+ case GOT_TLS_LE:
|
||
+ switch (r_type)
|
||
{
|
||
- /* Double check. */
|
||
- irel_keeper = ptr->irel_head;
|
||
- while (irel_keeper)
|
||
- {
|
||
- if (irel_keeper->keep == 1)
|
||
- {
|
||
-
|
||
- relocation = (irel_keeper->irel->r_offset
|
||
- + irel_keeper->sec->output_section->vma
|
||
- + irel_keeper->sec->output_offset);
|
||
- relocation = relocation - address;
|
||
- }
|
||
- if (relocation <= 1022)
|
||
- break;
|
||
- irel_keeper = irel_keeper->next;
|
||
- }
|
||
- if (!irel_keeper)
|
||
- return FALSE;
|
||
+ case R_NDS32_TLS_IEGP_HI20:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_IEGP_LO12:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12);
|
||
+ break;
|
||
+ case R_NDS32_TLS_IEGP_LW:
|
||
+ /* irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_TLS_LE_ADD); */
|
||
+ bfd_putb32 (INSN_NOP, contents + irel->r_offset);
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE);
|
||
+ break;
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ case R_NDS32_PTR_RESOLVED:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
}
|
||
- if (!nds32_get_section_contents
|
||
- (irel_ptr->sec->owner, irel_ptr->sec, &contents, TRUE))
|
||
- return FALSE;
|
||
- insn16 = INSN_IFCALL9 | (relocation >> 1);
|
||
- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
|
||
- irel_ptr->irel->r_info =
|
||
- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
|
||
- R_NDS32_NONE);
|
||
+ break;
|
||
+ default:
|
||
+#ifdef DEBUG_VERBOSE
|
||
+ printf (
|
||
+ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n",
|
||
+ inbfd->filename, h ? h->root.root.string : "local",
|
||
+ (unsigned) irel->r_offset, tls_type, eff_tls_type,
|
||
+ org_tls_type);
|
||
+#endif
|
||
+ break;
|
||
+ }
|
||
+ break;
|
||
+ /* IE to LE. */
|
||
+ case GOT_TLS_IE:
|
||
+ switch (eff_tls_type)
|
||
+ {
|
||
+ case GOT_TLS_LE:
|
||
+ switch (r_type)
|
||
+ {
|
||
+ case R_NDS32_TLS_IE_HI20:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20);
|
||
+ break;
|
||
+ case R_NDS32_TLS_IE_LO12S2:
|
||
+ {
|
||
+ uint32_t insn = bfd_getb32 (contents + irel->r_offset);
|
||
+ add_rt = N32_RT5 (insn);
|
||
+ insn = N32_TYPE2 (ORI, add_rt, sethi_rt, 0);
|
||
+ bfd_putb32 (insn, contents + irel->r_offset);
|
||
+
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12);
|
||
+ }
|
||
+ break;
|
||
+ /*
|
||
+ case R_NDS32_TLS_IE_ADD:
|
||
+ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_ADD);
|
||
+ break;
|
||
+ */
|
||
+ case R_NDS32_LOADSTORE:
|
||
+ case R_NDS32_PTR:
|
||
+ case R_NDS32_NONE:
|
||
+ case R_NDS32_LABEL:
|
||
+ break;
|
||
+ default:
|
||
+ BFD_ASSERT(0);
|
||
+ break;
|
||
+ }
|
||
+ break;
|
||
+ default:
|
||
+#ifdef DEBUG_VERBOSE
|
||
+ printf (
|
||
+ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n",
|
||
+ inbfd->filename, h ? h->root.root.string : "local",
|
||
+ (unsigned) irel->r_offset, tls_type, eff_tls_type,
|
||
+ org_tls_type);
|
||
+#endif
|
||
+ break;
|
||
}
|
||
- irel_ptr =irel_ptr->next;
|
||
+ break;
|
||
+ default:
|
||
+#ifdef DEBUG_VERBOSE
|
||
+ printf (
|
||
+ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n",
|
||
+ inbfd->filename, h ? h->root.root.string : "local",
|
||
+ (unsigned) irel->r_offset, tls_type, eff_tls_type,
|
||
+ org_tls_type);
|
||
+#endif
|
||
+ break;
|
||
}
|
||
}
|
||
+ pNextSig = pNextSig->next_sibling;
|
||
}
|
||
- ptr = ptr->next;
|
||
- }
|
||
-
|
||
- return TRUE;
|
||
-}
|
||
|
||
-/* End of IFC relaxation. */
|
||
-
|
||
-/* EX9 Instruction Table Relaxation. */
|
||
+#if 1
|
||
+ pNext = pNext->next;
|
||
+#else
|
||
+ while (pNext)
|
||
+ {
|
||
+ if (pNext->id != cur_grp_id)
|
||
+ break;
|
||
+ pNext = pNext->next;
|
||
+ }
|
||
+#endif
|
||
+ }
|
||
|
||
-/* Global hash list. */
|
||
-struct elf_link_hash_entry_list
|
||
-{
|
||
- struct elf_link_hash_entry *h;
|
||
- struct elf_link_hash_entry_list *next;
|
||
-};
|
||
+finish:
|
||
+ if (incontents)
|
||
+ contents = NULL;
|
||
|
||
-/* Save different destination but same insn. */
|
||
-struct elf_link_hash_entry_mul_list
|
||
-{
|
||
- /* Global symbol times. */
|
||
- int times;
|
||
- /* Save relocation for each global symbol but useful?? */
|
||
- Elf_Internal_Rela *irel;
|
||
- /* For sethi, two sethi may have the same high-part but different low-parts. */
|
||
- Elf_Internal_Rela rel_backup;
|
||
- struct elf_link_hash_entry_list *h_list;
|
||
- struct elf_link_hash_entry_mul_list *next;
|
||
-};
|
||
+ if (internal_relocs != NULL
|
||
+ && elf_section_data (insec)->relocs != internal_relocs)
|
||
+ free (internal_relocs);
|
||
|
||
-/* Instruction hash table. */
|
||
-struct elf_nds32_code_hash_entry
|
||
-{
|
||
- struct bfd_hash_entry root;
|
||
- int times;
|
||
- /* For insn that can use relocation or constant ex: sethi. */
|
||
- int const_insn;
|
||
- asection *sec;
|
||
- struct elf_link_hash_entry_mul_list *m_list;
|
||
- /* Using r_addend. */
|
||
- Elf_Internal_Rela *irel;
|
||
- /* Using r_info. */
|
||
- Elf_Internal_Rela rel_backup;
|
||
-};
|
||
+ if (contents != NULL
|
||
+ && elf_section_data (insec)->this_hdr.contents != contents)
|
||
+ free (contents);
|
||
|
||
-/* Instruction count list. */
|
||
-struct elf_nds32_insn_times_entry
|
||
-{
|
||
- const char *string;
|
||
- int times;
|
||
- int order;
|
||
- asection *sec;
|
||
- struct elf_link_hash_entry_mul_list *m_list;
|
||
- Elf_Internal_Rela *irel;
|
||
- Elf_Internal_Rela rel_backup;
|
||
- struct elf_nds32_insn_times_entry *next;
|
||
-};
|
||
+ if (local_syms != NULL && symtab_hdr->contents != (bfd_byte *) local_syms)
|
||
+ free (local_syms);
|
||
|
||
-/* J and JAL symbol list. */
|
||
-struct elf_nds32_symbol_entry
|
||
-{
|
||
- char *string;
|
||
- unsigned long insn;
|
||
- struct elf_nds32_symbol_entry *next;
|
||
-};
|
||
+ if (chain.next)
|
||
+ {
|
||
+ pNext = chain.next;
|
||
+ relax_group_list_t *pDel;
|
||
+ while (pNext)
|
||
+ {
|
||
+ pDel = pNext;
|
||
+ pNext = pNext->next;
|
||
+ free (pDel);
|
||
+ }
|
||
+ }
|
||
|
||
-/* Relocation list. */
|
||
-struct elf_nds32_irel_entry
|
||
-{
|
||
- Elf_Internal_Rela *irel;
|
||
- struct elf_nds32_irel_entry *next;
|
||
-};
|
||
+ return result;
|
||
|
||
-/* ex9.it insn need to be fixed. */
|
||
-struct elf_nds32_ex9_refix
|
||
-{
|
||
- Elf_Internal_Rela *irel;
|
||
- asection *sec;
|
||
- struct elf_link_hash_entry *h;
|
||
- int order;
|
||
- struct elf_nds32_ex9_refix *next;
|
||
-};
|
||
+error_return:
|
||
+ result = FALSE;
|
||
+ goto finish;
|
||
+}
|
||
|
||
-static struct bfd_hash_table ex9_code_table;
|
||
-static struct elf_nds32_insn_times_entry *ex9_insn_head = NULL;
|
||
-static struct elf_nds32_ex9_refix *ex9_refix_head = NULL;
|
||
+/* End TLS model conversion. */
|
||
+
|
||
|
||
-/* EX9 hash function. */
|
||
+/* Rom-patch table hash function. */
|
||
|
||
static struct bfd_hash_entry *
|
||
-nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry,
|
||
- struct bfd_hash_table *table,
|
||
- const char *string)
|
||
+nds32_elf_ict_hash_newfunc (struct bfd_hash_entry *entry,
|
||
+ struct bfd_hash_table *table,
|
||
+ const char *string)
|
||
{
|
||
- struct elf_nds32_code_hash_entry *ret;
|
||
+ struct elf_nds32_ict_hash_entry *ret;
|
||
|
||
/* Allocate the structure if it has not already been allocated by a
|
||
subclass. */
|
||
@@ -13602,1837 +15138,118 @@ nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry,
|
||
if (entry == NULL)
|
||
return entry;
|
||
|
||
- ret = (struct elf_nds32_code_hash_entry*) entry;
|
||
- ret->times = 0;
|
||
- ret->const_insn = 0;
|
||
- ret->m_list = NULL;
|
||
- ret->sec = NULL;
|
||
- ret->irel = NULL;
|
||
+ ret = (struct elf_nds32_ict_hash_entry*) entry;
|
||
+ ret->order = 0;
|
||
return &ret->root;
|
||
}
|
||
|
||
-/* Insert ex9 entry
|
||
- this insert must be stable sorted by times. */
|
||
+static void
|
||
+nds32_elf_ict_hash_init (void)
|
||
+{
|
||
+ if (!bfd_hash_table_init_n (&indirect_call_table, nds32_elf_ict_hash_newfunc,
|
||
+ sizeof (struct elf_nds32_ict_hash_entry),
|
||
+ 1023))
|
||
+ _bfd_error_handler (_("ld error: cannot init rom patch hash table\n"));
|
||
+ return;
|
||
+}
|
||
|
||
+/* Relocate for NDS32_ICT_SECTION. */
|
||
static void
|
||
-nds32_elf_ex9_insert_entry (struct elf_nds32_insn_times_entry *ptr)
|
||
+nds32_elf_ict_relocate (bfd *output_bfd, struct bfd_link_info *info)
|
||
{
|
||
- struct elf_nds32_insn_times_entry *temp;
|
||
- struct elf_nds32_insn_times_entry *temp2;
|
||
+ static bfd_boolean done = FALSE;
|
||
+ asection *sec;
|
||
+ bfd_byte *contents = NULL;
|
||
+ uint32_t insn;
|
||
+ unsigned int i;
|
||
+ struct elf_link_hash_entry *h;
|
||
+ struct bfd_link_hash_entry *h2;
|
||
+ bfd_vma relocation, base;
|
||
|
||
- if (ex9_insn_head == NULL)
|
||
- {
|
||
- ex9_insn_head = ptr;
|
||
- ptr->next = NULL;
|
||
- }
|
||
- else
|
||
+ if (done)
|
||
+ return;
|
||
+
|
||
+ done = TRUE;
|
||
+
|
||
+ sec = nds32_elf_get_target_section (info, NDS32_ICT_SECTION);
|
||
+ h2 = bfd_link_hash_lookup (info->hash, "_INDIRECT_CALL_TABLE_BASE_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ base = ((h2->u.def.value
|
||
+ + h2->u.def.section->output_section->vma
|
||
+ + h2->u.def.section->output_offset));
|
||
+
|
||
+ if (!nds32_get_section_contents (sec->owner, sec, &contents, TRUE))
|
||
+ return;
|
||
+
|
||
+ indirect_call_table.frozen = 1;
|
||
+ for (i = 0; i < indirect_call_table.size; i++)
|
||
{
|
||
- temp = ex9_insn_head;
|
||
- temp2 = ex9_insn_head;
|
||
- while (temp->next &&
|
||
- (temp->next->times >= ptr->times
|
||
- || temp->times == -1))
|
||
- {
|
||
- if (temp->times == -1)
|
||
- temp2 = temp;
|
||
- temp = temp->next;
|
||
- }
|
||
- if (ptr->times > temp->times && temp->times != -1)
|
||
+ struct bfd_hash_entry *p;
|
||
+ struct elf_nds32_ict_hash_entry *entry;
|
||
+
|
||
+ for (p = indirect_call_table.table[i]; p != NULL; p = p->next)
|
||
{
|
||
- ptr->next = temp;
|
||
- if (temp2->times == -1)
|
||
- temp2->next = ptr;
|
||
+ entry = (struct elf_nds32_ict_hash_entry *) p;
|
||
+ insn = INSN_J;
|
||
+ h = entry->h;
|
||
+ if ((h->root.type == bfd_link_hash_defined
|
||
+ || h->root.type == bfd_link_hash_defweak)
|
||
+ && h->root.u.def.section != NULL
|
||
+ && h->root.u.def.section->output_section != NULL)
|
||
+ {
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ {
|
||
+ insn = h->root.u.def.value +
|
||
+ h->root.u.def.section->output_section->vma +
|
||
+ h->root.u.def.section->output_offset;
|
||
+ bfd_put_32 (output_bfd, insn, contents + (entry->order) * 4);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ relocation = h->root.u.def.value +
|
||
+ h->root.u.def.section->output_section->vma +
|
||
+ h->root.u.def.section->output_offset;
|
||
+ insn |= ((relocation - base - entry->order * 4) >> 1)
|
||
+ & 0xffffff;
|
||
+ bfd_putb32 (insn, contents + (entry->order) * 4);
|
||
+ }
|
||
+ }
|
||
else
|
||
- ex9_insn_head = ptr;
|
||
- }
|
||
- else if (temp->next == NULL)
|
||
- {
|
||
- temp->next = ptr;
|
||
- ptr->next = NULL;
|
||
- }
|
||
- else
|
||
- {
|
||
- ptr->next = temp->next;
|
||
- temp->next = ptr;
|
||
+ {
|
||
+ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE)
|
||
+ {
|
||
+ insn = 0;
|
||
+ bfd_put_32 (output_bfd, insn, contents + (entry->order) * 4);
|
||
+ }
|
||
+ else
|
||
+ bfd_putb32 (insn, contents + (entry->order) * 4);
|
||
+ }
|
||
}
|
||
}
|
||
+ indirect_call_table.frozen = 0;
|
||
}
|
||
|
||
-/* Examine each insn times in hash table.
|
||
- Handle multi-link hash entry.
|
||
-
|
||
- TODO: This function doesn't assign so much info since it is fake. */
|
||
-
|
||
-static int
|
||
-nds32_elf_examine_insn_times (struct elf_nds32_code_hash_entry *h)
|
||
+static asection*
|
||
+nds32_elf_get_target_section (struct bfd_link_info *info, char *name)
|
||
{
|
||
- struct elf_nds32_insn_times_entry *ptr;
|
||
- int times;
|
||
+ asection *sec = NULL;
|
||
+ bfd *abfd;
|
||
|
||
- if (h->m_list == NULL)
|
||
+ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
|
||
{
|
||
- /* Local symbol insn or insn without relocation. */
|
||
- if (h->times < 3)
|
||
- return TRUE;
|
||
-
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = h->times;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = NULL;
|
||
- ptr->sec = h->sec;
|
||
- ptr->irel = h->irel;
|
||
- ptr->rel_backup = h->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
+ sec = bfd_get_section_by_name (abfd, name);
|
||
+ if (sec != NULL)
|
||
+ break;
|
||
}
|
||
- else
|
||
- {
|
||
- /* Global symbol insn. */
|
||
- /* Only sethi insn has multiple m_list. */
|
||
- struct elf_link_hash_entry_mul_list *m_list = h->m_list;
|
||
|
||
- times = 0;
|
||
- while (m_list)
|
||
- {
|
||
- times += m_list->times;
|
||
- m_list = m_list->next;
|
||
- }
|
||
- if (times >= 3)
|
||
- {
|
||
- m_list = h->m_list;
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = times; /* Use the total times. */
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = m_list;
|
||
- ptr->sec = h->sec;
|
||
- ptr->irel = m_list->irel;
|
||
- ptr->rel_backup = m_list->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- if (h->const_insn == 1)
|
||
- {
|
||
- /* sethi with constant value. */
|
||
- if (h->times < 3)
|
||
- return TRUE;
|
||
-
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = h->times;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = NULL;
|
||
- ptr->sec = NULL;
|
||
- ptr->irel = NULL;
|
||
- ptr->rel_backup = h->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- }
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Count each insn times in hash table.
|
||
- Handle multi-link hash entry. */
|
||
-
|
||
-static int
|
||
-nds32_elf_count_insn_times (struct elf_nds32_code_hash_entry *h)
|
||
-{
|
||
- int reservation, times;
|
||
- unsigned long relocation, min_relocation;
|
||
- struct elf_nds32_insn_times_entry *ptr;
|
||
-
|
||
- if (h->m_list == NULL)
|
||
- {
|
||
- /* Local symbol insn or insn without relocation. */
|
||
- if (h->times < 3)
|
||
- return TRUE;
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = h->times;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = NULL;
|
||
- ptr->sec = h->sec;
|
||
- ptr->irel = h->irel;
|
||
- ptr->rel_backup = h->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Global symbol insn. */
|
||
- /* Only sethi insn has multiple m_list. */
|
||
- struct elf_link_hash_entry_mul_list *m_list = h->m_list;
|
||
-
|
||
- if (ELF32_R_TYPE (m_list->rel_backup.r_info) == R_NDS32_HI20_RELA
|
||
- && m_list->next != NULL)
|
||
- {
|
||
- /* Sethi insn has different symbol or addend but has same hi20. */
|
||
- times = 0;
|
||
- reservation = 1;
|
||
- relocation = 0;
|
||
- min_relocation = 0xffffffff;
|
||
- while (m_list)
|
||
- {
|
||
- /* Get the minimum sethi address
|
||
- and calculate how many entry the sethi-list have to use. */
|
||
- if ((m_list->h_list->h->root.type == bfd_link_hash_defined
|
||
- || m_list->h_list->h->root.type == bfd_link_hash_defweak)
|
||
- && (m_list->h_list->h->root.u.def.section != NULL
|
||
- && m_list->h_list->h->root.u.def.section->output_section != NULL))
|
||
- {
|
||
- relocation = (m_list->h_list->h->root.u.def.value +
|
||
- m_list->h_list->h->root.u.def.section->output_section->vma +
|
||
- m_list->h_list->h->root.u.def.section->output_offset);
|
||
- relocation += m_list->irel->r_addend;
|
||
- }
|
||
- else
|
||
- relocation = 0;
|
||
- if (relocation < min_relocation)
|
||
- min_relocation = relocation;
|
||
- times += m_list->times;
|
||
- m_list = m_list->next;
|
||
- }
|
||
- if (min_relocation < ex9_relax_size)
|
||
- reservation = (min_relocation >> 12) + 1;
|
||
- else
|
||
- reservation = (min_relocation >> 12)
|
||
- - ((min_relocation - ex9_relax_size) >> 12) + 1;
|
||
- if (reservation < (times / 3))
|
||
- {
|
||
- /* Efficient enough to use ex9. */
|
||
- int i;
|
||
-
|
||
- for (i = reservation ; i > 0; i--)
|
||
- {
|
||
- /* Allocate number of reservation ex9 entry. */
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = h->m_list->times / reservation;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = h->m_list;
|
||
- ptr->sec = h->sec;
|
||
- ptr->irel = h->m_list->irel;
|
||
- ptr->rel_backup = h->m_list->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Normal global symbol that means no different address symbol
|
||
- using same ex9 entry. */
|
||
- if (m_list->times >= 3)
|
||
- {
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = m_list->times;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = h->m_list;
|
||
- ptr->sec = h->sec;
|
||
- ptr->irel = h->m_list->irel;
|
||
- ptr->rel_backup = h->m_list->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- }
|
||
-
|
||
- if (h->const_insn == 1)
|
||
- {
|
||
- /* sethi with constant value. */
|
||
- if (h->times < 3)
|
||
- return TRUE;
|
||
-
|
||
- ptr = (struct elf_nds32_insn_times_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->times = h->times;
|
||
- ptr->string = h->root.string;
|
||
- ptr->m_list = NULL;
|
||
- ptr->sec = NULL;
|
||
- ptr->irel = NULL;
|
||
- ptr->rel_backup = h->rel_backup;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- }
|
||
- }
|
||
-
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Hash table traverse function. */
|
||
-
|
||
-static void
|
||
-nds32_elf_code_hash_traverse (int (*func) (struct elf_nds32_code_hash_entry*))
|
||
-{
|
||
- unsigned int i;
|
||
-
|
||
- ex9_code_table.frozen = 1;
|
||
- for (i = 0; i < ex9_code_table.size; i++)
|
||
- {
|
||
- struct bfd_hash_entry *p;
|
||
-
|
||
- for (p = ex9_code_table.table[i]; p != NULL; p = p->next)
|
||
- if (!func ((struct elf_nds32_code_hash_entry *) p))
|
||
- goto out;
|
||
- }
|
||
-out:
|
||
- ex9_code_table.frozen = 0;
|
||
-}
|
||
-
|
||
-
|
||
-/* Give order number to insn list. */
|
||
-
|
||
-static void
|
||
-nds32_elf_order_insn_times (struct bfd_link_info *info)
|
||
-{
|
||
- struct elf_nds32_insn_times_entry *ex9_insn;
|
||
- struct elf_nds32_insn_times_entry *temp = NULL;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- int ex9_limit;
|
||
- int number = 0;
|
||
-
|
||
- if (ex9_insn_head == NULL)
|
||
- return;
|
||
-
|
||
-/* The max number of entries is 512. */
|
||
- ex9_insn = ex9_insn_head;
|
||
- table = nds32_elf_hash_table (info);
|
||
- ex9_limit = table->ex9_limit;
|
||
-
|
||
- ex9_insn = ex9_insn_head;
|
||
-
|
||
- while (ex9_insn != NULL && number < ex9_limit)
|
||
- {
|
||
- ex9_insn->order = number;
|
||
- number++;
|
||
- temp = ex9_insn;
|
||
- ex9_insn = ex9_insn->next;
|
||
- }
|
||
-
|
||
- if (ex9_insn && temp)
|
||
- temp->next = NULL;
|
||
-
|
||
- while (ex9_insn != NULL)
|
||
- {
|
||
- /* Free useless entry. */
|
||
- temp = ex9_insn;
|
||
- ex9_insn = ex9_insn->next;
|
||
- free (temp);
|
||
- }
|
||
-}
|
||
-
|
||
-/* Build .ex9.itable section. */
|
||
-
|
||
-static void
|
||
-nds32_elf_ex9_build_itable (struct bfd_link_info *link_info)
|
||
-{
|
||
- asection *table_sec;
|
||
- struct elf_nds32_insn_times_entry *ptr;
|
||
- bfd *it_abfd;
|
||
- int number = 0;
|
||
- bfd_byte *contents = NULL;
|
||
-
|
||
- for (it_abfd = link_info->input_bfds; it_abfd != NULL;
|
||
- it_abfd = it_abfd->link.next)
|
||
- {
|
||
- /* Find the section .ex9.itable, and put all entries into it. */
|
||
- table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable");
|
||
- if (table_sec != NULL)
|
||
- {
|
||
- if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE))
|
||
- return;
|
||
-
|
||
- for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next)
|
||
- number++;
|
||
-
|
||
- table_sec->size = number * 4;
|
||
-
|
||
- if (number == 0)
|
||
- return;
|
||
-
|
||
- elf_elfheader (link_info->output_bfd)->e_flags |= E_NDS32_HAS_EX9_INST;
|
||
- number = 0;
|
||
- for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next)
|
||
- {
|
||
- long val;
|
||
-
|
||
- val = strtol (ptr->string, NULL, 16);
|
||
- bfd_putb32 ((bfd_vma) val, (char *) contents + (number * 4));
|
||
- number++;
|
||
- }
|
||
- break;
|
||
- }
|
||
- }
|
||
-}
|
||
-
|
||
-/* Get insn with regs according to relocation type. */
|
||
-
|
||
-static void
|
||
-nds32_elf_get_insn_with_reg (Elf_Internal_Rela *irel,
|
||
- uint32_t insn, uint32_t *insn_with_reg)
|
||
-{
|
||
- reloc_howto_type *howto = NULL;
|
||
-
|
||
- if (irel == NULL
|
||
- || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table)
|
||
- && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY)
|
||
- >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table)))
|
||
- {
|
||
- *insn_with_reg = insn;
|
||
- return;
|
||
- }
|
||
-
|
||
- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
|
||
- *insn_with_reg = insn & (0xffffffff ^ howto->dst_mask);
|
||
-}
|
||
-
|
||
-/* Mask number of address bits according to relocation. */
|
||
-
|
||
-static unsigned long
|
||
-nds32_elf_irel_mask (Elf_Internal_Rela *irel)
|
||
-{
|
||
- reloc_howto_type *howto = NULL;
|
||
-
|
||
- if (irel == NULL
|
||
- || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table)
|
||
- && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY)
|
||
- >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table)))
|
||
- return 0;
|
||
-
|
||
- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
|
||
- return howto->dst_mask;
|
||
-}
|
||
-
|
||
-static void
|
||
-nds32_elf_insert_irel_entry (struct elf_nds32_irel_entry **irel_list,
|
||
- struct elf_nds32_irel_entry *irel_ptr)
|
||
-{
|
||
- if (*irel_list == NULL)
|
||
- {
|
||
- *irel_list = irel_ptr;
|
||
- irel_ptr->next = NULL;
|
||
- }
|
||
- else
|
||
- {
|
||
- irel_ptr->next = *irel_list;
|
||
- *irel_list = irel_ptr;
|
||
- }
|
||
-}
|
||
-
|
||
-static void
|
||
-nds32_elf_ex9_insert_fix (asection * sec, Elf_Internal_Rela * irel,
|
||
- struct elf_link_hash_entry *h, int order)
|
||
-{
|
||
- struct elf_nds32_ex9_refix *ptr;
|
||
-
|
||
- ptr = bfd_malloc (sizeof (struct elf_nds32_ex9_refix));
|
||
- ptr->sec = sec;
|
||
- ptr->irel = irel;
|
||
- ptr->h = h;
|
||
- ptr->order = order;
|
||
- ptr->next = NULL;
|
||
-
|
||
- if (ex9_refix_head == NULL)
|
||
- ex9_refix_head = ptr;
|
||
- else
|
||
- {
|
||
- struct elf_nds32_ex9_refix *temp = ex9_refix_head;
|
||
-
|
||
- while (temp->next != NULL)
|
||
- temp = temp->next;
|
||
- temp->next = ptr;
|
||
- }
|
||
-}
|
||
-
|
||
-enum
|
||
-{
|
||
- DATA_EXIST = 1,
|
||
- CLEAN_PRE = 1 << 1,
|
||
- PUSH_PRE = 1 << 2
|
||
-};
|
||
-
|
||
-/* Check relocation type if supporting for ex9. */
|
||
-
|
||
-static int
|
||
-nds32_elf_ex9_relocation_check (struct bfd_link_info *info,
|
||
- Elf_Internal_Rela **irel,
|
||
- Elf_Internal_Rela *irelend,
|
||
- nds32_elf_blank_t *relax_blank_list,
|
||
- asection *sec,bfd_vma *off,
|
||
- bfd_byte *contents)
|
||
-{
|
||
- /* Suppress ex9 if `.no_relax ex9' or inner loop. */
|
||
- bfd_boolean nested_ex9, nested_loop;
|
||
- bfd_boolean ex9_loop_aware;
|
||
- /* We use the highest 1 byte of result to record
|
||
- how many bytes location counter has to move. */
|
||
- int result = 0;
|
||
- Elf_Internal_Rela *irel_save = NULL;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
-
|
||
- table = nds32_elf_hash_table (info);
|
||
- ex9_loop_aware = table->ex9_loop_aware;
|
||
-
|
||
- while ((*irel) != NULL && (*irel) < irelend && *off == (*irel)->r_offset)
|
||
- {
|
||
- switch (ELF32_R_TYPE ((*irel)->r_info))
|
||
- {
|
||
- case R_NDS32_RELAX_REGION_BEGIN:
|
||
- /* Ignore code block. */
|
||
- nested_ex9 = FALSE;
|
||
- nested_loop = FALSE;
|
||
- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG)
|
||
- || (ex9_loop_aware
|
||
- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)))
|
||
- {
|
||
- /* Check the region if loop or not. If it is true and
|
||
- ex9-loop-aware is true, ignore the region till region end. */
|
||
- /* To save the status for in .no_relax ex9 region and
|
||
- loop region to conform the block can do ex9 relaxation. */
|
||
- nested_ex9 = ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG);
|
||
- nested_loop = (ex9_loop_aware
|
||
- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG));
|
||
- while ((*irel) && (*irel) < irelend && (nested_ex9 || nested_loop))
|
||
- {
|
||
- (*irel)++;
|
||
- if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN)
|
||
- {
|
||
- /* There may be nested region. */
|
||
- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0)
|
||
- nested_ex9 = TRUE;
|
||
- else if (ex9_loop_aware
|
||
- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))
|
||
- nested_loop = TRUE;
|
||
- }
|
||
- else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_END)
|
||
- {
|
||
- /* The end of region. */
|
||
- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0)
|
||
- nested_ex9 = FALSE;
|
||
- else if (ex9_loop_aware
|
||
- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))
|
||
- nested_loop = FALSE;
|
||
- }
|
||
- else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_LABEL
|
||
- && ((*irel)->r_addend & 0x1f) == 2)
|
||
- {
|
||
- /* Alignment exist in the region. */
|
||
- result |= CLEAN_PRE;
|
||
- if (((*irel)->r_offset -
|
||
- get_nds32_elf_blank_total (&relax_blank_list,
|
||
- (*irel)->r_offset, 0)) & 0x02)
|
||
- result |= PUSH_PRE;
|
||
- }
|
||
- }
|
||
- if ((*irel) >= irelend)
|
||
- *off = sec->size;
|
||
- else
|
||
- *off = (*irel)->r_offset;
|
||
-
|
||
- /* The final instruction in the region, regard this one as data to ignore it. */
|
||
- result |= DATA_EXIST;
|
||
- return result;
|
||
- }
|
||
- break;
|
||
-
|
||
- case R_NDS32_LABEL:
|
||
- if (((*irel)->r_addend & 0x1f) == 2)
|
||
- {
|
||
- /* Check this point is align and decide to do ex9 or not. */
|
||
- result |= CLEAN_PRE;
|
||
- if (((*irel)->r_offset -
|
||
- get_nds32_elf_blank_total (&relax_blank_list,
|
||
- (*irel)->r_offset, 0)) & 0x02)
|
||
- result |= PUSH_PRE;
|
||
- }
|
||
- break;
|
||
- case R_NDS32_32_RELA:
|
||
- /* Data. */
|
||
- result |= (4 << 24);
|
||
- result |= DATA_EXIST;
|
||
- break;
|
||
- case R_NDS32_16_RELA:
|
||
- /* Data. */
|
||
- result |= (2 << 24);
|
||
- result |= DATA_EXIST;
|
||
- break;
|
||
- case R_NDS32_DATA:
|
||
- /* Data. */
|
||
- /* The least code alignment is 2. If the data is only one byte,
|
||
- we have to shift one more byte. */
|
||
- if ((*irel)->r_addend == 1)
|
||
- result |= ((*irel)->r_addend << 25) ;
|
||
- else
|
||
- result |= ((*irel)->r_addend << 24) ;
|
||
-
|
||
- result |= DATA_EXIST;
|
||
- break;
|
||
-
|
||
- case R_NDS32_25_PCREL_RELA:
|
||
- case R_NDS32_SDA16S3_RELA:
|
||
- case R_NDS32_SDA15S3_RELA:
|
||
- case R_NDS32_SDA15S3:
|
||
- case R_NDS32_SDA17S2_RELA:
|
||
- case R_NDS32_SDA15S2_RELA:
|
||
- case R_NDS32_SDA12S2_SP_RELA:
|
||
- case R_NDS32_SDA12S2_DP_RELA:
|
||
- case R_NDS32_SDA15S2:
|
||
- case R_NDS32_SDA18S1_RELA:
|
||
- case R_NDS32_SDA15S1_RELA:
|
||
- case R_NDS32_SDA15S1:
|
||
- case R_NDS32_SDA19S0_RELA:
|
||
- case R_NDS32_SDA15S0_RELA:
|
||
- case R_NDS32_SDA15S0:
|
||
- case R_NDS32_HI20_RELA:
|
||
- case R_NDS32_LO12S0_ORI_RELA:
|
||
- case R_NDS32_LO12S0_RELA:
|
||
- case R_NDS32_LO12S1_RELA:
|
||
- case R_NDS32_LO12S2_RELA:
|
||
- /* These relocation is supported ex9 relaxation currently. */
|
||
- /* We have to save the relocation for using later, since we have
|
||
- to check there is any alignment in the same address. */
|
||
- irel_save = *irel;
|
||
- break;
|
||
- default:
|
||
- /* Not support relocations. */
|
||
- if (ELF32_R_TYPE ((*irel)->r_info) < ARRAY_SIZE (nds32_elf_howto_table)
|
||
- && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_NONE
|
||
- && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_INSN16)
|
||
- {
|
||
- /* Note: To optimize aggressively, it maybe can ignore R_NDS32_INSN16 here.
|
||
- But we have to consider if there is any side-effect. */
|
||
- if (!(result & DATA_EXIST))
|
||
- {
|
||
- /* We have to confirm there is no data relocation in the
|
||
- same address. In general case, this won't happen. */
|
||
- /* We have to do ex9 conservative, for those relocation not
|
||
- considerd we ignore instruction. */
|
||
- result |= DATA_EXIST;
|
||
- if (*(contents + *off) & 0x80)
|
||
- result |= (2 << 24);
|
||
- else
|
||
- result |= (4 << 24);
|
||
- break;
|
||
- }
|
||
- }
|
||
- }
|
||
- if ((*irel) < irelend
|
||
- && ((*irel) + 1) < irelend
|
||
- && (*irel)->r_offset == ((*irel) + 1)->r_offset)
|
||
- /* There are relocations pointing to the same address, we have to
|
||
- check all of them. */
|
||
- (*irel)++;
|
||
- else
|
||
- {
|
||
- if (irel_save)
|
||
- *irel = irel_save;
|
||
- return result;
|
||
- }
|
||
- }
|
||
- return result;
|
||
-}
|
||
-
|
||
-/* Replace with ex9 instruction. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ex9_push_insn (uint16_t insn16, bfd_byte *contents, bfd_vma pre_off,
|
||
- nds32_elf_blank_t **relax_blank_list,
|
||
- struct elf_nds32_irel_entry *pre_irel_ptr,
|
||
- struct elf_nds32_irel_entry **irel_list)
|
||
-{
|
||
- if (insn16 != 0)
|
||
- {
|
||
- /* Implement the ex9 relaxation. */
|
||
- bfd_putb16 (insn16, contents + pre_off);
|
||
- if (!insert_nds32_elf_blank_recalc_total (relax_blank_list,
|
||
- pre_off + 2, 2))
|
||
- return FALSE;
|
||
- if (pre_irel_ptr != NULL)
|
||
- nds32_elf_insert_irel_entry (irel_list, pre_irel_ptr);
|
||
- }
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Replace input file instruction which is in ex9 itable. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ex9_replace_instruction (struct bfd_link_info *info, bfd *abfd, asection *sec)
|
||
-{
|
||
- struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head;
|
||
- bfd_byte *contents = NULL;
|
||
- bfd_vma off;
|
||
- uint16_t insn16, insn_ex9;
|
||
- /* `pre_*' are used to track previous instruction that can use ex9.it. */
|
||
- bfd_vma pre_off = -1;
|
||
- uint16_t pre_insn16 = 0;
|
||
- struct elf_nds32_irel_entry *pre_irel_ptr = NULL;
|
||
- Elf_Internal_Rela *internal_relocs;
|
||
- Elf_Internal_Rela *irel;
|
||
- Elf_Internal_Rela *irelend;
|
||
- Elf_Internal_Shdr *symtab_hdr;
|
||
- Elf_Internal_Sym *isym = NULL;
|
||
- nds32_elf_blank_t *relax_blank_list = NULL;
|
||
- uint32_t insn = 0;
|
||
- uint32_t insn_with_reg = 0;
|
||
- uint32_t it_insn;
|
||
- uint32_t it_insn_with_reg;
|
||
- unsigned long r_symndx;
|
||
- asection *isec;
|
||
- struct elf_nds32_irel_entry *irel_list = NULL;
|
||
- struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
|
||
- int data_flag, do_replace, save_irel;
|
||
- struct elf_link_hash_entry_list *h_list;
|
||
-
|
||
-
|
||
- /* Load section instructions, relocations, and symbol table. */
|
||
- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)
|
||
- || !nds32_get_local_syms (abfd, sec, &isym))
|
||
- return FALSE;
|
||
- internal_relocs =
|
||
- _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, TRUE /* keep_memory */);
|
||
- irelend = internal_relocs + sec->reloc_count;
|
||
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||
-
|
||
- off = 0;
|
||
-
|
||
- /* Check if the object enable ex9. */
|
||
- irel = find_relocs_at_address (internal_relocs, internal_relocs,
|
||
- irelend, R_NDS32_RELAX_ENTRY);
|
||
-
|
||
- /* Check this section trigger ex9 relaxation. */
|
||
- if (irel == NULL
|
||
- || irel >= irelend
|
||
- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
|
||
- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
|
||
- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG)))
|
||
- return TRUE;
|
||
-
|
||
- irel = internal_relocs;
|
||
-
|
||
- /* Check alignment and fetch proper relocation. */
|
||
- while (off < sec->size)
|
||
- {
|
||
- struct elf_link_hash_entry *h = NULL;
|
||
- struct elf_nds32_irel_entry *irel_ptr = NULL;
|
||
-
|
||
- /* Syn the instruction and the relocation. */
|
||
- while (irel != NULL && irel < irelend && irel->r_offset < off)
|
||
- irel++;
|
||
-
|
||
- data_flag = nds32_elf_ex9_relocation_check (info, &irel, irelend,
|
||
- relax_blank_list, sec,
|
||
- &off, contents);
|
||
- if (data_flag & PUSH_PRE)
|
||
- if (!nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
|
||
- &relax_blank_list, pre_irel_ptr,
|
||
- &irel_list))
|
||
- return FALSE;
|
||
-
|
||
- if (data_flag & CLEAN_PRE)
|
||
- {
|
||
- pre_off = 0;
|
||
- pre_insn16 = 0;
|
||
- pre_irel_ptr = NULL;
|
||
- }
|
||
- if (data_flag & DATA_EXIST)
|
||
- {
|
||
- /* We save the move offset in the highest byte. */
|
||
- off += (data_flag >> 24);
|
||
- continue;
|
||
- }
|
||
-
|
||
- if (*(contents + off) & 0x80)
|
||
- {
|
||
- /* 2-byte instruction. */
|
||
- off += 2;
|
||
- continue;
|
||
- }
|
||
-
|
||
- /* Load the instruction and its opcode with register for comparing. */
|
||
- ex9_insn = ex9_insn_head;
|
||
- insn = bfd_getb32 (contents + off);
|
||
- insn_with_reg = 0;
|
||
- while (ex9_insn)
|
||
- {
|
||
- it_insn = strtol (ex9_insn->string, NULL, 16);
|
||
- it_insn_with_reg = 0;
|
||
- do_replace = 0;
|
||
- save_irel = 0;
|
||
-
|
||
- if (irel != NULL && irel < irelend && irel->r_offset == off)
|
||
- {
|
||
- /* Insn with relocation. */
|
||
- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
|
||
-
|
||
- if (ex9_insn->irel != NULL)
|
||
- nds32_elf_get_insn_with_reg (ex9_insn->irel, it_insn,
|
||
- &it_insn_with_reg);
|
||
-
|
||
- if (ex9_insn->irel != NULL
|
||
- && (ELF32_R_TYPE (irel->r_info) ==
|
||
- ELF32_R_TYPE (ex9_insn->irel->r_info))
|
||
- && (insn_with_reg == it_insn_with_reg))
|
||
- {
|
||
- /* Insn relocation and format is the same as table entry. */
|
||
-
|
||
- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <=
|
||
- R_NDS32_SDA12S2_SP_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
|
||
- {
|
||
- r_symndx = ELF32_R_SYM (irel->r_info);
|
||
- if (r_symndx < symtab_hdr->sh_info)
|
||
- {
|
||
- /* Local symbol. */
|
||
- int shndx = isym[r_symndx].st_shndx;
|
||
-
|
||
- isec = elf_elfsections (abfd)[shndx]->bfd_section;
|
||
- if (ex9_insn->sec == isec
|
||
- && ex9_insn->irel->r_addend == irel->r_addend
|
||
- && ex9_insn->irel->r_info == irel->r_info)
|
||
- {
|
||
- do_replace = 1;
|
||
- save_irel = 1;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* External symbol. */
|
||
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||
- if (ex9_insn->m_list)
|
||
- {
|
||
- h_list = ex9_insn->m_list->h_list;
|
||
- while (h_list)
|
||
- {
|
||
- if (h == h_list->h
|
||
- && (ex9_insn->m_list->irel->r_addend ==
|
||
- irel->r_addend))
|
||
- {
|
||
- do_replace = 1;
|
||
- save_irel = 1;
|
||
- break;
|
||
- }
|
||
- h_list = h_list->next;
|
||
- }
|
||
- }
|
||
- }
|
||
- }
|
||
- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA)
|
||
- {
|
||
- r_symndx = ELF32_R_SYM (irel->r_info);
|
||
- if (r_symndx < symtab_hdr->sh_info)
|
||
- {
|
||
- /* Local symbols. Compare its base symbol and offset. */
|
||
- int shndx = isym[r_symndx].st_shndx;
|
||
-
|
||
- isec = elf_elfsections (abfd)[shndx]->bfd_section;
|
||
- if (ex9_insn->sec == isec
|
||
- && ex9_insn->irel->r_addend == irel->r_addend
|
||
- && ex9_insn->irel->r_info == irel->r_info)
|
||
- {
|
||
- do_replace = 1;
|
||
- save_irel = 1;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* External symbol. */
|
||
- struct elf_link_hash_entry_mul_list *m_list;
|
||
-
|
||
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||
- m_list = ex9_insn->m_list;
|
||
-
|
||
- while (m_list)
|
||
- {
|
||
- h_list = m_list->h_list;
|
||
-
|
||
- while (h_list)
|
||
- {
|
||
- if (h == h_list->h
|
||
- && (m_list->irel->r_addend
|
||
- == irel->r_addend))
|
||
- {
|
||
- do_replace = 1;
|
||
- save_irel = 1;
|
||
- if (ex9_insn->next
|
||
- && ex9_insn->m_list
|
||
- && ex9_insn->m_list == ex9_insn->next->m_list)
|
||
- {
|
||
- /* sethi multiple entry must be fixed */
|
||
- nds32_elf_ex9_insert_fix (sec, irel,
|
||
- h, ex9_insn->order);
|
||
- }
|
||
- break;
|
||
- }
|
||
- h_list = h_list->next;
|
||
- }
|
||
- m_list = m_list->next;
|
||
- }
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- /* Import table: Check the symbol hash table and the
|
||
- jump target. Only R_NDS32_25_PCREL_RELA now. */
|
||
- else if (ex9_insn->times == -1
|
||
- && ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA)
|
||
- {
|
||
- nds32_elf_get_insn_with_reg (irel, it_insn, &it_insn_with_reg);
|
||
- if (insn_with_reg == it_insn_with_reg)
|
||
- {
|
||
- char code[10];
|
||
- bfd_vma relocation;
|
||
-
|
||
- r_symndx = ELF32_R_SYM (irel->r_info);
|
||
- if (r_symndx >= symtab_hdr->sh_info)
|
||
- {
|
||
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||
- if ((h->root.type == bfd_link_hash_defined
|
||
- || h->root.type == bfd_link_hash_defweak)
|
||
- && h->root.u.def.section != NULL
|
||
- && h->root.u.def.section->output_section != NULL
|
||
- && h->root.u.def.section->gc_mark == 1
|
||
- && bfd_is_abs_section (h->root.u.def.section)
|
||
- && h->root.u.def.value > sec->size)
|
||
- {
|
||
- relocation = h->root.u.def.value +
|
||
- h->root.u.def.section->output_section->vma +
|
||
- h->root.u.def.section->output_offset;
|
||
- relocation += irel->r_addend;
|
||
- insn = insn_with_reg
|
||
- | ((relocation >> 1) & 0xffffff);
|
||
- snprintf (code, sizeof (code), "%08x", insn);
|
||
- if (strcmp (code, ex9_insn->string) == 0)
|
||
- {
|
||
- do_replace = 1;
|
||
- save_irel = 1;
|
||
- }
|
||
- }
|
||
- }
|
||
- }
|
||
- }
|
||
- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
|
||
- {
|
||
- /* These relocations do not have to relocate contens, so it can
|
||
- be regard as instruction without relocation. */
|
||
- if (insn == it_insn && ex9_insn->irel == NULL)
|
||
- do_replace = 1;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Instruction without relocation, we only
|
||
- have to compare their byte code. */
|
||
- if (insn == it_insn && ex9_insn->irel == NULL)
|
||
- do_replace = 1;
|
||
- }
|
||
-
|
||
- /* Insntruction match so replacing the code here. */
|
||
- if (do_replace == 1)
|
||
- {
|
||
- /* There are two formats of ex9 instruction. */
|
||
- if (ex9_insn->order < 32)
|
||
- insn_ex9 = INSN_EX9_IT_2;
|
||
- else
|
||
- insn_ex9 = INSN_EX9_IT_1;
|
||
- insn16 = insn_ex9 | ex9_insn->order;
|
||
-
|
||
- /* Insert ex9 instruction. */
|
||
- nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
|
||
- &relax_blank_list, pre_irel_ptr,
|
||
- &irel_list);
|
||
- pre_off = off;
|
||
- pre_insn16 = insn16;
|
||
-
|
||
- if (save_irel)
|
||
- {
|
||
- /* For instuction with relocation do relax. */
|
||
- irel_ptr = (struct elf_nds32_irel_entry *)
|
||
- bfd_malloc (sizeof (struct elf_nds32_irel_entry));
|
||
- irel_ptr->irel = irel;
|
||
- irel_ptr->next = NULL;
|
||
- pre_irel_ptr = irel_ptr;
|
||
- }
|
||
- else
|
||
- pre_irel_ptr = NULL;
|
||
- break;
|
||
- }
|
||
- ex9_insn = ex9_insn->next;
|
||
- }
|
||
- off += 4;
|
||
- }
|
||
-
|
||
- /* Insert ex9 instruction. */
|
||
- nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
|
||
- &relax_blank_list, pre_irel_ptr,
|
||
- &irel_list);
|
||
-
|
||
- /* Delete the redundant code. */
|
||
- if (relax_blank_list)
|
||
- {
|
||
- nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list);
|
||
- relax_blank_list = NULL;
|
||
- }
|
||
-
|
||
- /* Clear the relocation that is replaced by ex9. */
|
||
- while (irel_list)
|
||
- {
|
||
- struct elf_nds32_irel_entry *irel_ptr;
|
||
-
|
||
- irel_ptr = irel_list;
|
||
- irel_list = irel_ptr->next;
|
||
- irel_ptr->irel->r_info =
|
||
- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), R_NDS32_TRAN);
|
||
- free (irel_ptr);
|
||
- }
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Initialize ex9 hash table. */
|
||
-
|
||
-int
|
||
-nds32_elf_ex9_init (void)
|
||
-{
|
||
- if (!bfd_hash_table_init_n (&ex9_code_table, nds32_elf_code_hash_newfunc,
|
||
- sizeof (struct elf_nds32_code_hash_entry),
|
||
- 1023))
|
||
- {
|
||
- _bfd_error_handler (_("Linker: cannot init ex9 hash table error \n"));
|
||
- return FALSE;
|
||
- }
|
||
- return TRUE;
|
||
-}
|
||
-
|
||
-/* Predict how many bytes will be relaxed with ex9 and ifc. */
|
||
-
|
||
-static void
|
||
-nds32_elf_ex9_total_relax (struct bfd_link_info *info)
|
||
-{
|
||
- struct elf_nds32_insn_times_entry *ex9_insn;
|
||
- struct elf_nds32_insn_times_entry *temp;
|
||
- int target_optimize;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
-
|
||
- if (ex9_insn_head == NULL)
|
||
- return;
|
||
-
|
||
- table = nds32_elf_hash_table (info);
|
||
- target_optimize = table->target_optimize;
|
||
- ex9_insn = ex9_insn_head;
|
||
- while (ex9_insn)
|
||
- {
|
||
- ex9_relax_size = ex9_insn->times * 2 + ex9_relax_size;
|
||
- temp = ex9_insn;
|
||
- ex9_insn = ex9_insn->next;
|
||
- free (temp);
|
||
- }
|
||
- ex9_insn_head = NULL;
|
||
-
|
||
- if ((target_optimize & NDS32_RELAX_JUMP_IFC_ON))
|
||
- {
|
||
- /* Examine ifc reduce size. */
|
||
- struct elf_nds32_ifc_symbol_entry *ifc_ent = ifc_symbol_head;
|
||
- struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
|
||
- int size = 0;
|
||
-
|
||
- while (ifc_ent)
|
||
- {
|
||
- if (ifc_ent->enable == 0)
|
||
- {
|
||
- /* Not ifc yet. */
|
||
- irel_ptr = ifc_ent->irel_head;
|
||
- while (irel_ptr)
|
||
- {
|
||
- size += 2;
|
||
- irel_ptr = irel_ptr->next;
|
||
- }
|
||
- }
|
||
- size -= 2;
|
||
- ifc_ent = ifc_ent->next;
|
||
- }
|
||
- ex9_relax_size += size;
|
||
- }
|
||
-}
|
||
-
|
||
-/* Finish ex9 table. */
|
||
-
|
||
-void
|
||
-nds32_elf_ex9_finish (struct bfd_link_info *link_info)
|
||
-{
|
||
- nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times);
|
||
- nds32_elf_order_insn_times (link_info);
|
||
- nds32_elf_ex9_total_relax (link_info);
|
||
- /* Traverse the hash table and count its times. */
|
||
- nds32_elf_code_hash_traverse (nds32_elf_count_insn_times);
|
||
- nds32_elf_order_insn_times (link_info);
|
||
- nds32_elf_ex9_build_itable (link_info);
|
||
-}
|
||
-
|
||
-/* Relocate the entries in ex9 table. */
|
||
-
|
||
-static bfd_vma
|
||
-nds32_elf_ex9_reloc_insn (struct elf_nds32_insn_times_entry *ptr,
|
||
- struct bfd_link_info *link_info)
|
||
-{
|
||
- Elf_Internal_Sym *isym = NULL;
|
||
- bfd_vma relocation = -1;
|
||
- struct elf_link_hash_entry *h;
|
||
-
|
||
- if (ptr->m_list != NULL)
|
||
- {
|
||
- /* Global symbol. */
|
||
- h = ptr->m_list->h_list->h;
|
||
- if ((h->root.type == bfd_link_hash_defined
|
||
- || h->root.type == bfd_link_hash_defweak)
|
||
- && h->root.u.def.section != NULL
|
||
- && h->root.u.def.section->output_section != NULL)
|
||
- {
|
||
-
|
||
- relocation = h->root.u.def.value +
|
||
- h->root.u.def.section->output_section->vma +
|
||
- h->root.u.def.section->output_offset;
|
||
- relocation += ptr->m_list->irel->r_addend;
|
||
- }
|
||
- else
|
||
- relocation = 0;
|
||
- }
|
||
- else if (ptr->sec !=NULL)
|
||
- {
|
||
- /* Local symbol. */
|
||
- Elf_Internal_Sym sym;
|
||
- asection *sec = NULL;
|
||
- asection isec;
|
||
- asection *isec_ptr = &isec;
|
||
- Elf_Internal_Rela irel_backup = *(ptr->irel);
|
||
- asection *sec_backup = ptr->sec;
|
||
- bfd *abfd = ptr->sec->owner;
|
||
-
|
||
- if (!nds32_get_local_syms (abfd, sec, &isym))
|
||
- return FALSE;
|
||
- isym = isym + ELF32_R_SYM (ptr->irel->r_info);
|
||
-
|
||
- sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||
- if (sec != NULL)
|
||
- *isec_ptr = *sec;
|
||
- sym = *isym;
|
||
-
|
||
- /* The purpose is same as elf_link_input_bfd. */
|
||
- if (isec_ptr != NULL
|
||
- && isec_ptr->sec_info_type == SEC_INFO_TYPE_MERGE
|
||
- && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
|
||
- {
|
||
- sym.st_value =
|
||
- _bfd_merged_section_offset (ptr->sec->output_section->owner, &isec_ptr,
|
||
- elf_section_data (isec_ptr)->sec_info,
|
||
- isym->st_value);
|
||
- }
|
||
- relocation = _bfd_elf_rela_local_sym (link_info->output_bfd, &sym,
|
||
- &ptr->sec, ptr->irel);
|
||
- if (ptr->irel != NULL)
|
||
- relocation += ptr->irel->r_addend;
|
||
-
|
||
- /* Restore origin value since there may be some insntructions that
|
||
- could not be replaced with ex9.it. */
|
||
- *(ptr->irel) = irel_backup;
|
||
- ptr->sec = sec_backup;
|
||
- }
|
||
-
|
||
- return relocation;
|
||
-}
|
||
-
|
||
-/* Import ex9 table and build list. */
|
||
-
|
||
-void
|
||
-nds32_elf_ex9_import_table (struct bfd_link_info *info)
|
||
-{
|
||
- int num = 0;
|
||
- bfd_byte *contents;
|
||
- FILE *ex9_import_file;
|
||
- int update_ex9_table;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
-
|
||
- table = nds32_elf_hash_table (info);
|
||
- ex9_import_file = table->ex9_import_file;
|
||
- rewind (table->ex9_import_file);
|
||
-
|
||
- contents = bfd_malloc (sizeof (bfd_byte) * 4);
|
||
-
|
||
- /* Read instructions from the input file and build the list. */
|
||
- while (!feof (ex9_import_file))
|
||
- {
|
||
- unsigned long insn;
|
||
- char *code;
|
||
- struct elf_nds32_insn_times_entry *ptr;
|
||
- size_t nread;
|
||
-
|
||
- nread = fread (contents, sizeof (bfd_byte) * 4, 1, ex9_import_file);
|
||
- /* Ignore the final byte 0x0a. */
|
||
- if (nread < 1)
|
||
- break;
|
||
- insn = bfd_getb32 (contents);
|
||
- code = bfd_malloc (sizeof (char) * 9);
|
||
- snprintf (code, 9, "%08lx", (insn & 0xffffffff));
|
||
- ptr = bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
|
||
- ptr->string = code;
|
||
- ptr->order = num;
|
||
- ptr->times = -1;
|
||
- ptr->sec = NULL;
|
||
- ptr->m_list = NULL;
|
||
- ptr->rel_backup.r_offset = 0;
|
||
- ptr->rel_backup.r_info = 0;
|
||
- ptr->rel_backup.r_addend = 0;
|
||
- ptr->irel = NULL;
|
||
- ptr->next = NULL;
|
||
- nds32_elf_ex9_insert_entry (ptr);
|
||
- num++;
|
||
- }
|
||
-
|
||
- update_ex9_table = table->update_ex9_table;
|
||
- if (update_ex9_table == 1)
|
||
- {
|
||
- /* It has to consider of sethi need to use multiple page
|
||
- but it not be done yet. */
|
||
- nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times);
|
||
- nds32_elf_order_insn_times (info);
|
||
- }
|
||
-}
|
||
-
|
||
-/* Export ex9 table. */
|
||
-
|
||
-static void
|
||
-nds32_elf_ex9_export (struct bfd_link_info *info,
|
||
- bfd_byte *contents, int size)
|
||
-{
|
||
- FILE *ex9_export_file;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
-
|
||
- table = nds32_elf_hash_table (info);
|
||
- ex9_export_file = table->ex9_export_file;
|
||
- fwrite (contents, sizeof (bfd_byte), size, ex9_export_file);
|
||
- fclose (ex9_export_file);
|
||
-}
|
||
-
|
||
-/* Adjust relocations of J and JAL in ex9.itable.
|
||
- Export ex9 table. */
|
||
-
|
||
-static void
|
||
-nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info)
|
||
-{
|
||
- asection *table_sec = NULL;
|
||
- struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head;
|
||
- struct elf_nds32_insn_times_entry *temp_ptr, *temp_ptr2;
|
||
- bfd *it_abfd;
|
||
- uint32_t insn, insn_with_reg, source_insn;
|
||
- bfd_byte *contents = NULL, *source_contents = NULL;
|
||
- int size = 0;
|
||
- bfd_vma gp;
|
||
- int shift, update_ex9_table, offset = 0;
|
||
- reloc_howto_type *howto = NULL;
|
||
- Elf_Internal_Rela rel_backup;
|
||
- unsigned short insn_ex9;
|
||
- struct elf_nds32_link_hash_table *table;
|
||
- FILE *ex9_export_file;
|
||
- static bfd_boolean done = FALSE;
|
||
-
|
||
- if (done)
|
||
- return;
|
||
-
|
||
- done = TRUE;
|
||
-
|
||
- table = nds32_elf_hash_table (link_info);
|
||
- if (table)
|
||
- table->relax_status |= NDS32_RELAX_EX9_DONE;
|
||
-
|
||
-
|
||
- update_ex9_table = table->update_ex9_table;
|
||
- /* Generated ex9.itable exactly. */
|
||
- if (update_ex9_table == 0)
|
||
- {
|
||
- for (it_abfd = link_info->input_bfds; it_abfd != NULL;
|
||
- it_abfd = it_abfd->link.next)
|
||
- {
|
||
- table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable");
|
||
- if (table_sec != NULL)
|
||
- break;
|
||
- }
|
||
-
|
||
- if (table_sec != NULL)
|
||
- {
|
||
- bfd *output_bfd;
|
||
-
|
||
- output_bfd = table_sec->output_section->owner;
|
||
- nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
|
||
- if (table_sec->size == 0)
|
||
- return;
|
||
-
|
||
- if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE))
|
||
- return;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Set gp. */
|
||
- bfd *output_bfd;
|
||
-
|
||
- output_bfd = link_info->input_bfds->sections->output_section->owner;
|
||
- nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
|
||
- contents = bfd_malloc (sizeof (bfd_byte) * 2048);
|
||
- }
|
||
-
|
||
- /* Relocate instruction. */
|
||
- while (ex9_insn)
|
||
- {
|
||
- bfd_vma relocation, min_relocation = 0xffffffff;
|
||
-
|
||
- insn = strtol (ex9_insn->string, NULL, 16);
|
||
- insn_with_reg = 0;
|
||
- if (ex9_insn->m_list != NULL || ex9_insn->sec != NULL)
|
||
- {
|
||
- if (ex9_insn->m_list)
|
||
- rel_backup = ex9_insn->m_list->rel_backup;
|
||
- else
|
||
- rel_backup = ex9_insn->rel_backup;
|
||
-
|
||
- nds32_elf_get_insn_with_reg (&rel_backup, insn, &insn_with_reg);
|
||
- howto =
|
||
- bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE
|
||
- (rel_backup.r_info));
|
||
- shift = howto->rightshift;
|
||
- if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_25_PCREL_RELA
|
||
- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_ORI_RELA
|
||
- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_RELA
|
||
- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S1_RELA
|
||
- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S2_RELA)
|
||
- {
|
||
- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
|
||
- insn =
|
||
- insn_with_reg | ((relocation >> shift) &
|
||
- nds32_elf_irel_mask (&rel_backup));
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- }
|
||
- else if ((ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3
|
||
- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0)
|
||
- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3_RELA
|
||
- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0_RELA)
|
||
- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA12S2_DP_RELA
|
||
- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA12S2_SP_RELA)
|
||
- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA16S3_RELA
|
||
- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA19S0_RELA))
|
||
- {
|
||
- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
|
||
- insn =
|
||
- insn_with_reg | (((relocation - gp) >> shift) &
|
||
- nds32_elf_irel_mask (&rel_backup));
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- }
|
||
- else if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_HI20_RELA)
|
||
- {
|
||
- /* Sethi may be multiple entry for one insn. */
|
||
- if (ex9_insn->next && ex9_insn->m_list
|
||
- && ex9_insn->m_list == ex9_insn->next->m_list)
|
||
- {
|
||
- struct elf_link_hash_entry_mul_list *m_list;
|
||
- struct elf_nds32_ex9_refix *fix_ptr;
|
||
- struct elf_link_hash_entry *h;
|
||
-
|
||
- temp_ptr = ex9_insn;
|
||
- temp_ptr2 = ex9_insn;
|
||
- m_list = ex9_insn->m_list;
|
||
- while (m_list)
|
||
- {
|
||
- h = m_list->h_list->h;
|
||
- relocation = h->root.u.def.value +
|
||
- h->root.u.def.section->output_section->vma +
|
||
- h->root.u.def.section->output_offset;
|
||
- relocation += m_list->irel->r_addend;
|
||
-
|
||
- if (relocation < min_relocation)
|
||
- min_relocation = relocation;
|
||
- m_list = m_list->next;
|
||
- }
|
||
- relocation = min_relocation;
|
||
-
|
||
- /* Put insntruction into ex9 table. */
|
||
- insn = insn_with_reg
|
||
- | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup));
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- relocation = relocation + 0x1000; /* hi20 */
|
||
-
|
||
- while (ex9_insn->next && ex9_insn->m_list
|
||
- && ex9_insn->m_list == ex9_insn->next->m_list)
|
||
- {
|
||
- /* Multiple sethi. */
|
||
- ex9_insn = ex9_insn->next;
|
||
- size += 4;
|
||
- insn =
|
||
- insn_with_reg | ((relocation >> shift) &
|
||
- nds32_elf_irel_mask (&rel_backup));
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- relocation = relocation + 0x1000; /* hi20 */
|
||
- }
|
||
-
|
||
- fix_ptr = ex9_refix_head;
|
||
- while (fix_ptr)
|
||
- {
|
||
- /* Fix ex9 insn. */
|
||
- /* temp_ptr2 points to the head of multiple sethi. */
|
||
- temp_ptr = temp_ptr2;
|
||
- while (fix_ptr->order != temp_ptr->order && fix_ptr->next)
|
||
- {
|
||
- fix_ptr = fix_ptr->next;
|
||
- }
|
||
- if (fix_ptr->order != temp_ptr->order)
|
||
- break;
|
||
-
|
||
- /* Set source insn. */
|
||
- relocation =
|
||
- fix_ptr->h->root.u.def.value +
|
||
- fix_ptr->h->root.u.def.section->output_section->vma +
|
||
- fix_ptr->h->root.u.def.section->output_offset;
|
||
- relocation += fix_ptr->irel->r_addend;
|
||
- /* sethi imm is imm20s. */
|
||
- source_insn = insn_with_reg | ((relocation >> shift) & 0xfffff);
|
||
-
|
||
- while (temp_ptr)
|
||
- {
|
||
- /* Match entry and source code. */
|
||
- insn = bfd_getb32 (contents + (temp_ptr->order) * 4 + offset);
|
||
- if (insn == source_insn)
|
||
- {
|
||
- /* Fix the ex9 insn. */
|
||
- if (temp_ptr->order != fix_ptr->order)
|
||
- {
|
||
- if (!nds32_get_section_contents
|
||
- (fix_ptr->sec->owner, fix_ptr->sec,
|
||
- &source_contents, TRUE))
|
||
- _bfd_error_handler
|
||
- (_("Linker: error cannot fixed ex9 relocation \n"));
|
||
- if (temp_ptr->order < 32)
|
||
- insn_ex9 = INSN_EX9_IT_2;
|
||
- else
|
||
- insn_ex9 = INSN_EX9_IT_1;
|
||
- insn_ex9 = insn_ex9 | temp_ptr->order;
|
||
- bfd_putb16 (insn_ex9, source_contents + fix_ptr->irel->r_offset);
|
||
- }
|
||
- break;
|
||
- }
|
||
- else
|
||
- {
|
||
- if (!temp_ptr->next || temp_ptr->m_list != temp_ptr->next->m_list)
|
||
- _bfd_error_handler
|
||
- (_("Linker: error cannot fixed ex9 relocation \n"));
|
||
- else
|
||
- temp_ptr = temp_ptr->next;
|
||
- }
|
||
- }
|
||
- fix_ptr = fix_ptr->next;
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
|
||
- insn = insn_with_reg
|
||
- | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup));
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- }
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Insn without relocation does not have to be fixed
|
||
- if need to update export table. */
|
||
- if (update_ex9_table == 1)
|
||
- bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
|
||
- }
|
||
- ex9_insn = ex9_insn->next;
|
||
- size += 4;
|
||
- }
|
||
-
|
||
- ex9_export_file = table->ex9_export_file;
|
||
- if (ex9_export_file != NULL)
|
||
- nds32_elf_ex9_export (link_info, contents, table_sec->size);
|
||
- else if (update_ex9_table == 1)
|
||
- {
|
||
- table->ex9_export_file = table->ex9_import_file;
|
||
- rewind (table->ex9_export_file);
|
||
- nds32_elf_ex9_export (link_info, contents, size);
|
||
- }
|
||
-}
|
||
-
|
||
-/* Generate ex9 hash table. */
|
||
-
|
||
-static bfd_boolean
|
||
-nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec,
|
||
- struct bfd_link_info *link_info)
|
||
-{
|
||
- Elf_Internal_Rela *internal_relocs;
|
||
- Elf_Internal_Rela *irelend;
|
||
- Elf_Internal_Rela *irel;
|
||
- Elf_Internal_Rela *jrel;
|
||
- Elf_Internal_Rela rel_backup;
|
||
- Elf_Internal_Shdr *symtab_hdr;
|
||
- Elf_Internal_Sym *isym = NULL;
|
||
- asection *isec;
|
||
- struct elf_link_hash_entry **sym_hashes;
|
||
- bfd_byte *contents = NULL;
|
||
- bfd_vma off = 0;
|
||
- unsigned long r_symndx;
|
||
- uint32_t insn, insn_with_reg;
|
||
- struct elf_link_hash_entry *h;
|
||
- int data_flag, shift, align;
|
||
- bfd_vma relocation;
|
||
- /* Suppress ex9 if `.no_relax ex9' or inner loop. */
|
||
- reloc_howto_type *howto = NULL;
|
||
-
|
||
- sym_hashes = elf_sym_hashes (abfd);
|
||
- /* Load section instructions, relocations, and symbol table. */
|
||
- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE))
|
||
- return FALSE;
|
||
-
|
||
- internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
|
||
- TRUE /* keep_memory */);
|
||
- irelend = internal_relocs + sec->reloc_count;
|
||
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||
- if (!nds32_get_local_syms (abfd, sec, &isym))
|
||
- return FALSE;
|
||
-
|
||
- /* Check the object if enable ex9. */
|
||
- irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend,
|
||
- R_NDS32_RELAX_ENTRY);
|
||
-
|
||
- /* Check this section trigger ex9 relaxation. */
|
||
- if (irel == NULL
|
||
- || irel >= irelend
|
||
- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
|
||
- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
|
||
- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG)))
|
||
- return TRUE;
|
||
-
|
||
- irel = internal_relocs;
|
||
-
|
||
- /* Push each insn into hash table. */
|
||
- while (off < sec->size)
|
||
- {
|
||
- char code[10];
|
||
- struct elf_nds32_code_hash_entry *entry;
|
||
-
|
||
- while (irel != NULL && irel < irelend && irel->r_offset < off)
|
||
- irel++;
|
||
-
|
||
- data_flag = nds32_elf_ex9_relocation_check (link_info, &irel, irelend,
|
||
- NULL, sec, &off, contents);
|
||
- if (data_flag & DATA_EXIST)
|
||
- {
|
||
- /* We save the move offset in the highest byte. */
|
||
- off += (data_flag >> 24);
|
||
- continue;
|
||
- }
|
||
-
|
||
- if (*(contents + off) & 0x80)
|
||
- {
|
||
- off += 2;
|
||
- }
|
||
- else
|
||
- {
|
||
- h = NULL;
|
||
- isec = NULL;
|
||
- jrel = NULL;
|
||
- rel_backup.r_info = 0;
|
||
- rel_backup.r_offset = 0;
|
||
- rel_backup.r_addend = 0;
|
||
- /* Load the instruction and its opcode with register for comparing. */
|
||
- insn = bfd_getb32 (contents + off);
|
||
- insn_with_reg = 0;
|
||
- if (irel != NULL && irel < irelend && irel->r_offset == off)
|
||
- {
|
||
- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
|
||
- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
|
||
- shift = howto->rightshift;
|
||
- align = (1 << shift) - 1;
|
||
- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA
|
||
- ||(ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
|
||
- {
|
||
- r_symndx = ELF32_R_SYM (irel->r_info);
|
||
- jrel = irel;
|
||
- rel_backup = *irel;
|
||
- if (r_symndx < symtab_hdr->sh_info)
|
||
- {
|
||
- /* Local symbol. */
|
||
- int shndx = isym[r_symndx].st_shndx;
|
||
-
|
||
- bfd_vma st_value = (isym + r_symndx)->st_value;
|
||
- isec = elf_elfsections (abfd)[shndx]->bfd_section;
|
||
- relocation = (isec->output_section->vma + isec->output_offset
|
||
- + st_value + irel->r_addend);
|
||
- }
|
||
- else
|
||
- {
|
||
- /* External symbol. */
|
||
- bfd_boolean warned ATTRIBUTE_UNUSED;
|
||
- bfd_boolean ignored ATTRIBUTE_UNUSED;
|
||
- bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED;
|
||
- asection *sym_sec;
|
||
-
|
||
- /* Maybe there is a better way to get h and relocation */
|
||
- RELOC_FOR_GLOBAL_SYMBOL (link_info, abfd, sec, irel,
|
||
- r_symndx, symtab_hdr, sym_hashes,
|
||
- h, sym_sec, relocation,
|
||
- unresolved_reloc, warned, ignored);
|
||
- relocation += irel->r_addend;
|
||
- if ((h->root.type != bfd_link_hash_defined
|
||
- && h->root.type != bfd_link_hash_defweak)
|
||
- || strcmp (h->root.root.string, "_FP_BASE_") == 0)
|
||
- {
|
||
- off += 4;
|
||
- continue;
|
||
- }
|
||
- }
|
||
-
|
||
- /* Check for gp relative instruction alignment. */
|
||
- if ((ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA)
|
||
- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
|
||
- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
|
||
- {
|
||
- bfd_vma gp;
|
||
- bfd *output_bfd = sec->output_section->owner;
|
||
- bfd_reloc_status_type r;
|
||
-
|
||
- /* If the symbol is in the abs section, the out_bfd will be null.
|
||
- This happens when the relocation has a symbol@GOTOFF. */
|
||
- r = nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
|
||
- if (r != bfd_reloc_ok)
|
||
- {
|
||
- off += 4;
|
||
- continue;
|
||
- }
|
||
-
|
||
- relocation -= gp;
|
||
-
|
||
- /* Make sure alignment is correct. */
|
||
- if (relocation & align)
|
||
- {
|
||
- /* Incorrect alignment. */
|
||
- _bfd_error_handler
|
||
- /* xgettext:c-format */
|
||
- (_("%B: warning: unaligned small data access "
|
||
- "for entry: {%Ld, %Ld, %Ld}, addr = %#Lx, align = %#x"),
|
||
- abfd, irel->r_offset,
|
||
- irel->r_info, irel->r_addend, relocation, align);
|
||
- off += 4;
|
||
- continue;
|
||
- }
|
||
- }
|
||
-
|
||
- insn = insn_with_reg
|
||
- | ((relocation >> shift) & nds32_elf_irel_mask (irel));
|
||
- }
|
||
- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
|
||
- || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
|
||
- {
|
||
- /* These relocations do not have to relocate contens, so it can
|
||
- be regard as instruction without relocation. */
|
||
- }
|
||
- else
|
||
- {
|
||
- off += 4;
|
||
- continue;
|
||
- }
|
||
- }
|
||
-
|
||
- snprintf (code, sizeof (code), "%08x", insn);
|
||
- /* Copy "code". */
|
||
- entry = (struct elf_nds32_code_hash_entry*)
|
||
- bfd_hash_lookup (&ex9_code_table, code, TRUE, TRUE);
|
||
- if (entry == NULL)
|
||
- {
|
||
- _bfd_error_handler
|
||
- (_("failed creating ex9.it %s hash table entry"), code);
|
||
- return FALSE;
|
||
- }
|
||
- if (h)
|
||
- {
|
||
- if (h->root.type == bfd_link_hash_undefined)
|
||
- return TRUE;
|
||
- /* Global symbol. */
|
||
- /* In order to do sethi with different symbol but same value. */
|
||
- if (entry->m_list == NULL)
|
||
- {
|
||
- struct elf_link_hash_entry_mul_list *m_list_new;
|
||
- struct elf_link_hash_entry_list *h_list_new;
|
||
-
|
||
- m_list_new = (struct elf_link_hash_entry_mul_list *)
|
||
- bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list));
|
||
- h_list_new = (struct elf_link_hash_entry_list *)
|
||
- bfd_malloc (sizeof (struct elf_link_hash_entry_list));
|
||
- entry->m_list = m_list_new;
|
||
- m_list_new->h_list = h_list_new;
|
||
- m_list_new->rel_backup = rel_backup;
|
||
- m_list_new->times = 1;
|
||
- m_list_new->irel = jrel;
|
||
- m_list_new->next = NULL;
|
||
- h_list_new->h = h;
|
||
- h_list_new->next = NULL;
|
||
- }
|
||
- else
|
||
- {
|
||
- struct elf_link_hash_entry_mul_list *m_list = entry->m_list;
|
||
- struct elf_link_hash_entry_list *h_list;
|
||
-
|
||
- while (m_list)
|
||
- {
|
||
- /* Build the different symbols that point to the same address. */
|
||
- h_list = m_list->h_list;
|
||
- if (h_list->h->root.u.def.value == h->root.u.def.value
|
||
- && h_list->h->root.u.def.section->output_section->vma
|
||
- == h->root.u.def.section->output_section->vma
|
||
- && h_list->h->root.u.def.section->output_offset
|
||
- == h->root.u.def.section->output_offset
|
||
- && m_list->rel_backup.r_addend == rel_backup.r_addend)
|
||
- {
|
||
- m_list->times++;
|
||
- m_list->irel = jrel;
|
||
- while (h_list->h != h && h_list->next)
|
||
- h_list = h_list->next;
|
||
- if (h_list->h != h)
|
||
- {
|
||
- struct elf_link_hash_entry_list *h_list_new;
|
||
-
|
||
- h_list_new = (struct elf_link_hash_entry_list *)
|
||
- bfd_malloc (sizeof (struct elf_link_hash_entry_list));
|
||
- h_list->next = h_list_new;
|
||
- h_list_new->h = h;
|
||
- h_list_new->next = NULL;
|
||
- }
|
||
- break;
|
||
- }
|
||
- /* The sethi case may have different address but the
|
||
- hi20 is the same. */
|
||
- else if (ELF32_R_TYPE (jrel->r_info) == R_NDS32_HI20_RELA
|
||
- && m_list->next == NULL)
|
||
- {
|
||
- struct elf_link_hash_entry_mul_list *m_list_new;
|
||
- struct elf_link_hash_entry_list *h_list_new;
|
||
-
|
||
- m_list_new = (struct elf_link_hash_entry_mul_list *)
|
||
- bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list));
|
||
- h_list_new = (struct elf_link_hash_entry_list *)
|
||
- bfd_malloc (sizeof (struct elf_link_hash_entry_list));
|
||
- m_list->next = m_list_new;
|
||
- m_list_new->h_list = h_list_new;
|
||
- m_list_new->rel_backup = rel_backup;
|
||
- m_list_new->times = 1;
|
||
- m_list_new->irel = jrel;
|
||
- m_list_new->next = NULL;
|
||
- h_list_new->h = h;
|
||
- h_list_new->next = NULL;
|
||
- break;
|
||
- }
|
||
- m_list = m_list->next;
|
||
- }
|
||
- if (!m_list)
|
||
- {
|
||
- off += 4;
|
||
- continue;
|
||
- }
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Local symbol and insn without relocation*/
|
||
- entry->times++;
|
||
- entry->rel_backup = rel_backup;
|
||
- }
|
||
-
|
||
- /* Use in sethi insn with constant and global symbol in same format. */
|
||
- if (!jrel)
|
||
- entry->const_insn = 1;
|
||
- else
|
||
- entry->irel = jrel;
|
||
- entry->sec = isec;
|
||
- off += 4;
|
||
- }
|
||
- }
|
||
- return TRUE;
|
||
+ return sec;
|
||
}
|
||
-
|
||
-/* Set the _ITB_BASE, and point it to ex9 table. */
|
||
-
|
||
-bfd_boolean
|
||
-nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
|
||
-{
|
||
- bfd *abfd;
|
||
- asection *sec;
|
||
- bfd *output_bfd = NULL;
|
||
- struct bfd_link_hash_entry *bh = NULL;
|
||
-
|
||
- if (is_ITB_BASE_set == 1)
|
||
- return TRUE;
|
||
-
|
||
- is_ITB_BASE_set = 1;
|
||
-
|
||
- bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", FALSE, FALSE, TRUE);
|
||
-
|
||
- if (bh && (bh->type == bfd_link_hash_defined
|
||
- || bh->type == bfd_link_hash_defweak))
|
||
- return TRUE;
|
||
-
|
||
- for (abfd = link_info->input_bfds; abfd != NULL;
|
||
- abfd = abfd->link.next)
|
||
- {
|
||
- sec = bfd_get_section_by_name (abfd, ".ex9.itable");
|
||
- if (sec != NULL)
|
||
- {
|
||
- output_bfd = sec->output_section->owner;
|
||
- break;
|
||
- }
|
||
- }
|
||
- if (output_bfd == NULL)
|
||
- {
|
||
- output_bfd = link_info->output_bfd;
|
||
- if (output_bfd->sections == NULL)
|
||
- return TRUE;
|
||
- else
|
||
- sec = bfd_abs_section_ptr;
|
||
- }
|
||
- bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_",
|
||
- FALSE, FALSE, TRUE);
|
||
- return (_bfd_generic_link_add_one_symbol
|
||
- (link_info, output_bfd, "_ITB_BASE_",
|
||
- BSF_GLOBAL | BSF_WEAK, sec, 0,
|
||
- (const char *) NULL, FALSE, get_elf_backend_data
|
||
- (output_bfd)->collect, &bh));
|
||
-} /* End EX9.IT */
|
||
|
||
|
||
#define ELF_ARCH bfd_arch_nds32
|
||
#define ELF_MACHINE_CODE EM_NDS32
|
||
#define ELF_MAXPAGESIZE 0x1000
|
||
-#define ELF_TARGET_ID NDS32_ELF_DATA
|
||
+#define ELF_TARGET_ID NDS32_ELF_DATA
|
||
|
||
#define TARGET_BIG_SYM nds32_elf32_be_vec
|
||
#define TARGET_BIG_NAME "elf32-nds32be"
|
||
@@ -15448,7 +15265,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
|
||
#define bfd_elf32_bfd_relax_section nds32_elf_relax_section
|
||
#define bfd_elf32_bfd_set_private_flags nds32_elf_set_private_flags
|
||
|
||
-#define bfd_elf32_mkobject nds32_elf_mkobject
|
||
+#define bfd_elf32_mkobject nds32_elf_mkobject
|
||
#define elf_backend_action_discarded nds32_elf_action_discarded
|
||
#define elf_backend_add_symbol_hook nds32_elf_add_symbol_hook
|
||
#define elf_backend_check_relocs nds32_elf_check_relocs
|
||
@@ -15469,7 +15286,9 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
|
||
#define elf_backend_final_write_processing nds32_elf_final_write_processing
|
||
#define elf_backend_special_sections nds32_elf_special_sections
|
||
#define bfd_elf32_bfd_get_relocated_section_contents \
|
||
- nds32_elf_get_relocated_section_contents
|
||
+ nds32_elf_get_relocated_section_contents
|
||
+#define bfd_elf32_bfd_is_target_special_symbol nds32_elf_is_target_special_symbol
|
||
+#define elf_backend_maybe_function_sym nds32_elf_maybe_function_sym
|
||
|
||
#define elf_backend_can_gc_sections 1
|
||
#define elf_backend_can_refcount 1
|
||
@@ -15480,7 +15299,6 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
|
||
#define elf_backend_may_use_rel_p 1
|
||
#define elf_backend_default_use_rela_p 1
|
||
#define elf_backend_may_use_rela_p 1
|
||
-#define elf_backend_dtrel_excludes_plt 1
|
||
|
||
#include "elf32-target.h"
|
||
|
||
diff --git binutils-2.30/bfd/elf32-nds32.h binutils-2.30-nds32/bfd/elf32-nds32.h
|
||
index 7e09e01a3f..fda4155ab3 100644
|
||
--- binutils-2.30/bfd/elf32-nds32.h
|
||
+++ binutils-2.30-nds32/bfd/elf32-nds32.h
|
||
@@ -22,6 +22,8 @@
|
||
#ifndef ELF32_NDS32_H
|
||
#define ELF32_NDS32_H
|
||
|
||
+#include "bfd_stdint.h"
|
||
+
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
@@ -46,6 +48,13 @@ extern "C" {
|
||
#define R_NDS32_RELAX_ENTRY_EX9_FLAG (1 << 2)
|
||
/* Enable IFC optimization for this section. */
|
||
#define R_NDS32_RELAX_ENTRY_IFC_FLAG (1 << 3)
|
||
+/* Two bits for ICT to comply with files without directive. */
|
||
+/* ICT small model. */
|
||
+#define R_NDS32_RELAX_ENTRY_ICT_SMALL (0x2 << 4)
|
||
+/* ICT large model. */
|
||
+#define R_NDS32_RELAX_ENTRY_ICT_LARGE (0x3 << 4)
|
||
+/* Mask for get ict bits. */
|
||
+#define R_NDS32_RELAX_ENTRY_ICT_MASK (0x3 << 4)
|
||
|
||
|
||
/* Relocation flags for R_NDS32_INSN16. */
|
||
@@ -66,8 +75,6 @@ extern "C" {
|
||
/* NOT_OMIT_FP_FLAG is set if this region is not worth
|
||
for fp-as-gp. */
|
||
#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG (1 << 1)
|
||
-/* Suppress EX9 optimization in the region. */
|
||
-#define R_NDS32_RELAX_REGION_NO_EX9_FLAG (1 << 2)
|
||
/* A Innermost loop region. Some optimizations is suppressed
|
||
in this region due to performance drop. */
|
||
#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG (1 << 4)
|
||
@@ -91,35 +98,57 @@ enum
|
||
NDS32_RELAX_NONE_ROUND = 0,
|
||
NDS32_RELAX_NORMAL_ROUND,
|
||
NDS32_RELAX_JUMP_IFC_ROUND,
|
||
+ NDS32_RELAX_IFC_ROUND,
|
||
NDS32_RELAX_EX9_BUILD_ROUND,
|
||
NDS32_RELAX_EX9_REPLACE_ROUND,
|
||
NDS32_RELAX_EMPTY_ROUND
|
||
};
|
||
|
||
-/* Optimization status mask. */
|
||
-#define NDS32_RELAX_JUMP_IFC_DONE (1 << 0)
|
||
-#define NDS32_RELAX_EX9_DONE (1 << 1)
|
||
+/* Security tag. */
|
||
+enum
|
||
+{
|
||
+ NDS32_SECURITY_NONE = 0,
|
||
+ NDS32_SECURITY_START,
|
||
+ NDS32_SECURITY_RESTART,
|
||
+ NDS32_SECURITY_END
|
||
+};
|
||
|
||
/* Optimization turn on mask. */
|
||
-#define NDS32_RELAX_JUMP_IFC_ON (1 << 0)
|
||
+#define NDS32_RELAX_IFC_ON (1 << 0)
|
||
#define NDS32_RELAX_EX9_ON (1 << 1)
|
||
|
||
extern void nds32_insertion_sort
|
||
(void *, size_t, size_t, int (*) (const void *, const void *));
|
||
|
||
-extern int nds32_elf_ex9_init (void);
|
||
-extern int nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
|
||
-extern int nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
|
||
-extern void bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
|
||
- int, int, FILE *, int,
|
||
- int, int, int, FILE *,
|
||
- FILE *, int, int,
|
||
- bfd_boolean, bfd_boolean);
|
||
+struct section_id_list_t
|
||
+{
|
||
+ int id;
|
||
+ struct section_id_list_t *next;
|
||
+};
|
||
+
|
||
+extern struct section_id_list_t *
|
||
+elf32_nds32_lookup_section_id (int, struct section_id_list_t **);
|
||
+extern int elf32_nds32_check_relax_group (bfd *, asection *);
|
||
+extern int elf32_nds32_unify_relax_group (bfd *, asection *);
|
||
+extern int nds32_elf_unify_tls_model (bfd *, asection *, bfd_byte *,
|
||
+ struct bfd_link_info *);
|
||
+
|
||
+extern void bfd_elf32_nds32_set_target_option (struct bfd_link_info *, int, int,
|
||
+ FILE *, int, int, int, int, int,
|
||
+ int, char *);
|
||
+extern void bfd_elf32_nds32_append_section (struct bfd_link_info*, bfd *);
|
||
+extern int nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
|
||
+extern int nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
|
||
|
||
#define nds32_elf_hash_table(info) \
|
||
(elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
|
||
- == NDS32_ELF_DATA ? \
|
||
- ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL)
|
||
+ == NDS32_ELF_DATA ? ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL)
|
||
+
|
||
+#define elf32_nds32_compute_jump_table_size(htab) \
|
||
+ ((htab)->next_tls_desc_index * 4)
|
||
+
|
||
+#define elf32_nds32_local_tlsdesc_gotent(bfd) \
|
||
+ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent)
|
||
|
||
/* Hash table structure for target nds32. There are some members to
|
||
save target options passed from nds32elf.em to bfd. */
|
||
@@ -144,12 +173,34 @@ struct elf_nds32_link_hash_table
|
||
int target_optimize; /* Switch optimization. */
|
||
int relax_status; /* Finished optimization. */
|
||
int relax_round; /* Going optimization. */
|
||
- FILE *ex9_export_file; /* --mexport-ex9=<file> */
|
||
- FILE *ex9_import_file; /* --mimport-ex9=<file> */
|
||
- int update_ex9_table; /* --mupdate-ex9. */
|
||
- int ex9_limit;
|
||
- bfd_boolean ex9_loop_aware; /* Ignore ex9 if inside a loop. */
|
||
- bfd_boolean ifc_loop_aware; /* Ignore ifc if inside a loop. */
|
||
+ bfd_boolean hyper_relax; /* Relax for symbol not in RW sections. */
|
||
+ int tls_desc_trampoline; /* --m[no-]tlsdesc-trampoline. */
|
||
+
|
||
+ /* The offset into splt of the PLT entry for the TLS descriptor
|
||
+ resolver. Special values are 0, if not necessary (or not found
|
||
+ to be necessary yet), and -1 if needed but not determined
|
||
+ yet. */
|
||
+ bfd_vma dt_tlsdesc_plt;
|
||
+
|
||
+ /* The offset into sgot of the GOT entry used by the PLT entry
|
||
+ above. */
|
||
+ bfd_vma dt_tlsdesc_got;
|
||
+
|
||
+ /* Offset in .plt section of tls_nds32_trampoline. */
|
||
+ bfd_vma tls_trampoline;
|
||
+
|
||
+ /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt. */
|
||
+ bfd_vma next_tls_desc_index;
|
||
+
|
||
+ /* How many R_NDS32_TLS_DESC relocations were generated so far. */
|
||
+ bfd_vma num_tls_desc;
|
||
+
|
||
+ /* The amount of space used by the reserved portion of the sgotplt
|
||
+ section, plus whatever space is used by the jump slots. */
|
||
+ bfd_vma sgotplt_jump_table_size;
|
||
+
|
||
+ /* True if the target uses REL relocations. */
|
||
+ int use_rel;
|
||
};
|
||
|
||
#ifdef __cplusplus
|
||
diff --git binutils-2.30/bfd/libbfd.h binutils-2.30-nds32/bfd/libbfd.h
|
||
index 2f5f16e776..ff89105086 100644
|
||
--- binutils-2.30/bfd/libbfd.h
|
||
+++ binutils-2.30-nds32/bfd/libbfd.h
|
||
@@ -1872,6 +1872,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||
"BFD_RELOC_NDS32_SDA17S2",
|
||
"BFD_RELOC_NDS32_SDA18S1",
|
||
"BFD_RELOC_NDS32_SDA19S0",
|
||
+ "BFD_RELOC_NDS32_SECURITY_16",
|
||
"BFD_RELOC_NDS32_GOT20",
|
||
"BFD_RELOC_NDS32_9_PLTREL",
|
||
"BFD_RELOC_NDS32_25_PLTREL",
|
||
@@ -1955,18 +1956,39 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||
"BFD_RELOC_NDS32_17IFC_PCREL",
|
||
"BFD_RELOC_NDS32_10IFCU_PCREL",
|
||
"BFD_RELOC_NDS32_TPOFF",
|
||
+ "BFD_RELOC_NDS32_GOTTPOFF",
|
||
"BFD_RELOC_NDS32_TLS_LE_HI20",
|
||
"BFD_RELOC_NDS32_TLS_LE_LO12",
|
||
- "BFD_RELOC_NDS32_TLS_LE_ADD",
|
||
- "BFD_RELOC_NDS32_TLS_LE_LS",
|
||
- "BFD_RELOC_NDS32_GOTTPOFF",
|
||
- "BFD_RELOC_NDS32_TLS_IE_HI20",
|
||
- "BFD_RELOC_NDS32_TLS_IE_LO12S2",
|
||
- "BFD_RELOC_NDS32_TLS_TPOFF",
|
||
"BFD_RELOC_NDS32_TLS_LE_20",
|
||
"BFD_RELOC_NDS32_TLS_LE_15S0",
|
||
"BFD_RELOC_NDS32_TLS_LE_15S1",
|
||
"BFD_RELOC_NDS32_TLS_LE_15S2",
|
||
+ "BFD_RELOC_NDS32_TLS_LE_ADD",
|
||
+ "BFD_RELOC_NDS32_TLS_LE_LS",
|
||
+ "BFD_RELOC_NDS32_TLS_IE_HI20",
|
||
+ "BFD_RELOC_NDS32_TLS_IE_LO12",
|
||
+ "BFD_RELOC_NDS32_TLS_IE_LO12S2",
|
||
+ "BFD_RELOC_NDS32_TLS_IEGP_HI20",
|
||
+ "BFD_RELOC_NDS32_TLS_IEGP_LO12",
|
||
+ "BFD_RELOC_NDS32_TLS_IEGP_LO12S2",
|
||
+ "BFD_RELOC_NDS32_TLS_IEGP_LW",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_HI20",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_LO12",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_20",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_SDA17S2",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_ADD",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_FUNC",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_CALL",
|
||
+ "BFD_RELOC_NDS32_TLS_DESC_MEM",
|
||
+ "BFD_RELOC_NDS32_REMOVE",
|
||
+ "BFD_RELOC_NDS32_GROUP",
|
||
+ "BFD_RELOC_NDS32_ICT",
|
||
+ "BFD_RELOC_NDS32_ICT_HI20",
|
||
+ "BFD_RELOC_NDS32_ICT_LO12",
|
||
+ "BFD_RELOC_NDS32_ICT_25PC",
|
||
+ "BFD_RELOC_NDS32_ICT_LO12S2",
|
||
+ "BFD_RELOC_NDS32_LSI",
|
||
"BFD_RELOC_V850_9_PCREL",
|
||
"BFD_RELOC_V850_22_PCREL",
|
||
"BFD_RELOC_V850_SDA_16_16_OFFSET",
|
||
diff --git binutils-2.30/bfd/reloc.c binutils-2.30-nds32/bfd/reloc.c
|
||
index a1353a281b..0d96e13027 100644
|
||
--- binutils-2.30/bfd/reloc.c
|
||
+++ binutils-2.30-nds32/bfd/reloc.c
|
||
@@ -4182,6 +4182,10 @@ ENUMDOC
|
||
This is a 19-bit reloc containing the small data area 19-bit signed offset
|
||
and shift left by 0 for use in lbi.gp, sbi.gp...
|
||
ENUM
|
||
+ BFD_RELOC_NDS32_SECURITY_16
|
||
+ENUMDOC
|
||
+ This is a 24-bit reloc for security check sum.
|
||
+ENUM
|
||
BFD_RELOC_NDS32_GOT20
|
||
ENUMX
|
||
BFD_RELOC_NDS32_9_PLTREL
|
||
@@ -4375,33 +4379,62 @@ ENUMDOC
|
||
ENUM
|
||
BFD_RELOC_NDS32_TPOFF
|
||
ENUMX
|
||
+ BFD_RELOC_NDS32_GOTTPOFF
|
||
+ENUMX
|
||
BFD_RELOC_NDS32_TLS_LE_HI20
|
||
ENUMX
|
||
BFD_RELOC_NDS32_TLS_LE_LO12
|
||
ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_LE_20
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_LE_15S0
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_LE_15S1
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_LE_15S2
|
||
+ENUMX
|
||
BFD_RELOC_NDS32_TLS_LE_ADD
|
||
ENUMX
|
||
BFD_RELOC_NDS32_TLS_LE_LS
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_GOTTPOFF
|
||
-ENUMX
|
||
BFD_RELOC_NDS32_TLS_IE_HI20
|
||
ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_IE_LO12
|
||
+ENUMX
|
||
BFD_RELOC_NDS32_TLS_IE_LO12S2
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_TLS_TPOFF
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_HI20
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_TLS_LE_20
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LO12
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_TLS_LE_15S0
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LO12S2
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_TLS_LE_15S1
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_LW
|
||
ENUMX
|
||
- BFD_RELOC_NDS32_TLS_LE_15S2
|
||
+ BFD_RELOC_NDS32_TLS_DESC
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_HI20
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_LO12
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_20
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_SDA17S2
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_ADD
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_FUNC
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_CALL
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_TLS_DESC_MEM
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_REMOVE
|
||
+ENUMX
|
||
+ BFD_RELOC_NDS32_GROUP
|
||
ENUMDOC
|
||
For TLS.
|
||
|
||
-
|
||
ENUM
|
||
BFD_RELOC_V850_9_PCREL
|
||
ENUMDOC
|
||
diff --git binutils-2.30/gas/config.in binutils-2.30-nds32/gas/config.in
|
||
index 0855179696..551434a45b 100644
|
||
--- binutils-2.30/gas/config.in
|
||
+++ binutils-2.30-nds32/gas/config.in
|
||
@@ -202,6 +202,9 @@
|
||
/* Define default value for nds32_audio_ext */
|
||
#undef NDS32_DEFAULT_AUDIO_EXT
|
||
|
||
+/* Define default value for nds32_dsp_ext */
|
||
+#undef NDS32_DEFAULT_DSP_EXT
|
||
+
|
||
/* Define default value for nds32_dx_regs */
|
||
#undef NDS32_DEFAULT_DX_REGS
|
||
|
||
@@ -214,6 +217,12 @@
|
||
/* Define default value for nds32_string_ext */
|
||
#undef NDS32_DEFAULT_STRING_EXT
|
||
|
||
+/* Define default value for nds32_zol_ext */
|
||
+#undef NDS32_DEFAULT_ZOL_EXT
|
||
+
|
||
+/* Defined for linux toolchain */
|
||
+#undef NDS32_LINUX_TOOLCHAIN
|
||
+
|
||
/* Define if environ is not declared in system header files. */
|
||
#undef NEED_DECLARATION_ENVIRON
|
||
|
||
diff --git binutils-2.30/gas/config/tc-nds32.c binutils-2.30-nds32/gas/config/tc-nds32.c
|
||
index b2741b8213..f8cbd80edc 100644
|
||
--- binutils-2.30/gas/config/tc-nds32.c
|
||
+++ binutils-2.30-nds32/gas/config/tc-nds32.c
|
||
@@ -19,6 +19,8 @@
|
||
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||
02110-1301, USA. */
|
||
|
||
+#pragma GCC diagnostic ignored "-Wstack-usage="
|
||
+
|
||
#include "as.h"
|
||
#include "safe-ctype.h"
|
||
#include "subsegs.h"
|
||
@@ -35,6 +37,8 @@
|
||
#include "opcode/nds32.h"
|
||
|
||
#include <stdio.h>
|
||
+#include <errno.h>
|
||
+#include <limits.h>
|
||
|
||
/* GAS definitions. */
|
||
|
||
@@ -66,6 +70,8 @@ struct nds32_relocs_pattern
|
||
struct nds32_opcode *opcode;
|
||
char *where;
|
||
struct nds32_relocs_pattern *next;
|
||
+ /* Assembled instruction bytes. */
|
||
+ uint32_t insn;
|
||
};
|
||
|
||
/* Suffix name and relocation. */
|
||
@@ -73,7 +79,6 @@ struct suffix_name
|
||
{
|
||
const char *suffix;
|
||
short unsigned int reloc;
|
||
- int pic;
|
||
};
|
||
static int vec_size = 0;
|
||
/* If the assembly code is generated by compiler, it is supposed to have
|
||
@@ -87,11 +92,7 @@ static struct hash_control *nds32_hint_hash;
|
||
|
||
/* Generate relocation for relax or not, and the default is true. */
|
||
static int enable_relax_relocs = 1;
|
||
-/* The value will be used in RELAX_ENTRY. */
|
||
-static int enable_relax_ex9 = 0;
|
||
-/* The value will be used in RELAX_ENTRY. */
|
||
-static int enable_relax_ifc = 0;
|
||
-/* Save option -O for performance. */
|
||
+/* Save option -O for perfomance. */
|
||
static int optimize = 0;
|
||
/* Save option -Os for code size. */
|
||
static int optimize_for_space = 0;
|
||
@@ -99,1768 +100,1798 @@ static int optimize_for_space = 0;
|
||
static int label_exist = 0;
|
||
/* Flag to save state in omit_fp region. */
|
||
static int in_omit_fp = 0;
|
||
-extern struct nds32_keyword keyword_gpr[];
|
||
+extern keyword_t keyword_gpr[];
|
||
/* Tag there is relax relocation having to link. */
|
||
static bfd_boolean relaxing = FALSE;
|
||
+/* Save security status. */
|
||
+static bfd_boolean crcing = FALSE;
|
||
+/* Inline asm status. */
|
||
+static bfd_boolean inline_asm = FALSE;
|
||
+/* v3 is compatiable with v3f/v3s. */
|
||
+static bfd_boolean compatible_abi = FALSE;
|
||
+/* ICT model. */
|
||
+enum ict_option {
|
||
+ ICT_NONE = 0,
|
||
+ ICT_SMALL,
|
||
+ ICT_LARGE
|
||
+};
|
||
+static enum ict_option ict_flag = ICT_NONE;
|
||
+/* True if ICT existed. */
|
||
+static bfd_boolean ict_exist = FALSE;
|
||
|
||
static struct hash_control *nds32_relax_info_hash;
|
||
+/* Branch pattern. */
|
||
static relax_info_t relax_table[] =
|
||
{
|
||
- {
|
||
- "jal", /* opcode */
|
||
- BR_RANGE_S16M, /* br_range */
|
||
- {{0, 0, 0, FALSE}}, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JRAL_TA
|
||
- }, /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
|
||
- {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 4, 12}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
|
||
- {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bltzal", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BLTZAL /* bltzal $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BLTZAL /* bltzal $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BLTZAL /* bltzal $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BGEZ, /* bgez $rt, $1 */
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BGEZ, /* bgez $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JRAL_TA /* jral $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bgezal", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BGEZAL /* bgezal $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BGEZAL /* bgezal $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BGEZAL /* bgezal $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BLTZ, /* bltz $rt, $1 */
|
||
- INSN_JAL /* jal label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BLTZ, /* bltz $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JRAL_TA /* jral $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "j", /* opcode */
|
||
- BR_RANGE_S16M, /* br_range */
|
||
- {{0, 0, 0, FALSE}}, /* cond_field */
|
||
- {
|
||
- {
|
||
- (INSN_J8 << 16) /* j8 label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- }, /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
|
||
- {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 4, 12}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
|
||
- {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "j8", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
- {{0, 0, 0, FALSE}}, /* cond_field */
|
||
- {
|
||
- {
|
||
- (INSN_J8 << 16) /* j8 label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- }, /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
|
||
- {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 4, 12}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
|
||
- {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beqz", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BEQZ /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BEQZ /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQZ /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNEZ, /* bnez $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNEZ, /* bnez $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bgez", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BGEZ /* bgez $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BGEZ /* bgez $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BGEZ /* bgez $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BLTZ, /* bltz $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BLTZ, /* bltz $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bnez", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BNEZ /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BNEZ /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNEZ /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQZ, /* beqz $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQZ, /* beqz $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bgtz", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BGTZ /* bgtz $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BGTZ /* bgtz $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BGTZ /* bgtz $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BLEZ, /* blez $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BLEZ, /* blez $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "blez", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BLEZ /* blez $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BLEZ /* blez $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BLEZ /* blez $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BGTZ, /* bgtz $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BGTZ, /* bgtz $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bltz", /* opcode */
|
||
- BR_RANGE_S64K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BLTZ /* bltz $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BLTZ /* bltz $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BLTZ /* bltz $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BGEZ, /* bgez $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BGEZ, /* bgez $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beq", /* opcode */
|
||
- BR_RANGE_S16K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BEQ /* beq $rt, $ra, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BEQ /* beq $rt, $ra, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNE, /* bne $rt, $ra, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNE, /* bne $rt, $ra, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNE, /* bne $rt, $ra, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 8, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bne", /* opcode */
|
||
- BR_RANGE_S16K, /* br_range */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BNE /* bne $rt, $ra, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BNE /* bne $rt, $ra, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 15, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 4, 8, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beqz38", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BEQZ38 << 16 /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BEQZ /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQZ /* beqz $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNEZ, /* bnez $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNEZ, /* bnez $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
- {
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bnez38", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
- {
|
||
- {
|
||
- INSN_BNEZ38 << 16 /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BNEZ /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNEZ /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQZ, /* beqz $rt, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQZ, /* beqz $rt, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
{
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "jal",
|
||
+ .br_range = BR_RANGE_S16M,
|
||
+ .cond_field = {
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_size[BR_RANGE_S16M] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JRAL_TA}, /* jral $ta */
|
||
+ .relax_code_size[BR_RANGE_U4G] = 12,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
|
||
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beqzs8", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
- {{0, 0, 0, FALSE}}, /* cond_field */
|
||
+ .opcode = "bgezal",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BGEZAL}, /* bgezal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BGEZAL}, /* bgezal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BGEZAL}, /* bgezal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BLTZ, /* bltz $rt, $1 */
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BLTZ, /* bltz $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JRAL_TA}, /* jral $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BEQZS8 << 16 /* beqz $r15, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BEQZ_TA /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQZ_TA /* bnez $rt, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNEZ_TA, /* bnez $r15, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNEZ_TA, /* bnez $r15, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
|
||
- {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "bltzal",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BLTZAL}, /* bltzal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BLTZAL}, /* bltzal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BLTZAL}, /* bltzal $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BGEZ, /* bgez $rt, $1 */
|
||
+ INSN_JAL}, /* jal label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BGEZ, /* bgez $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JRAL_TA}, /* jral $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bnezs8", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
- {{0, 0, 0, FALSE}}, /* cond_field */
|
||
+ .opcode = "j",
|
||
+ .br_range = BR_RANGE_S16M,
|
||
+ .cond_field = {
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ (INSN_J8 << 16)}, /* j8 label */
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16M] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_size[BR_RANGE_U4G] = 12,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
|
||
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BNEZS8 << 16 /* bnez $r15, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BNEZ_TA /* bnez $r15, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNEZ_TA /* bnez $r15, label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQZ_TA, /* beqz $r15, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQZ_TA, /* beqz $r15, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
|
||
- {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
|
||
- {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 4, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "j8",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ (INSN_J8 << 16)}, /* j8 label */
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16M] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_size[BR_RANGE_U4G] = 12,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
|
||
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bnes38", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
+ .opcode = "beqz",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ /* We do not use beqz38 and beqzs8 here directly because we
|
||
+ don't want to check register number for specail condition. */
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQZ}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BEQZ}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQZ}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNEZ, /* bnez $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ /* bnez range is 17 pcrel, but it use 15 pcrel here since link time
|
||
+ relaxtion. If 17 pcrel can reach, it do not have to
|
||
+ use S16M. Therefore, 15 pcrel is just for linker to
|
||
+ distinguish LONGJUMP5 and LONGJUMP6. */
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNEZ, /* bnez $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
+ .opcode = "bgez",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BGEZ}, /* bgez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BGEZ}, /* bgez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BGEZ}, /* bgez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BLTZ, /* bltz $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BLTZ, /* bltz $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BNES38 << 16 /* bne $rt, $R5, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BNE_R5 /* bne $rt, $R5, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQ_R5, /* beq $rt, $R5, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQ_R5, /* beq $rt, $R5, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQ_R5, /* beq $rt, $R5, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
+ .opcode = "bnez",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNEZ}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BNEZ}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNEZ}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQZ, /* beqz $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQZ, /* beqz $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 8, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "bgtz",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BGTZ}, /* bgtz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BGTZ}, /* bgtz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BGTZ}, /* bgtz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BLEZ, /* blez $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BLEZ, /* blez $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beqs38", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
+ .opcode = "blez",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BLEZ}, /* blez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BLEZ}, /* blez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BLEZ}, /* blez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BGTZ, /* bgtz $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BGTZ, /* bgtz $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
+ .opcode = "bltz",
|
||
+ .br_range = BR_RANGE_S64K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BLTZ}, /* bltz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BLTZ}, /* bltz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BLTZ}, /* bltz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BGEZ, /* bgez $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BGEZ, /* bgez $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE},
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BEQS38 << 16 /* beq $rt, $R5, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_BEQ_R5 /* beq $rt, $R5, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNE_R5, /* bne $rt, $R5, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNE_R5, /* bne $rt, $R5, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNE_R5, /* bne $rt, $R5, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
+ .opcode = "beq",
|
||
+ .br_range = BR_RANGE_S16K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQ}, /* beq $rt, $ra, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BEQ}, /* beq $rt, $ra, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNE, /* bne $rt, $ra, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNE, /* bne $rt, $ra, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNE, /* bne $rt, $ra, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 8, 0x7, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {2, 4, 8, 8, 16}, /* relax_code_size */
|
||
- {2, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "bne",
|
||
+ .br_range = BR_RANGE_S16K,
|
||
+ .cond_field = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNE}, /* bne $rt, $ra, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BNE}, /* bne $rt, $ra, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQ, /* beq $rt, $ra, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 15, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
- {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
- {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
- {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "beqc", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
+ .opcode = "beqz38",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQZ38 << 16}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BEQZ}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQZ}, /* beqz $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNEZ, /* bnez $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNEZ, /* bnez $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ta */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {0, 8, 0x7FF, TRUE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
+ .opcode = "bnez38",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNEZ38 << 16}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BNEZ}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNEZ}, /* bnez $rt, label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQZ, /* beqz $rt, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQZ, /* beqz $rt, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BEQC /* beqc $rt, imm11s, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_MOVI_TA, /* movi $ta, imm11s */
|
||
- INSN_BEQ_TA /* beq $rt, $ta, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
+ .opcode = "beqzs8",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQZS8 << 16}, /* beqz $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BEQZ_TA}, /* beqz $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQZ_TA}, /* beqz $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNEZ_TA, /* bnez $r15, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNEZ_TA, /* bnez $r15, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 8, 0x7FF, TRUE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 0, 0xFFFFF, FALSE},
|
||
- {4, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 8, 8, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "bnezs8",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNEZS8 << 16}, /* bnez $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BNEZ_TA}, /* bnez $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNEZ_TA}, /* bnez $r15, label */
|
||
+ .relax_code_size[BR_RANGE_S64K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQZ_TA, /* beqz $r15, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQZ_TA, /* beqz $r15, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- },
|
||
- {
|
||
- "bnec", /* opcode */
|
||
- BR_RANGE_S256, /* br_range */
|
||
+ .opcode = "bnes38",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNES38 << 16}, /* bne $rt, $r5, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BNE_R5}, /* bne $rt, $r5, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQ_R5, /* beq $rt, $r5, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQ_R5, /* beq $rt, $r5, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQ_R5, /* beq $rt, $r5, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {0, 8, 0x7FF, TRUE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* cond_field */
|
||
+ .opcode = "beqs38",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQS38 << 16}, /* beq $rt, $r5, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 2,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 2,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_BEQ_R5}, /* beq $rt, $r5, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNE_R5, /* bne $rt, $r5, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNE_R5, /* bne $rt, $r5, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNE_R5, /* bne $rt, $r5, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
|
||
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- INSN_BNEC /* bnec $rt, imm11s, label */
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- INSN_MOVI_TA, /* movi $ta, imm11s */
|
||
- INSN_BNE_TA /* bne $rt, $ta, label */
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
- INSN_J /* j label */
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
- INSN_SETHI_TA, /* sethi $ta, label */
|
||
- INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
- INSN_JR_TA /* jr $ta */
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_seq */
|
||
+ .opcode = "beqc",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7FF, TRUE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BEQC}, /* beqc $rt, imm11s, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_MOVI_TA, /* movi $ta, imm11s */
|
||
+ INSN_BEQ_TA}, /* beq $rt, $ta, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 0, 0xFFFFF, FALSE},
|
||
+ {4, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 8, 0x7FF, TRUE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 0, 0xFFFFF, FALSE},
|
||
- {4, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 8, 0x7FF, FALSE},
|
||
- {0, 20, 0x1F, FALSE},
|
||
- {0, 0, 0, FALSE}
|
||
- } /* BR_RANGE_U4G */
|
||
- }, /* relax_code_condition */
|
||
- {4, 8, 8, 8, 16}, /* relax_code_size */
|
||
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
|
||
+ .opcode = "bnec",
|
||
+ .br_range = BR_RANGE_S256,
|
||
+ .cond_field = {
|
||
+ {0, 8, 0x7FF, TRUE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_seq[BR_RANGE_S256] = {
|
||
+ INSN_BNEC}, /* bnec $rt, imm11s, label */
|
||
+ .relax_code_condition[BR_RANGE_S256] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S256] = 4,
|
||
+ .relax_branch_isize[BR_RANGE_S256] = 4,
|
||
+ .relax_fixup[BR_RANGE_S256] = {
|
||
+ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16K] = {
|
||
+ INSN_MOVI_TA, /* movi $ta, imm11s */
|
||
+ INSN_BNE_TA}, /* bne $rt, $ta, label */
|
||
+ .relax_code_condition[BR_RANGE_S16K] = {
|
||
+ {0, 0, 0xFFFFF, FALSE},
|
||
+ {4, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16K] = {
|
||
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S64K] = {
|
||
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S64K] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S64K] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S64K] = 4,
|
||
+ .relax_fixup[BR_RANGE_S64K] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_S16M] = {
|
||
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
+ INSN_J}, /* j label */
|
||
+ .relax_code_condition[BR_RANGE_S16M] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_S16M] = 8,
|
||
+ .relax_branch_isize[BR_RANGE_S16M] = 4,
|
||
+ .relax_fixup[BR_RANGE_S16M] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+
|
||
+ .relax_code_seq[BR_RANGE_U4G] = {
|
||
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
|
||
+ INSN_SETHI_TA, /* sethi $ta, label */
|
||
+ INSN_ORI_TA, /* ori $ta, $ta, label */
|
||
+ INSN_JR_TA}, /* jr $ a */
|
||
+ .relax_code_condition[BR_RANGE_U4G] = {
|
||
+ {0, 8, 0x7FF, FALSE},
|
||
+ {0, 20, 0x1F, FALSE},
|
||
+ {0, 0, 0, FALSE}
|
||
+ },
|
||
+ .relax_code_size[BR_RANGE_U4G] = 16,
|
||
+ .relax_branch_isize[BR_RANGE_U4G] = 4,
|
||
+ .relax_fixup[BR_RANGE_U4G] = {
|
||
+ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
+ {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
+ {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ },
|
||
+ },
|
||
{
|
||
- {
|
||
- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S256 */
|
||
- {
|
||
- {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S64K */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
|
||
- {0, 0, 0, 0}
|
||
- }, /* BR_RANGE_S16M */
|
||
- {
|
||
- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
|
||
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
|
||
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
|
||
- {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
- {0, 0, 0, 0}
|
||
- } /* BR_RANGE_U4G */
|
||
- } /* relax_fixup */
|
||
- }
|
||
+ .opcode = NULL,
|
||
+ },
|
||
};
|
||
+
|
||
|
||
/* GAS definitions for command-line options. */
|
||
enum options
|
||
@@ -1901,9 +1932,9 @@ size_t md_longopts_size = sizeof (md_longopts);
|
||
|
||
struct nds32_parse_option_table
|
||
{
|
||
- const char *name; /* Option string. */
|
||
- const char *help; /* Help description. */
|
||
- int (*func) (const char *arg); /* How to parse it. */
|
||
+ const char *name; /* Option string. */
|
||
+ const char *help; /* Help description. */
|
||
+ int (*func) (const char *arg); /* How to parse it. */
|
||
};
|
||
|
||
|
||
@@ -1920,7 +1951,7 @@ static int nds32_fpu_dp_ext = -1;
|
||
static int nds32_freg = -1;
|
||
static int nds32_abi = -1;
|
||
|
||
-/* Record ELF flags */
|
||
+/* Record ELF flags. */
|
||
static int nds32_elf_flags = 0;
|
||
static int nds32_fpu_com = 0;
|
||
|
||
@@ -1929,34 +1960,49 @@ static int nds32_parse_baseline (const char *str);
|
||
static int nds32_parse_freg (const char *str);
|
||
static int nds32_parse_abi (const char *str);
|
||
|
||
+static void add_mapping_symbol (enum mstate state,
|
||
+ unsigned int padding_byte, unsigned int align);
|
||
+
|
||
static struct nds32_parse_option_table parse_opts [] =
|
||
{
|
||
+ {"ace=", N_("<shrlibfile>\t Support user defined instruction extension"),
|
||
+ nds32_parse_udi},
|
||
+ {"cop0=", N_("<shrlibfile>\t Support coprocessor 0 extension"),
|
||
+ nds32_parse_cop0},
|
||
+ {"cop1=", N_("<shrlibfile>\t Support coprocessor 1 extension"),
|
||
+ nds32_parse_cop1},
|
||
+ {"cop2=", N_("<shrlibfile>\t Support coprocessor 2 extension"),
|
||
+ nds32_parse_cop2},
|
||
+ {"cop3=", N_("<shrlibfile>\t Support coprocessor 3 extension"),
|
||
+ nds32_parse_cop3},
|
||
{"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
|
||
<arch name> could be\n\
|
||
- v3, v3j, v3m, v3f, v3s, "\
|
||
+ v3, v3j, v3m, v3m+ v3f, v3s, "\
|
||
"v2, v2j, v2f, v2s"), nds32_parse_arch},
|
||
{"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
|
||
<baseline> could be v2, v3, v3m"),
|
||
nds32_parse_baseline},
|
||
{"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
|
||
<freg>\n\
|
||
- 0: 8 SP / 4 DP registers\n\
|
||
- 1: 16 SP / 8 DP registers\n\
|
||
- 2: 32 SP / 16 DP registers\n\
|
||
- 3: 32 SP / 32 DP registers"), nds32_parse_freg},
|
||
+ 0/4: 8 SP / 4 DP registers\n\
|
||
+ 1/5: 16 SP / 8 DP registers\n\
|
||
+ 2/6: 32 SP / 16 DP registers\n\
|
||
+ 3/7: 32 SP / 32 DP registers"), nds32_parse_freg},
|
||
{"abi=", N_("<abi>\t Specify a abi version\n\
|
||
- <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi},
|
||
+ <abi> could be v1, v2, v2fp, v2fp+"), nds32_parse_abi},
|
||
{NULL, NULL, NULL}
|
||
};
|
||
|
||
static int nds32_mac = 1;
|
||
static int nds32_div = 1;
|
||
static int nds32_16bit_ext = 1;
|
||
-static int nds32_dx_regs = 1;
|
||
-static int nds32_perf_ext = 1;
|
||
-static int nds32_perf_ext2 = 1;
|
||
-static int nds32_string_ext = 1;
|
||
-static int nds32_audio_ext = 1;
|
||
+static int nds32_dx_regs = NDS32_DEFAULT_DX_REGS;
|
||
+static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT;
|
||
+static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2;
|
||
+static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT;
|
||
+static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT;
|
||
+static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT;
|
||
+static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT;
|
||
static int nds32_fpu_fma = 0;
|
||
static int nds32_pic = 0;
|
||
static int nds32_relax_fp_as_gp = 1;
|
||
@@ -1965,7 +2011,7 @@ static int nds32_relax_all = 1;
|
||
struct nds32_set_option_table
|
||
{
|
||
const char *name; /* Option string. */
|
||
- const char *help; /* Help description. */
|
||
+ const char *help; /* Help description. */
|
||
int *var; /* Variable to be set. */
|
||
int value; /* Value to set. */
|
||
};
|
||
@@ -1987,6 +2033,8 @@ static struct nds32_set_option_table toggle_opts [] =
|
||
{"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
|
||
{"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
|
||
{"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
|
||
+ {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1},
|
||
+ {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1},
|
||
{NULL, NULL, NULL, 0}
|
||
};
|
||
|
||
@@ -2000,7 +2048,7 @@ nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
|
||
char **pstr, int64_t *value);
|
||
|
||
|
||
-struct nds32_asm_desc asm_desc;
|
||
+static struct nds32_asm_desc asm_desc;
|
||
|
||
/* md_after_parse_args ()
|
||
|
||
@@ -2086,11 +2134,9 @@ nds32_start_line_hook (void)
|
||
{
|
||
}
|
||
|
||
-/*
|
||
- * Pseudo opcodes
|
||
- */
|
||
+/* Pseudo opcodes. */
|
||
|
||
-typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], unsigned int pv);
|
||
+typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], int pv);
|
||
struct nds32_pseudo_opcode
|
||
{
|
||
const char *opcode;
|
||
@@ -2183,13 +2229,12 @@ static void do_pseudo_li_internal (const char *rt, int imm32s);
|
||
static void do_pseudo_move_reg_internal (char *dst, char *src);
|
||
|
||
static void
|
||
-do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
char *arg_label = argv[0];
|
||
relaxing = TRUE;
|
||
/* b label */
|
||
- if (nds32_pic && strstr (arg_label, "@PLT"))
|
||
+ if (nds32_pic)
|
||
{
|
||
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
|
||
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
|
||
@@ -2204,18 +2249,16 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
char *arg_label = argv[0];
|
||
relaxing = TRUE;
|
||
/* bal|call label */
|
||
- if (nds32_pic
|
||
- && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
|
||
+ if (nds32_pic)
|
||
{
|
||
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
|
||
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
|
||
- md_assemble ((char *) "add $ta,$ta,$gp");
|
||
+ md_assemble ((char *) "add $ta,$ta,$gp");
|
||
md_assemble ((char *) "jral $ta");
|
||
}
|
||
else
|
||
@@ -2226,8 +2269,7 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* rt5, ra5, label */
|
||
md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
|
||
@@ -2235,8 +2277,7 @@ do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* rt5, ra5, label */
|
||
md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
|
||
@@ -2244,8 +2285,7 @@ do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* bgt rt5, ra5, label */
|
||
md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
|
||
@@ -2253,8 +2293,7 @@ do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* bgt rt5, ra5, label */
|
||
md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
|
||
@@ -2262,8 +2301,7 @@ do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* bgt rt5, ra5, label */
|
||
md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
|
||
@@ -2271,8 +2309,7 @@ do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* bgt rt5, ra5, label */
|
||
md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
|
||
@@ -2280,8 +2317,7 @@ do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* rt5, ra5, label */
|
||
md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
|
||
@@ -2289,8 +2325,7 @@ do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* rt5, ra5, label */
|
||
md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
|
||
@@ -2298,15 +2333,13 @@ do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
md_assemblef ("jr %s", argv[0]);
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_bral (int argc, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
if (argc == 1)
|
||
md_assemblef ("jral $lp,%s", argv[0]);
|
||
@@ -2329,19 +2362,24 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label,
|
||
|
||
relaxing = TRUE;
|
||
/* rt, label */
|
||
- if (!nds32_pic && !strstr(arg_label, "@"))
|
||
+ if (!nds32_pic && !strstr (arg_label, "@"))
|
||
+ {
|
||
+ md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
|
||
+ md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
|
||
+ }
|
||
+ else if (strstr (arg_label, "@ICT"))
|
||
{
|
||
md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
|
||
md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
|
||
}
|
||
else if (strstr (arg_label, "@TPOFF"))
|
||
{
|
||
- /* la $rt, sym@TPOFF */
|
||
+ /* la $rt, sym@TPOFF */
|
||
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
|
||
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
|
||
md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
|
||
}
|
||
- else if (strstr(arg_label, "@GOTTPOFF"))
|
||
+ else if (strstr (arg_label, "@GOTTPOFF"))
|
||
{
|
||
/* la $rt, sym@GOTTPOFF*/
|
||
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
|
||
@@ -2381,8 +2419,7 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label,
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
|
||
}
|
||
@@ -2404,8 +2441,7 @@ do_pseudo_li_internal (const char *rt, int imm32s)
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* Validate argv[1] for constant expression. */
|
||
expressionS exp;
|
||
@@ -2421,8 +2457,7 @@ do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv)
|
||
+do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
|
||
{
|
||
char ls = 'r';
|
||
char size = 'x';
|
||
@@ -2451,14 +2486,14 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
relaxing = TRUE;
|
||
if (strstr (argv[1], "@TPOFF"))
|
||
{
|
||
- /* ls.w $rt, sym@TPOFF */
|
||
+ /* ls.w $rt, sym@TPOFF */
|
||
md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
|
||
md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
|
||
md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
|
||
}
|
||
else if (strstr (argv[1], "@GOTTPOFF"))
|
||
{
|
||
- /* ls.w $rt, sym@GOTTPOFF */
|
||
+ /* ls.w $rt, sym@GOTTPOFF */
|
||
md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
|
||
md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
|
||
md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
|
||
@@ -2509,8 +2544,7 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv)
|
||
+do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
|
||
{
|
||
char *arg_rt = argv[0];
|
||
char *arg_label = argv[1];
|
||
@@ -2537,8 +2571,7 @@ do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv)
|
||
+do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
|
||
{
|
||
char *arg_rt = argv[0];
|
||
char *arg_inc = argv[1];
|
||
@@ -2563,8 +2596,7 @@ do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv)
|
||
+do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
|
||
{
|
||
char ls = 'r';
|
||
char size = 'x';
|
||
@@ -2597,8 +2629,7 @@ do_pseudo_move_reg_internal (char *dst, char *src)
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
expressionS exp;
|
||
|
||
@@ -2617,23 +2648,20 @@ do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* Instead of "subri". */
|
||
md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_pushpopm (int argc, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* posh/pop $ra, $rb */
|
||
/* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
|
||
@@ -2683,11 +2711,11 @@ do_pseudo_pushpopm (int argc, char *argv[],
|
||
/* Reduce register. */
|
||
if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
|
||
{
|
||
- if (re >= 15 && strstr(opc, "smw") != NULL)
|
||
+ if (re >= 15 && strstr (opc, "smw") != NULL)
|
||
md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
|
||
if (rb <= 10)
|
||
md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
|
||
- if (re >= 15 && strstr(opc, "lmw") != NULL)
|
||
+ if (re >= 15 && strstr (opc, "lmw") != NULL)
|
||
md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
|
||
}
|
||
else
|
||
@@ -2695,10 +2723,9 @@ do_pseudo_pushpopm (int argc, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_pushpop (int argc, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
- /* push/pop $ra5, $label=$sp */
|
||
+ /* push/pop $ra5, $label=$sp */
|
||
char *argvm[3];
|
||
|
||
if (argc == 2)
|
||
@@ -2712,15 +2739,13 @@ do_pseudo_pushpop (int argc, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
md_assemblef ("push25 %s,%s", argv[0], argv[1]);
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
|
||
}
|
||
@@ -2729,11 +2754,10 @@ do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
pv != 0, parsing "pop.s" pseudo instruction operands. */
|
||
|
||
static void
|
||
-do_pseudo_pushpop_stack (int argc, char *argv[],
|
||
- unsigned int pv)
|
||
+do_pseudo_pushpop_stack (int argc, char *argv[], int pv)
|
||
{
|
||
- /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
|
||
- /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
|
||
+ /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
|
||
+ /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
|
||
|
||
int rb, re;
|
||
int en4;
|
||
@@ -2794,8 +2818,7 @@ do_pseudo_pushpop_stack (int argc, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
char size = 'x';
|
||
/* If users omit push location, use $sp as default value. */
|
||
@@ -2818,7 +2841,7 @@ do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
md_assemblef ("l.%c $ta,%s", size, argv[0]);
|
||
md_assemblef ("smw.adm $ta,[%s],$ta", location);
|
||
|
||
- if ((pv & 0x3) == 0x3) /* double-word */
|
||
+ if ((pv & 0x3) == 0x3) /* double-word */
|
||
{
|
||
md_assemblef ("l.w $ta,%s+4", argv[0]);
|
||
md_assemblef ("smw.adm $ta,[%s],$ta", location);
|
||
@@ -2826,8 +2849,7 @@ do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
char size = 'x';
|
||
/* If users omit pop location, use $sp as default value. */
|
||
@@ -2847,7 +2869,7 @@ do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
location[7] = '\0';
|
||
}
|
||
|
||
- if ((pv & 0x3) == 0x3) /* double-word */
|
||
+ if ((pv & 0x3) == 0x3) /* double-word */
|
||
{
|
||
md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
|
||
md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
|
||
@@ -2858,8 +2880,7 @@ do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* If users omit push location, use $sp as default value. */
|
||
char location[8] = "$sp"; /* 8 is enough for register name. */
|
||
@@ -2875,8 +2896,7 @@ do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
}
|
||
|
||
static void
|
||
-do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
- unsigned int pv ATTRIBUTE_UNUSED)
|
||
+do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
|
||
{
|
||
/* If users omit push location, use $sp as default value. */
|
||
char location[8] = "$sp"; /* 8 is enough for register name. */
|
||
@@ -2891,8 +2911,7 @@ do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
|
||
md_assemblef ("smw.adm $ta,[%s],$ta", location);
|
||
}
|
||
|
||
-struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
|
||
-{
|
||
+static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] = {
|
||
{"b", 1, do_pseudo_b, 0, 0},
|
||
{"bal", 1, do_pseudo_bal, 0, 0},
|
||
|
||
@@ -2967,8 +2986,8 @@ struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
|
||
{"v3pop", 2, do_pseudo_v3pop, 0, 0},
|
||
|
||
/* Support pseudo instructions of pushing/poping registers into/from stack
|
||
- push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
|
||
- pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
|
||
+ push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
|
||
+ pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
|
||
{ "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
|
||
{ "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
|
||
{ "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
|
||
@@ -3009,18 +3028,16 @@ static struct nds32_pseudo_opcode *
|
||
nds32_lookup_pseudo_opcode (const char *str)
|
||
{
|
||
int i = 0;
|
||
- /* Assume pseudo-opcode are less than 16-char in length. */
|
||
- char op[16] = {0};
|
||
+ /* *op = first word of current source line (*str) */
|
||
+ int maxlen = strlen (str);
|
||
+ char *op = alloca (maxlen + 1);
|
||
|
||
- for (i = 0; i < (int)ARRAY_SIZE (op); i++)
|
||
+ for (i = 0; i < maxlen; i++)
|
||
{
|
||
if (ISSPACE (op[i] = str[i]))
|
||
break;
|
||
}
|
||
|
||
- if (i >= (int)ARRAY_SIZE (op))
|
||
- return NULL;
|
||
-
|
||
op[i] = '\0';
|
||
|
||
return hash_find (nds32_pseudo_opcode_hash, op);
|
||
@@ -3081,6 +3098,7 @@ nds32_parse_arch (const char *str)
|
||
} archs[] =
|
||
{
|
||
{"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
|
||
+ {"v3m+",ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
|
||
{"v3j", ISA_V3, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
|
||
{"v3s", ISA_V3, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
|
||
{"v3f", ISA_V3, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
|
||
@@ -3119,11 +3137,11 @@ nds32_parse_arch (const char *str)
|
||
static int
|
||
nds32_parse_baseline (const char *str)
|
||
{
|
||
- if (strcmp (str, "v3") == 0)
|
||
+ if (strcasecmp (str, "v3") == 0)
|
||
nds32_baseline = ISA_V3;
|
||
- else if (strcmp (str, "v3m") == 0)
|
||
+ else if (strcasecmp (str, "v3m") == 0)
|
||
nds32_baseline = ISA_V3M;
|
||
- else if (strcmp (str, "v2") == 0)
|
||
+ else if (strcasecmp (str, "v2") == 0)
|
||
nds32_baseline = ISA_V2;
|
||
else
|
||
{
|
||
@@ -3140,13 +3158,13 @@ nds32_parse_baseline (const char *str)
|
||
static int
|
||
nds32_parse_freg (const char *str)
|
||
{
|
||
- if (strcmp (str, "2") == 0)
|
||
+ if (strcmp (str, "2") == 0 || strcmp (str, "6") == 0)
|
||
nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
|
||
- else if (strcmp (str, "3") == 0)
|
||
+ else if (strcmp (str, "3") == 0 || strcmp (str, "7") == 0)
|
||
nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
|
||
- else if (strcmp (str, "1") == 0)
|
||
+ else if (strcmp (str, "1") == 0 || strcmp (str, "5") == 0)
|
||
nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
|
||
- else if (strcmp (str, "0") == 0)
|
||
+ else if (strcmp (str, "0") == 0 || strcmp (str, "4") == 0)
|
||
nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
|
||
else
|
||
{
|
||
@@ -3170,13 +3188,19 @@ nds32_parse_abi (const char *str)
|
||
nds32_abi = E_NDS_ABI_V2FP;
|
||
else if (strcmp (str, "v1") == 0)
|
||
nds32_abi = E_NDS_ABI_V1;
|
||
- else if (strcmp (str,"v2fpp") == 0)
|
||
+ else if (strcmp (str,"v2fpp") == 0 || strcmp (str,"v2fp+") == 0)
|
||
nds32_abi = E_NDS_ABI_V2FP_PLUS;
|
||
else
|
||
{
|
||
- /* Logic here rejects the input abi version. */
|
||
- as_bad (_("unknown ABI version`%s'\n"), str);
|
||
- return 0;
|
||
+ /* bug-10880, decided to accept any other versions but drop them. */
|
||
+ if (TRUE)
|
||
+ return 1;
|
||
+ else
|
||
+ {
|
||
+ /* Logic here rejects the input abi version. */
|
||
+ as_bad (_("unknown ABI version`%s'\n"), str);
|
||
+ return 0;
|
||
+ }
|
||
}
|
||
|
||
return 1;
|
||
@@ -3198,6 +3222,10 @@ nds32_all_ext (void)
|
||
nds32_fpu_fma = 1;
|
||
nds32_fpu_sp_ext = 1;
|
||
nds32_fpu_dp_ext = 1;
|
||
+ nds32_dsp_ext = 1;
|
||
+ nds32_zol_ext = 1;
|
||
+ /* Turn off reduced register. */
|
||
+ nds32_gpr16 = 0;
|
||
|
||
return 1;
|
||
}
|
||
@@ -3295,7 +3323,7 @@ nds32_parse_option (int c, const char *arg)
|
||
return 1;
|
||
}
|
||
|
||
-/* tc_check_label */
|
||
+/* tc_check_label */
|
||
|
||
void
|
||
nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
|
||
@@ -3342,8 +3370,7 @@ typedef struct nds32_seg_entryT
|
||
flagword flags;
|
||
} nds32_seg_entry;
|
||
|
||
-nds32_seg_entry nds32_seg_table[] =
|
||
-{
|
||
+static nds32_seg_entry nds32_seg_table[] = {
|
||
{NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
|
||
| SEC_HAS_CONTENTS | SEC_SMALL_DATA},
|
||
{NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
|
||
@@ -3409,24 +3436,40 @@ nds32_seg (int i)
|
||
}
|
||
|
||
/* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
|
||
-static symbolS *nds32_last_label; /* Last label for alignment. */
|
||
+static symbolS *nds32_last_label; /* Last label for aligment. */
|
||
+
|
||
+static void
|
||
+add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align)
|
||
+{
|
||
+ if ((shift > 1) && (addr & 1))
|
||
+ {
|
||
+ int n = (1 << shift) - 1;
|
||
+ if (!is_data_align)
|
||
+ add_mapping_symbol (MAP_CODE, 1, 0);
|
||
+ else if ((int) (addr & n) != n)
|
||
+ add_mapping_symbol (MAP_CODE, 1, 0);
|
||
+ }
|
||
+ else if ((shift > 1) && ((int) (addr & 1) == 0))
|
||
+ add_mapping_symbol (MAP_CODE, 0, 0);
|
||
|
||
-/* This code is referred from D30V for adjust label to be with pending
|
||
- alignment. For example,
|
||
+}
|
||
+
|
||
+/* This code is referred from D30V for adjust label to be with pedning
|
||
+ aligment. For example,
|
||
LBYTE: .byte 0x12
|
||
LHALF: .half 0x12
|
||
LWORD: .word 0x12
|
||
- Without this, the above label will not attach to incoming data. */
|
||
+ Without this, the above label will not attatch to incoming data. */
|
||
|
||
static void
|
||
nds32_adjust_label (int n)
|
||
{
|
||
- /* FIXME: I think adjust label and alignment is
|
||
- the programmer's obligation. Sadly, VLSI team doesn't
|
||
+ /* FIXME: I think adjust lable and alignment is
|
||
+ the programmer's obligation. Saddly, VLSI team doesn't
|
||
properly use .align for their test cases.
|
||
So I re-implement cons_align and auto adjust labels, again.
|
||
|
||
- I think d30v's implementation is simple and good enough. */
|
||
+ I think d30v's implmentation is simple and good enough. */
|
||
|
||
symbolS *label = nds32_last_label;
|
||
nds32_last_label = NULL;
|
||
@@ -3441,10 +3484,14 @@ nds32_adjust_label (int n)
|
||
/* Only frag by alignment when needed.
|
||
Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
|
||
See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
|
||
+
|
||
if (frag_now_fix () & ((1 << n) -1 ))
|
||
{
|
||
if (subseg_text_p (now_seg))
|
||
- frag_align_code (n, 0);
|
||
+ {
|
||
+ add_mapping_symbol_for_align (n, frag_now_fix (), 1);
|
||
+ frag_align_code (n, 0);
|
||
+ }
|
||
else
|
||
frag_align (n, 0, 0);
|
||
|
||
@@ -3474,7 +3521,7 @@ nds32_adjust_label (int n)
|
||
if (symbol_get_frag (sym) == old_frag
|
||
&& S_GET_VALUE (sym) == old_value)
|
||
{
|
||
- /* Warning HERE! */
|
||
+ /* Warning HERE! */
|
||
label_seen = TRUE;
|
||
symbol_set_frag (sym, frag_now);
|
||
S_SET_VALUE (sym, new_value);
|
||
@@ -3493,7 +3540,7 @@ nds32_cons_align (int size ATTRIBUTE_UNUSED)
|
||
|
||
There are two things should be done for auto-adjust-label.
|
||
1. Align data/instructions and adjust label to be attached to them.
|
||
- 2. Clear auto-adjust state, so incoming data/instructions will not
|
||
+ 2. Clear auto-adjust state, so incommng data/instructions will not
|
||
adjust the label.
|
||
|
||
For example,
|
||
@@ -3510,15 +3557,67 @@ nds32_cons_align (int size ATTRIBUTE_UNUSED)
|
||
}
|
||
|
||
static void
|
||
+make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align)
|
||
+{
|
||
+ symbolS *symbol_p = NULL;
|
||
+ const char *symbol_name = NULL;
|
||
+ switch (state)
|
||
+ {
|
||
+ case MAP_DATA:
|
||
+ if (align == 0) {
|
||
+ symbol_name = "$d0";
|
||
+ }
|
||
+ else if (align == 1) {
|
||
+ symbol_name = "$d1";
|
||
+ }
|
||
+ else if (align == 2)
|
||
+ symbol_name = "$d2";
|
||
+ else if (align == 3)
|
||
+ symbol_name = "$d3";
|
||
+ else if (align == 4)
|
||
+ symbol_name = "$d4";
|
||
+ break;
|
||
+ case MAP_CODE:
|
||
+ symbol_name = "$c";
|
||
+ break;
|
||
+ default:
|
||
+ abort ();
|
||
+ }
|
||
+
|
||
+ symbol_p = symbol_new (symbol_name, now_seg, value, frag);
|
||
+ /* local scope attribute */
|
||
+ symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL;
|
||
+}
|
||
+
|
||
+static void
|
||
+add_mapping_symbol (enum mstate state, unsigned int padding_byte, unsigned int align)
|
||
+{
|
||
+ enum mstate current_mapping_state =
|
||
+ seg_info (now_seg)->tc_segment_info_data.mapstate;
|
||
+
|
||
+ if (state == MAP_CODE && current_mapping_state == state)
|
||
+ return;
|
||
+
|
||
+ if (!SEG_NORMAL (now_seg) || !subseg_text_p (now_seg))
|
||
+ return;
|
||
+
|
||
+ /* start adding mapping symbol */
|
||
+ seg_info (now_seg)->tc_segment_info_data.mapstate = state;
|
||
+ make_mapping_symbol (state, (valueT) frag_now_fix () + padding_byte,
|
||
+ frag_now, align);
|
||
+}
|
||
+
|
||
+static void
|
||
nds32_aligned_cons (int idx)
|
||
{
|
||
nds32_adjust_label (idx);
|
||
+ add_mapping_symbol (MAP_DATA, 0, idx);
|
||
/* Call default handler. */
|
||
cons (1 << idx);
|
||
if (now_seg->flags & SEC_CODE
|
||
&& now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
|
||
{
|
||
- /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data. */
|
||
+ /* Use BFD_RELOC_NDS32_DATA to avoid linker optimization replacing data. */
|
||
expressionS exp;
|
||
|
||
exp.X_add_number = 0;
|
||
@@ -3578,7 +3677,7 @@ nds32_relax_relocs (int relax)
|
||
char *name;
|
||
int i;
|
||
const char *subtype_relax[] =
|
||
- {"", "", "ex9", "ifc"};
|
||
+ {"", "",};
|
||
|
||
name = input_line_pointer;
|
||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
||
@@ -3595,14 +3694,6 @@ nds32_relax_relocs (int relax)
|
||
case 0:
|
||
case 1:
|
||
enable_relax_relocs = relax & enable_relax_relocs;
|
||
- enable_relax_ex9 = relax & enable_relax_ex9;
|
||
- enable_relax_ifc = relax & enable_relax_ifc;
|
||
- break;
|
||
- case 2:
|
||
- enable_relax_ex9 = relax;
|
||
- break;
|
||
- case 3:
|
||
- enable_relax_ifc = relax;
|
||
break;
|
||
default:
|
||
break;
|
||
@@ -3652,51 +3743,36 @@ nds32_omit_fp_begin (int mode)
|
||
}
|
||
}
|
||
|
||
-/* Insert relocations to mark the begin and end of ex9 region,
|
||
- for further relaxation use.
|
||
- bit[i] for $ri */
|
||
-
|
||
static void
|
||
-nds32_no_ex9_begin (int mode)
|
||
+nds32_loop_begin (int mode)
|
||
{
|
||
+ /* Insert loop region relocation here. */
|
||
expressionS exp;
|
||
|
||
exp.X_op = O_symbol;
|
||
exp.X_add_symbol = abs_section_sym;
|
||
if (mode == 1)
|
||
{
|
||
- exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
|
||
+ exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
|
||
fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
|
||
BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
|
||
}
|
||
else
|
||
{
|
||
- exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
|
||
+ exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
|
||
fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
|
||
BFD_RELOC_NDS32_RELAX_REGION_END);
|
||
}
|
||
}
|
||
|
||
+/* Record if in the inline assembly code segment. */
|
||
static void
|
||
-nds32_loop_begin (int mode)
|
||
+nds32_inline_asm (int mode)
|
||
{
|
||
- /* Insert loop region relocation here. */
|
||
- expressionS exp;
|
||
-
|
||
- exp.X_op = O_symbol;
|
||
- exp.X_add_symbol = abs_section_sym;
|
||
- if (mode == 1)
|
||
- {
|
||
- exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
|
||
- fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
|
||
- BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
|
||
- }
|
||
+ if (mode)
|
||
+ inline_asm = TRUE;
|
||
else
|
||
- {
|
||
- exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
|
||
- fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
|
||
- BFD_RELOC_NDS32_RELAX_REGION_END);
|
||
- }
|
||
+ inline_asm = FALSE;
|
||
}
|
||
|
||
struct nds32_relocs_group
|
||
@@ -3706,16 +3782,49 @@ struct nds32_relocs_group
|
||
};
|
||
|
||
static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
|
||
+/* Used to reorder the id for ".relax_hint id". */
|
||
+static int relax_hint_bias = 0;
|
||
+/* Record current relax hint id. */
|
||
+static int relax_hint_id_current = -1;
|
||
+int reset_bias = 0;
|
||
+/* If ".relax_hint begin" is triggered? */
|
||
+int relax_hint_begin = 0;
|
||
+
|
||
+/* Record the reordered relax hint id. */
|
||
+
|
||
+struct relax_hint_id
|
||
+{
|
||
+ int old_id;
|
||
+ int new_id;
|
||
+ struct relax_hint_id *next;
|
||
+};
|
||
+
|
||
+/* FIXME: Need to find somewhere to free the list. */
|
||
+struct relax_hint_id *record_id_head = NULL;
|
||
+
|
||
+/* Is the buffer large enough? */
|
||
+#define MAX_BUFFER 12
|
||
+
|
||
+static char *nds_itoa (int n);
|
||
+
|
||
+static char *
|
||
+nds_itoa (int n)
|
||
+{
|
||
+ char *buf = xmalloc (MAX_BUFFER * sizeof (char));
|
||
+ snprintf (buf, MAX_BUFFER, "%d", n);
|
||
+ return buf;
|
||
+}
|
||
|
||
/* Insert a relax hint. */
|
||
|
||
static void
|
||
nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
|
||
{
|
||
- char *name;
|
||
+ char *name = NULL;
|
||
char saved_char;
|
||
struct nds32_relocs_pattern *relocs = NULL;
|
||
struct nds32_relocs_group *group, *new;
|
||
+ struct relax_hint_id *record_id;
|
||
|
||
name = input_line_pointer;
|
||
while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
||
@@ -3724,20 +3833,66 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
|
||
*input_line_pointer = 0;
|
||
name = strdup (name);
|
||
|
||
+ if (name && strcmp (name, "begin") == 0)
|
||
+ {
|
||
+ if (relax_hint_id_current == -1)
|
||
+ reset_bias = 1;
|
||
+ relax_hint_bias++;
|
||
+ relax_hint_id_current++;
|
||
+ relax_hint_begin = 1;
|
||
+ }
|
||
+
|
||
+ /* Original case ".relax_hint id". It's id may need to be reordered. */
|
||
+ if (!relax_hint_begin)
|
||
+ {
|
||
+ int tmp = strtol (name, NULL, 10);
|
||
+ record_id = record_id_head;
|
||
+ while (record_id)
|
||
+ {
|
||
+ if (record_id->old_id == tmp)
|
||
+ {
|
||
+ name = nds_itoa (record_id->new_id);
|
||
+ goto reordered_id;
|
||
+ }
|
||
+ record_id = record_id->next;
|
||
+ }
|
||
+ if (reset_bias)
|
||
+ {
|
||
+ relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
|
||
+ reset_bias = 0;
|
||
+ }
|
||
+ relax_hint_id_current = tmp + relax_hint_bias;
|
||
+
|
||
+ /* Insert the element to the head of the link list. */
|
||
+ struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
|
||
+ tmp_id->old_id = tmp;
|
||
+ tmp_id->new_id = relax_hint_id_current;
|
||
+ tmp_id->next = record_id_head;
|
||
+ record_id_head = tmp_id;
|
||
+ }
|
||
+
|
||
+ if (name && strcmp (name, "end") == 0)
|
||
+ relax_hint_begin = 0;
|
||
+ name = nds_itoa (relax_hint_id_current);
|
||
+
|
||
+reordered_id:
|
||
+
|
||
/* Find relax hint entry for next instruction, and all member will be
|
||
initialized at that time. */
|
||
relocs = hash_find (nds32_hint_hash, name);
|
||
if (relocs == NULL)
|
||
{
|
||
- relocs = XNEW (struct nds32_relocs_pattern);
|
||
+ relocs = malloc (sizeof (struct nds32_relocs_pattern));
|
||
+ memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
|
||
hash_insert (nds32_hint_hash, name, relocs);
|
||
}
|
||
else
|
||
{
|
||
while (relocs->next)
|
||
relocs=relocs->next;
|
||
- relocs->next = XNEW (struct nds32_relocs_pattern);
|
||
+ relocs->next = malloc (sizeof (struct nds32_relocs_pattern));
|
||
relocs = relocs->next;
|
||
+ memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
|
||
}
|
||
|
||
relocs->next = NULL;
|
||
@@ -3749,7 +3904,8 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
|
||
/* It has to build this list because there are maybe more than one
|
||
instructions relative to the same instruction. It to connect to
|
||
next instruction after md_assemble. */
|
||
- new = XNEW (struct nds32_relocs_group);
|
||
+ new = malloc (sizeof (struct nds32_relocs_group));
|
||
+ memset (new, 0, sizeof (struct nds32_relocs_group));
|
||
new->pattern = relocs;
|
||
new->next = NULL;
|
||
group = nds32_relax_hint_current;
|
||
@@ -3764,6 +3920,27 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
|
||
relaxing = TRUE;
|
||
}
|
||
|
||
+/* This is directive generated for compiler to estimate branch target
|
||
+ alignment. But assembler does not use the info currently. */
|
||
+
|
||
+static void
|
||
+nds32_maybe_align (int mode ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ /* Ignore the reset of line. */
|
||
+ ignore_rest_of_line ();
|
||
+}
|
||
+
|
||
+/* The end of security. It must check if there is any branch
|
||
+ between begin and end. */
|
||
+static void
|
||
+nds32_security_end (int mode ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ if (crcing == FALSE)
|
||
+ as_bad (_("Found unexpected branches inside the "
|
||
+ "signature protected region."));
|
||
+
|
||
+}
|
||
+
|
||
/* Decide the size of vector entries, only accepts 4 or 16 now. */
|
||
|
||
static void
|
||
@@ -3819,7 +3996,7 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
|
||
switch (i)
|
||
{
|
||
case 0:
|
||
- /* flag: verbatim */
|
||
+ /* flag: verbatim */
|
||
verbatim = 1;
|
||
break;
|
||
default:
|
||
@@ -3835,6 +4012,54 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
|
||
}
|
||
|
||
static void
|
||
+ict_model (int ignore ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ char *name;
|
||
+ char saved_char;
|
||
+ int i;
|
||
+ const char *possible_flags[] = { "small", "large" };
|
||
+
|
||
+ /* Skip whitespaces. */
|
||
+ name = input_line_pointer;
|
||
+ while (*input_line_pointer && !ISSPACE (*input_line_pointer))
|
||
+ input_line_pointer++;
|
||
+ saved_char = *input_line_pointer;
|
||
+ *input_line_pointer = 0;
|
||
+
|
||
+ for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
|
||
+ {
|
||
+ if (strcmp (name, possible_flags[i]) == 0)
|
||
+ {
|
||
+ switch (i)
|
||
+ {
|
||
+ case 0:
|
||
+ /* flag: verbatim */
|
||
+ ict_flag = ICT_SMALL;
|
||
+ break;
|
||
+ case 1:
|
||
+ ict_flag = ICT_LARGE;
|
||
+ break;
|
||
+ default:
|
||
+ break;
|
||
+ }
|
||
+ /* Already found the flag, no need to continue next loop. */
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ *input_line_pointer = saved_char;
|
||
+ ignore_rest_of_line ();
|
||
+}
|
||
+
|
||
+/* Create .note.v2abi_compatible section if the object is compatible with v3f/v3s.
|
||
+ Do it at the md_end(). */
|
||
+static void
|
||
+nds32_compatible_abi (int mode ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ compatible_abi = TRUE;
|
||
+}
|
||
+
|
||
+static void
|
||
nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
|
||
{
|
||
/* N1213HC core is used. */
|
||
@@ -3842,8 +4067,7 @@ nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
|
||
|
||
|
||
/* The target specific pseudo-ops which we support. */
|
||
-const pseudo_typeS md_pseudo_table[] =
|
||
-{
|
||
+const pseudo_typeS md_pseudo_table[] = {
|
||
/* Forced alignment if declared these ways. */
|
||
{"ascii", stringer, 8 + 0},
|
||
{"asciz", stringer, 8 + 1},
|
||
@@ -3894,13 +4118,17 @@ const pseudo_typeS md_pseudo_table[] =
|
||
{"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon?? */
|
||
{"omit_fp_begin", nds32_omit_fp_begin, 1},
|
||
{"omit_fp_end", nds32_omit_fp_begin, 0},
|
||
- {"no_ex9_begin", nds32_no_ex9_begin, 1},
|
||
- {"no_ex9_end", nds32_no_ex9_begin, 0},
|
||
{"vec_size", nds32_vec_size, 0},
|
||
{"flag", nds32_flag, 0},
|
||
{"innermost_loop_begin", nds32_loop_begin, 1},
|
||
{"innermost_loop_end", nds32_loop_begin, 0},
|
||
{"relax_hint", nds32_relax_hint, 0},
|
||
+ {"maybe_align", nds32_maybe_align, 0},
|
||
+ {"signature_end", nds32_security_end, 0},
|
||
+ {"inline_asm_begin", nds32_inline_asm, 1},
|
||
+ {"inline_asm_end", nds32_inline_asm, 0},
|
||
+ {"ict_model", ict_model, 0},
|
||
+ {"v2abi_compatible", nds32_compatible_abi, 0},
|
||
{NULL, NULL, 0}
|
||
};
|
||
|
||
@@ -3917,9 +4145,10 @@ nds32_pre_do_align (int n, char *fill, int len, int max)
|
||
{
|
||
dwarf2_emit_insn (0);
|
||
fragP = frag_now;
|
||
+ add_mapping_symbol_for_align (n, frag_now_fix (), 0);
|
||
frag_align_code (n, max);
|
||
|
||
- /* Tag this alignment when there is a label before it. */
|
||
+ /* Tag this alignment when there is a lable before it. */
|
||
if (label_exist)
|
||
{
|
||
fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
|
||
@@ -4003,24 +4232,26 @@ void
|
||
md_begin (void)
|
||
{
|
||
struct nds32_keyword *k;
|
||
- unsigned int i;
|
||
+ relax_info_t *relax_info;
|
||
+ int flags = 0;
|
||
|
||
bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
|
||
|
||
nds32_init_nds32_pseudo_opcodes ();
|
||
asm_desc.parse_operand = nds32_asm_parse_operand;
|
||
- nds32_asm_init (&asm_desc, 0);
|
||
+ if (nds32_gpr16)
|
||
+ flags |= NASM_OPEN_REDUCED_REG;
|
||
+ nds32_asm_init (&asm_desc, flags);
|
||
|
||
- /* Initial general purpose registers hash table. */
|
||
+ /* Initial general pupose registers hash table. */
|
||
nds32_gprs_hash = hash_new ();
|
||
for (k = keyword_gpr; k->name; k++)
|
||
hash_insert (nds32_gprs_hash, k->name, k);
|
||
|
||
/* Initial branch hash table. */
|
||
nds32_relax_info_hash = hash_new ();
|
||
- for (i = 0; i < ARRAY_SIZE (relax_table); i++)
|
||
- hash_insert (nds32_relax_info_hash, relax_table[i].opcode,
|
||
- &relax_table[i]);
|
||
+ for (relax_info = relax_table; relax_info->opcode; relax_info++)
|
||
+ hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
|
||
|
||
/* Initial relax hint hash table. */
|
||
nds32_hint_hash = hash_new ();
|
||
@@ -4138,13 +4369,14 @@ get_range_type (const struct nds32_field *field)
|
||
/* Save pseudo instruction relocation list. */
|
||
|
||
static struct nds32_relocs_pattern*
|
||
-nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
|
||
+nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
|
||
char *out, symbolS *sym,
|
||
struct nds32_relocs_pattern *reloc_ptr,
|
||
fragS *fragP)
|
||
{
|
||
+ struct nds32_opcode *opcode = insn->opcode;
|
||
if (!reloc_ptr)
|
||
- reloc_ptr = XNEW (struct nds32_relocs_pattern);
|
||
+ reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern));
|
||
reloc_ptr->seg = now_seg;
|
||
reloc_ptr->sym = sym;
|
||
reloc_ptr->frag = fragP;
|
||
@@ -4152,6 +4384,7 @@ nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
|
||
reloc_ptr->fixP = fixP;
|
||
reloc_ptr->opcode = opcode;
|
||
reloc_ptr->where = out;
|
||
+ reloc_ptr->insn = insn->insn;
|
||
reloc_ptr->next = NULL;
|
||
return reloc_ptr;
|
||
}
|
||
@@ -4193,10 +4426,21 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
|
||
break;
|
||
case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
|
||
- reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
|
||
+ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
|
||
+ break;
|
||
+ case BFD_RELOC_NDS32_TLS_DESC: /* @TLSDESC */
|
||
+ reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
|
||
+ break;
|
||
+ case BFD_RELOC_NDS32_ICT:
|
||
+ reloc = BFD_RELOC_NDS32_ICT_HI20;
|
||
break;
|
||
default: /* No suffix. */
|
||
- reloc = BFD_RELOC_NDS32_HI20;
|
||
+ if (nds32_pic)
|
||
+ /* When the file is pic, the address must be offset to gp.
|
||
+ It may define another relocation or use GOTOFF. */
|
||
+ reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
|
||
+ else
|
||
+ reloc = BFD_RELOC_NDS32_HI20;
|
||
break;
|
||
}
|
||
fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
@@ -4228,8 +4472,22 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
|
||
reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
|
||
break;
|
||
+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
|
||
+ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
|
||
+ break;
|
||
+ case BFD_RELOC_NDS32_TLS_DESC: /* @TLSDESC */
|
||
+ reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
|
||
+ break;
|
||
+ case BFD_RELOC_NDS32_ICT:
|
||
+ reloc = BFD_RELOC_NDS32_ICT_LO12;
|
||
+ break;
|
||
default: /* No suffix. */
|
||
- reloc = BFD_RELOC_NDS32_LO12S0;
|
||
+ if (nds32_pic)
|
||
+ /* When the file is pic, the address must be offset to gp.
|
||
+ It may define another relocation or use GOTOFF. */
|
||
+ reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
|
||
+ else
|
||
+ reloc = BFD_RELOC_NDS32_LO12S0;
|
||
break;
|
||
}
|
||
}
|
||
@@ -4237,11 +4495,14 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */
|
||
else if (fld->bitsize == 15 && fld->shift == 2)
|
||
{
|
||
- /* [ls]wi */
|
||
+ /* [ls]wi */
|
||
switch (pexp->X_md)
|
||
{
|
||
case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
|
||
- reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
|
||
+ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
|
||
+ break;
|
||
+ case BFD_RELOC_NDS32_ICT:
|
||
+ reloc = BFD_RELOC_NDS32_ICT_LO12S2;
|
||
break;
|
||
default: /* No suffix. */
|
||
reloc = BFD_RELOC_NDS32_LO12S2;
|
||
@@ -4251,7 +4512,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
else if (fld->bitsize == 15 && fld->shift == 3)
|
||
reloc = BFD_RELOC_NDS32_LO12S3; /* [ls]di */
|
||
else if (fld->bitsize == 12 && fld->shift == 2)
|
||
- reloc = R_NDS32_LO12S2_SP_RELA; /* f[ls][sd]i */
|
||
+ reloc = BFD_RELOC_NDS32_LO12S2_SP; /* f[ls][sd]i */
|
||
|
||
fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
insn->info, 0 /* pcrel */, reloc);
|
||
@@ -4261,7 +4522,12 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
{
|
||
/* Relocation for 32-bit branch instructions. */
|
||
if (fld->bitsize == 24 && fld->shift == 1)
|
||
- reloc = BFD_RELOC_NDS32_25_PCREL;
|
||
+ {
|
||
+ if (pexp->X_md == BFD_RELOC_NDS32_ICT)
|
||
+ reloc = BFD_RELOC_NDS32_ICT_25PC;
|
||
+ else
|
||
+ reloc = BFD_RELOC_NDS32_25_PCREL;
|
||
+ }
|
||
else if (fld->bitsize == 16 && fld->shift == 1)
|
||
reloc = BFD_RELOC_NDS32_17_PCREL;
|
||
else if (fld->bitsize == 14 && fld->shift == 1)
|
||
@@ -4272,7 +4538,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
abort ();
|
||
|
||
fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
- insn->info, 1 /* pcrel */, reloc);
|
||
+ insn->info, 1 /* pcrel */, reloc);
|
||
}
|
||
else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
|
||
&& (insn->attr & NASM_ATTR_GPREL))
|
||
@@ -4288,7 +4554,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
abort ();
|
||
|
||
fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
- insn->info, 0 /* pcrel */, reloc);
|
||
+ insn->info, 0 /* pcrel */, reloc);
|
||
/* Insert INSN16 for converting fp_as_gp. */
|
||
exp.X_op = O_symbol;
|
||
exp.X_add_symbol = abs_section_sym;
|
||
@@ -4310,20 +4576,6 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
insn->info, 1 /* pcrel */, reloc);
|
||
}
|
||
- else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
|
||
- {
|
||
- /* Relocation for ifcall instruction. */
|
||
- if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
|
||
- reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
|
||
- else if (insn->opcode->isize == 4 && fld->bitsize == 16
|
||
- && fld->shift == 1)
|
||
- reloc = BFD_RELOC_NDS32_17IFC_PCREL;
|
||
- else
|
||
- abort ();
|
||
-
|
||
- fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
- insn->info, 1 /* pcrel */, reloc);
|
||
- }
|
||
else if (fld)
|
||
as_bad (_("Don't know how to handle this field. %s"), str);
|
||
|
||
@@ -4335,8 +4587,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
|
||
|
||
static void
|
||
nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
|
||
- struct nds32_opcode *opcode, fragS *fragP,
|
||
- const struct nds32_field *fld)
|
||
+ struct nds32_asm_insn *insn, fragS *fragP,
|
||
+ const struct nds32_field *fld,
|
||
+ bfd_boolean pseudo_hint)
|
||
{
|
||
struct nds32_relocs_pattern *reloc_ptr;
|
||
struct nds32_relocs_group *group;
|
||
@@ -4346,10 +4599,32 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
|
||
if (fld)
|
||
sym = pexp->X_add_symbol;
|
||
|
||
- if (pseudo_opcode)
|
||
+ if (pseudo_hint)
|
||
+ {
|
||
+ /* We cannot know how many instructions will be expanded for
|
||
+ the pseudo instruction here. The first expanded instruction fills
|
||
+ the memory created by relax_hint. The follower will created and link
|
||
+ here. */
|
||
+ group = nds32_relax_hint_current;
|
||
+ while (group)
|
||
+ {
|
||
+ if (group->pattern->opcode == NULL)
|
||
+ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
|
||
+ group->pattern, fragP);
|
||
+ else
|
||
+ {
|
||
+ group->pattern->next =
|
||
+ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
|
||
+ NULL, fragP);
|
||
+ group->pattern = group->pattern->next;
|
||
+ }
|
||
+ group = group->next;
|
||
+ }
|
||
+ }
|
||
+ else if (pseudo_opcode)
|
||
{
|
||
/* Save instruction relation for pseudo instruction expanding pattern. */
|
||
- reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
|
||
+ reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
|
||
NULL, fragP);
|
||
if (!relocs_list)
|
||
relocs_list = reloc_ptr;
|
||
@@ -4367,7 +4642,7 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
|
||
group = nds32_relax_hint_current;
|
||
while (group)
|
||
{
|
||
- nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
|
||
+ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
|
||
group->pattern, fragP);
|
||
group = group->next;
|
||
free (nds32_relax_hint_current);
|
||
@@ -4383,40 +4658,214 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
|
||
#define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
|
||
|
||
/* Relax pattern for link time relaxation. */
|
||
+/* relaxation types only! relocation types are not necessary */
|
||
+/* refer to nds32_elf_record_fixup_exp() */
|
||
|
||
static struct nds32_relax_hint_table relax_ls_table[] =
|
||
{
|
||
{
|
||
- /* Set address: la -> sethi ori. */
|
||
- NDS32_RELAX_HINT_LA, /* main_type */
|
||
- 8, /* relax_code_size */
|
||
- {
|
||
- OP6 (SETHI),
|
||
- OP6 (ORI),
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
- {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
|
||
- } /* relax_fixup */
|
||
+ /* For bug-12566, LA and Floating LSI. */
|
||
+ .main_type = NDS32_RELAX_HINT_LA_FLSI,
|
||
+ .relax_code_size = 12,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (LBI),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
|
||
+ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
},
|
||
{
|
||
- /* Set address: l.w -> sethi ori. */
|
||
- NDS32_RELAX_HINT_LS, /* main_type */
|
||
- 8, /* relax_code_size */
|
||
- {
|
||
- OP6 (SETHI),
|
||
- OP6 (LBI),
|
||
- }, /* relax_code_seq */
|
||
- {
|
||
- {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
- {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
|
||
- } /* relax_fixup */
|
||
+ /* Load Address / Load-Store (LALS). */
|
||
+ .main_type = NDS32_RELAX_HINT_LALS,
|
||
+ .relax_code_size = 12,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (LBI),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
},
|
||
{
|
||
- 0,
|
||
- 0,
|
||
- {0},
|
||
- {{0, 0 , 0, 0}}
|
||
+ /* B(AL) symbol@PLT */
|
||
+ .main_type = NDS32_RELAX_HINT_LA_PLT,
|
||
+ .relax_code_size = 16,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (ALU1),
|
||
+ OP6 (JREG),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
|
||
+ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
|
||
+ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* LA (@GOT). */
|
||
+ .main_type = NDS32_RELAX_HINT_LA_GOT,
|
||
+ .relax_code_size = 12,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (MEM),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* LA (@GOTOFF). */
|
||
+ .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
|
||
+ .relax_code_size = 16,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (ALU1),
|
||
+ OP6 (MEM),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
|
||
+ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* TLS LE LS|LA */
|
||
+ .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
|
||
+ .relax_code_size = 16,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6(SETHI),
|
||
+ OP6(ORI),
|
||
+ OP6(MEM),
|
||
+ OP6(ALU1),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
|
||
+ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* TLS IE LA */
|
||
+ .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
|
||
+ .relax_code_size = 8,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6(SETHI),
|
||
+ OP6(LBI),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* TLS IEGP LA */
|
||
+ .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
|
||
+ .relax_code_size = 12,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (MEM),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* TLS DESC LS: */
|
||
+ .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
|
||
+ .relax_code_size = 24,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ OP6 (ALU1),
|
||
+ OP6 (LBI), /* load argument */
|
||
+ OP6 (JREG),
|
||
+ OP6 (MEM), /* load/store variable or load argument */
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
|
||
+ {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
|
||
+ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
|
||
+ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
|
||
+ {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
|
||
+ {16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
|
||
+ {20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ /* Load Address of ICT. */
|
||
+ .main_type = NDS32_RELAX_HINT_ICT_LA,
|
||
+ .relax_code_size = 8,
|
||
+ .relax_code_seq =
|
||
+ {
|
||
+ OP6 (SETHI),
|
||
+ OP6 (ORI),
|
||
+ },
|
||
+ .relax_fixup =
|
||
+ {
|
||
+ /* TODO: insert relocations to do relax. */
|
||
+ {0, 0, 0, 0}
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ .main_type = 0,
|
||
+ .relax_code_seq = {0},
|
||
+ .relax_fixup = {{0, 0 , 0, 0}}
|
||
}
|
||
};
|
||
|
||
@@ -4481,118 +4930,189 @@ nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
|
||
(((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
|
||
| ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
|
||
|
||
+#define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
|
||
static void
|
||
nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
|
||
{
|
||
- /* Set E_NDS32_HAS_EXT_INST. */
|
||
- if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
|
||
- {
|
||
- if (nds32_perf_ext)
|
||
- nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling performance extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
|
||
- {
|
||
- if (nds32_perf_ext2)
|
||
- nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling performance extension II"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
|
||
- {
|
||
- if (nds32_audio_ext)
|
||
- nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling AUDIO extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
|
||
- {
|
||
- if (nds32_string_ext)
|
||
- nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling STRING extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if ((insn->opcode->attr & NASM_ATTR_DIV)
|
||
- && (insn->opcode->attr & NASM_ATTR_DXREG))
|
||
- {
|
||
- if (nds32_div && nds32_dx_regs)
|
||
- nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_FPU)
|
||
- {
|
||
- if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
|
||
- {
|
||
- if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
|
||
- nds32_fpu_com = 1;
|
||
- }
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling FPU extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
|
||
- {
|
||
- if (nds32_fpu_sp_ext)
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling FPU_SP extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
|
||
- && (insn->opcode->attr & NASM_ATTR_MAC))
|
||
- {
|
||
- if (nds32_fpu_sp_ext && nds32_mac)
|
||
- {
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
|
||
- }
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling FPU_MAC extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
|
||
- {
|
||
- if (nds32_fpu_dp_ext)
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling FPU_DP extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
|
||
- && (insn->opcode->attr & NASM_ATTR_MAC))
|
||
+ static int skip_flags = NASM_ATTR_EX9_EXT | NASM_ATTR_FPU_FMA
|
||
+ | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT | NASM_ATTR_GPREL
|
||
+ | NASM_ATTR_DXREG | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2 | NASM_ATTR_ISA_V3
|
||
+ | NASM_ATTR_ISA_V3M | NASM_ATTR_PCREL;
|
||
+
|
||
+ int new_flags = insn->opcode->attr & ~skip_flags;
|
||
+ while (new_flags)
|
||
{
|
||
- if (nds32_fpu_dp_ext && nds32_mac)
|
||
+ int next = 1 << (ffs (new_flags) - 1);
|
||
+ new_flags &= ~next;
|
||
+ switch (next)
|
||
{
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
|
||
- nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
|
||
+ case NASM_ATTR_PERF_EXT:
|
||
+ {
|
||
+ if (nds32_perf_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
|
||
+ skip_flags |= NASM_ATTR_PERF_EXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling performance "
|
||
+ "extension"), insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_PERF2_EXT:
|
||
+ {
|
||
+ if (nds32_perf_ext2)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
|
||
+ skip_flags |= NASM_ATTR_PERF2_EXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling performance "
|
||
+ "extension II"), insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_AUDIO_ISAEXT:
|
||
+ {
|
||
+ if (nds32_audio_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
|
||
+ skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling AUDIO extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_STR_EXT:
|
||
+ {
|
||
+ if (nds32_string_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
|
||
+ skip_flags |= NASM_ATTR_STR_EXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling STRING extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_DIV:
|
||
+ {
|
||
+ if (insn->opcode->attr & NASM_ATTR_DXREG)
|
||
+ {
|
||
+ if (nds32_div && nds32_dx_regs)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
|
||
+ skip_flags |= NASM_ATTR_DIV;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling DIV & DX_REGS "
|
||
+ "extension"), insn->opcode->opcode);
|
||
+ }
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_FPU:
|
||
+ {
|
||
+ if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
|
||
+ {
|
||
+ if (!(nds32_elf_flags
|
||
+ & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
|
||
+ nds32_fpu_com = 1;
|
||
+ skip_flags |= NASM_ATTR_FPU;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling FPU extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_FPU_SP_EXT:
|
||
+ {
|
||
+ if (nds32_fpu_sp_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
|
||
+ skip_flags |= NASM_ATTR_FPU_SP_EXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling FPU_SP extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_FPU_DP_EXT:
|
||
+ {
|
||
+ if (nds32_fpu_dp_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
|
||
+ skip_flags |= NASM_ATTR_FPU_DP_EXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling FPU_DP extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_MAC:
|
||
+ {
|
||
+ if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
|
||
+ {
|
||
+ if (nds32_fpu_sp_ext && nds32_mac)
|
||
+ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling FPU_MAC "
|
||
+ "extension"), insn->opcode->opcode);
|
||
+ }
|
||
+ else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
|
||
+ {
|
||
+ if (nds32_fpu_dp_ext && nds32_mac)
|
||
+ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling FPU_MAC "
|
||
+ "extension"), insn->opcode->opcode);
|
||
+ }
|
||
+ else if (insn->opcode->attr & NASM_ATTR_DXREG)
|
||
+ {
|
||
+ if (nds32_dx_regs && nds32_mac)
|
||
+ nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling DX_REGS "
|
||
+ "extension"), insn->opcode->opcode);
|
||
+ }
|
||
+
|
||
+ if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
|
||
+ skip_flags |= NASM_ATTR_MAC;
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_IFC_EXT:
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
|
||
+ skip_flags |= NASM_ATTR_IFC_EXT;
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_DSP_ISAEXT:
|
||
+ {
|
||
+ if (nds32_dsp_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
|
||
+ skip_flags |= NASM_ATTR_DSP_ISAEXT;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling dsp extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ case NASM_ATTR_ZOL:
|
||
+ {
|
||
+ if (nds32_zol_ext)
|
||
+ {
|
||
+ nds32_elf_flags |= E_NDS32_HAS_ZOL;
|
||
+ skip_flags |= NASM_ATTR_ZOL;
|
||
+ }
|
||
+ else
|
||
+ as_bad (_("instruction %s requires enabling zol extension"),
|
||
+ insn->opcode->opcode);
|
||
+ }
|
||
+ break;
|
||
+ default:
|
||
+ as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
|
||
+ next);
|
||
}
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling FPU_MAC extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- /* TODO: FPU_BOTH */
|
||
- else if ((insn->opcode->attr & NASM_ATTR_MAC)
|
||
- && (insn->opcode->attr & NASM_ATTR_DXREG))
|
||
- {
|
||
- if (nds32_mac && nds32_dx_regs)
|
||
- nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
|
||
- else
|
||
- as_bad (_("instruction %s requires enabling DX_REGS extension"),
|
||
- insn->opcode->opcode);
|
||
- }
|
||
- /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
|
||
- else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
|
||
- {
|
||
- nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
|
||
}
|
||
- /* TODO: E_NDS32_HAS_SATURATION_INST */
|
||
}
|
||
|
||
/* Flag for analysis relaxation type. */
|
||
@@ -4607,100 +5127,212 @@ enum nds32_insn_type
|
||
N32_RELAX_ORI = (1 << 5),
|
||
N32_RELAX_MEM = (1 << 6),
|
||
N32_RELAX_MOVI = (1 << 7),
|
||
+ N32_RELAX_ALU1 = (1 << 8),
|
||
+ N32_RELAX_16BIT = (1 << 9),
|
||
};
|
||
|
||
struct nds32_hint_map
|
||
{
|
||
+ /* the preamble relocation */
|
||
bfd_reloc_code_real_type hi_type;
|
||
+ /* mnemonic */
|
||
const char *opc;
|
||
+ /* relax pattern ID */
|
||
enum nds32_relax_hint_type hint_type;
|
||
+ /* range */
|
||
enum nds32_br_range range;
|
||
+ /* pattern character flags */
|
||
enum nds32_insn_type insn_list;
|
||
+ /* optional pattern character flags */
|
||
+ enum nds32_insn_type option_list;
|
||
};
|
||
|
||
/* Table to match instructions with hint and relax pattern. */
|
||
|
||
static struct nds32_hint_map hint_map [] =
|
||
{
|
||
- {
|
||
- /* LONGCALL4. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- "jal",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
|
||
- },
|
||
- {
|
||
- /* LONGCALL5. */
|
||
- _dummy_first_bfd_reloc_code_real,
|
||
- "bgezal",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_S16M,
|
||
- N32_RELAX_BR | N32_RELAX_CALL
|
||
- },
|
||
- {
|
||
- /* LONGCALL6. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- "bgezal",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
|
||
- },
|
||
- {
|
||
- /* LONGJUMP4. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- "j",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
|
||
- },
|
||
- {
|
||
- /* LONGJUMP5. */
|
||
- /* There is two kinds of variations of LONGJUMP5. One of them
|
||
- generate EMPTY relocation for converted INSN16 if needed.
|
||
- But we don't distinguish them here. */
|
||
- _dummy_first_bfd_reloc_code_real,
|
||
- "beq",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_S16M,
|
||
- N32_RELAX_BR | N32_RELAX_JUMP
|
||
- },
|
||
- {
|
||
- /* LONGJUMP6. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- "beq",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
|
||
- },
|
||
- {
|
||
- /* LONGJUMP7. */
|
||
- _dummy_first_bfd_reloc_code_real,
|
||
- "beqc",
|
||
- NDS32_RELAX_HINT_NONE,
|
||
- BR_RANGE_S16K,
|
||
- N32_RELAX_MOVI | N32_RELAX_BR
|
||
- },
|
||
- {
|
||
- /* LOADSTORE ADDRESS. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- NULL,
|
||
- NDS32_RELAX_HINT_LA,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_SETHI | N32_RELAX_ORI
|
||
- },
|
||
- {
|
||
- /* LOADSTORE ADDRESS. */
|
||
- BFD_RELOC_NDS32_HI20,
|
||
- NULL,
|
||
- NDS32_RELAX_HINT_LS,
|
||
- BR_RANGE_U4G,
|
||
- N32_RELAX_SETHI | N32_RELAX_LSI
|
||
- },
|
||
- {0, NULL, 0, 0 ,0}
|
||
+ {
|
||
+ /* LONGCALL4. */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ "jal",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGCALL5. */
|
||
+ _dummy_first_bfd_reloc_code_real,
|
||
+ "bgezal",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_S16M,
|
||
+ N32_RELAX_BR | N32_RELAX_CALL,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGCALL6. */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ "bgezal",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGJUMP4. */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ "j",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGJUMP5. */
|
||
+ /* There is two kinds of variation of LONGJUMP5. One of them
|
||
+ generate EMPTY relocation for converted INSN16 if needed.
|
||
+ But we don't distinguish them here. */
|
||
+ _dummy_first_bfd_reloc_code_real,
|
||
+ "beq",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_S16M,
|
||
+ N32_RELAX_BR | N32_RELAX_JUMP,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGJUMP6. */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ "beq",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGJUMP7. */
|
||
+ _dummy_first_bfd_reloc_code_real,
|
||
+ "beqc",
|
||
+ NDS32_RELAX_HINT_NONE,
|
||
+ BR_RANGE_S16K,
|
||
+ N32_RELAX_MOVI | N32_RELAX_BR,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* LONGCALL (BAL|JR|LA symbol@PLT). */
|
||
+ BFD_RELOC_NDS32_PLT_GOTREL_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LA_PLT,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
|
||
+ },
|
||
+ /* relative issue: #12566 */
|
||
+ {
|
||
+ /* LA and Floating LSI. */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LA_FLSI,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
|
||
+ 0,
|
||
+ },
|
||
+ /* relative issue: #11685 #11602 */
|
||
+ {
|
||
+ /* load address / load-store (LALS). */
|
||
+ BFD_RELOC_NDS32_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LALS,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI,
|
||
+ N32_RELAX_ORI | N32_RELAX_LSI,
|
||
+ },
|
||
+ {
|
||
+ /* setup $GP (_GLOBAL_OFFSET_TABLE_) */
|
||
+ BFD_RELOC_NDS32_GOTPC_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LALS,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* GOT LA/LS (symbol@GOT) */
|
||
+ BFD_RELOC_NDS32_GOT_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LA_GOT,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ N32_RELAX_MEM,
|
||
+ },
|
||
+ {
|
||
+ /* GOTOFF LA/LS (symbol@GOTOFF) */
|
||
+ BFD_RELOC_NDS32_GOTOFF_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_LA_GOTOFF,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ N32_RELAX_ALU1 | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
|
||
+ },
|
||
+ {
|
||
+ /* TLS LE LA|LS (@TPOFF) */
|
||
+ BFD_RELOC_NDS32_TLS_LE_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_TLS_LE_LS,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ N32_RELAX_ALU1 | N32_RELAX_MEM,
|
||
+ },
|
||
+ {
|
||
+ /* TLS IE LA */
|
||
+ BFD_RELOC_NDS32_TLS_IE_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_TLS_IE_LA,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_LSI,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* TLS IE LS */
|
||
+ BFD_RELOC_NDS32_TLS_IE_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_TLS_IE_LS,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* TLS IEGP LA */
|
||
+ BFD_RELOC_NDS32_TLS_IEGP_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_TLS_IEGP_LA,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
|
||
+ 0,
|
||
+ },
|
||
+ {
|
||
+ /* TLS DESC LS */
|
||
+ BFD_RELOC_NDS32_TLS_DESC_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_TLS_DESC_LS,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
|
||
+ N32_RELAX_LSI | N32_RELAX_MEM,
|
||
+ },
|
||
+ {
|
||
+ /* Jump-patch load address (LA). */
|
||
+ BFD_RELOC_NDS32_ICT_HI20,
|
||
+ NULL,
|
||
+ NDS32_RELAX_HINT_ICT_LA,
|
||
+ BR_RANGE_U4G,
|
||
+ N32_RELAX_SETHI | N32_RELAX_ORI,
|
||
+ 0,
|
||
+ },
|
||
+ /* last one */
|
||
+ {0, NULL, 0, 0 ,0, 0}
|
||
};
|
||
|
||
/* Find the relaxation pattern according to instructions. */
|
||
+/* TODO: refine this function with hash or so */
|
||
|
||
static bfd_boolean
|
||
nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
@@ -4739,6 +5371,9 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
case N32_OP6_MEM:
|
||
relax_type |= N32_RELAX_MEM;
|
||
break;
|
||
+ case N32_OP6_ALU1:
|
||
+ relax_type |= N32_RELAX_ALU1;
|
||
+ break;
|
||
case N32_OP6_ORI:
|
||
relax_type |= N32_RELAX_ORI;
|
||
break;
|
||
@@ -4760,6 +5395,8 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
case N32_OP6_SWI:
|
||
case N32_OP6_LWC:
|
||
case N32_OP6_SWC:
|
||
+ case N32_OP6_LDC:
|
||
+ case N32_OP6_SDC:
|
||
relax_type |= N32_RELAX_LSI;
|
||
break;
|
||
case N32_OP6_JREG:
|
||
@@ -4784,16 +5421,20 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
{
|
||
/* 2 byte instruction. Compare by opcode name because the opcode of
|
||
2byte instruction is not regular. */
|
||
- for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
|
||
+ int is_matched = 0;
|
||
+ for (i = 0; i < ARRAY_SIZE (check_insn); i++)
|
||
{
|
||
if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
|
||
{
|
||
relax_type |= N32_RELAX_BR;
|
||
+ is_matched += 1;
|
||
break;
|
||
}
|
||
}
|
||
- if (strcmp (pattern->opcode->opcode, "movi55") == 0)
|
||
- relax_type |= N32_RELAX_MOVI;
|
||
+ if (!is_matched)
|
||
+ {
|
||
+ relax_type |= N32_RELAX_16BIT;
|
||
+ }
|
||
}
|
||
pattern = pattern->next;
|
||
}
|
||
@@ -4801,23 +5442,35 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
/* Analysis instruction flag to choose relaxation table. */
|
||
while (map_ptr->insn_list != 0)
|
||
{
|
||
- if (map_ptr->insn_list == relax_type
|
||
- && (!hi_pattern
|
||
- || (hi_pattern->fixP
|
||
- && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
|
||
+ struct nds32_hint_map *hint = map_ptr++;
|
||
+ enum nds32_insn_type must = hint->insn_list;
|
||
+ enum nds32_insn_type optional = hint->option_list;
|
||
+ enum nds32_insn_type extra;
|
||
+
|
||
+ if (must != (must & relax_type))
|
||
+ continue;
|
||
+
|
||
+ extra = relax_type ^ must;
|
||
+ if (extra != (extra & optional))
|
||
+ continue;
|
||
+
|
||
+ if (!hi_pattern
|
||
+ || (hi_pattern->fixP
|
||
+ && hi_pattern->fixP->fx_r_type == hint->hi_type))
|
||
{
|
||
- opc = map_ptr->opc;
|
||
- hint_type = map_ptr->hint_type;
|
||
- range = map_ptr->range;
|
||
+ opc = hint->opc;
|
||
+ hint_type = hint->hint_type;
|
||
+ range = hint->range;
|
||
+ map_ptr = hint;
|
||
break;
|
||
}
|
||
- map_ptr++;
|
||
}
|
||
|
||
if (map_ptr->insn_list == 0)
|
||
{
|
||
- as_warn (_("Can not find match relax hint. Line: %d"),
|
||
- relocs_pattern->frag->fr_line);
|
||
+ if (!nds32_pic)
|
||
+ as_warn (_("Can not find match relax hint. line : %d"),
|
||
+ relocs_pattern->fixP->fx_line);
|
||
return FALSE;
|
||
}
|
||
|
||
@@ -4876,12 +5529,14 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
|
||
/* Because there are a lot of variant of load-store, check
|
||
all these type here. */
|
||
|
||
-#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
|
||
+#define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
|
||
+#define GET_OPCODE(insn) ((insn) & 0xfe000000)
|
||
+
|
||
static bfd_boolean
|
||
nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
|
||
{
|
||
const char *check_insn[] =
|
||
- { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
|
||
+ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
|
||
uint32_t insn = opcode->value;
|
||
unsigned int i;
|
||
|
||
@@ -4897,22 +5552,23 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
|
||
if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
|
||
|| insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
|
||
|| insn == OP6 (LWI) || insn == OP6 (SWI)
|
||
- || insn == OP6 (LWC) || insn == OP6 (SWC))
|
||
- return TRUE;
|
||
+ || insn == OP6 (LWC) || insn == OP6 (SWC)
|
||
+ || insn == OP6 (LDC) || insn == OP6 (SDC))
|
||
+ return TRUE;
|
||
break;
|
||
case OP6 (BR2):
|
||
/* This is for LONGCALL5 and LONGCALL6. */
|
||
if (insn == OP6 (BR2))
|
||
- return TRUE;
|
||
+ return TRUE;
|
||
break;
|
||
case OP6 (BR1):
|
||
/* This is for LONGJUMP5 and LONGJUMP6. */
|
||
if (opcode->isize == 4
|
||
&& (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
|
||
- return TRUE;
|
||
+ return TRUE;
|
||
else if (opcode->isize == 2)
|
||
{
|
||
- for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
|
||
+ for (i = 0; i < ARRAY_SIZE (check_insn); i++)
|
||
if (strcmp (opcode->opcode, check_insn[i]) == 0)
|
||
return TRUE;
|
||
}
|
||
@@ -4920,8 +5576,28 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
|
||
case OP6 (MOVI):
|
||
/* This is for LONGJUMP7. */
|
||
if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
|
||
- return TRUE;
|
||
+ return TRUE;
|
||
+ break;
|
||
+ case OP6 (MEM):
|
||
+ if (OP6 (MEM) == GET_OPCODE (insn))
|
||
+ return TRUE;
|
||
break;
|
||
+ case OP6 (JREG):
|
||
+ /* bit 24: N32_JI_JAL */ /* feed me! */
|
||
+ if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
|
||
+ return TRUE;
|
||
+ break;
|
||
+ default:
|
||
+ if (opcode->isize == 2)
|
||
+ {
|
||
+ for (i = 0; i < ARRAY_SIZE (check_insn); i++)
|
||
+ if (strcmp (opcode->opcode, check_insn[i]) == 0)
|
||
+ return TRUE;
|
||
+
|
||
+ if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
|
||
+ (strcmp (opcode->opcode, "add45") == 0))
|
||
+ return TRUE;
|
||
+ }
|
||
}
|
||
return FALSE;
|
||
}
|
||
@@ -4929,7 +5605,7 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
|
||
/* Append relax relocation for link time relaxing. */
|
||
|
||
static void
|
||
-nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
+nds32_elf_append_relax_relocs (const char *key, void *value)
|
||
{
|
||
struct nds32_relocs_pattern *relocs_pattern =
|
||
(struct nds32_relocs_pattern *) value;
|
||
@@ -4942,7 +5618,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
struct nds32_relax_hint_table hint_info;
|
||
nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
|
||
size_t fixup_size;
|
||
- offsetT branch_offset;
|
||
+ offsetT branch_offset, hi_branch_offset = 0;
|
||
fixS *fixP;
|
||
int range, offset;
|
||
unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
|
||
@@ -4963,6 +5639,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
if (pattern_now->opcode->value == OP6 (SETHI))
|
||
{
|
||
hi_sym = pattern_now->sym;
|
||
+ hi_branch_offset = pattern_now->fixP->fx_offset;
|
||
break;
|
||
}
|
||
pattern_now = pattern_now->next;
|
||
@@ -4979,15 +5656,36 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
relax_code_size = hint_info.relax_code_size;
|
||
pattern_now = relocs_pattern;
|
||
|
||
+#ifdef NDS32_LINUX_TOOLCHAIN
|
||
+ /* prepare group relocation ID (number). */
|
||
+ long group_id = 0;
|
||
+ if (key)
|
||
+ {
|
||
+ /* convert .relax_hint key to number */
|
||
+ errno = 0;
|
||
+ group_id = strtol (key, NULL, 10);
|
||
+ if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
|
||
+ || (errno != 0 && group_id == 0))
|
||
+ {
|
||
+ as_bad (_("Internal error: .relax_hint KEY is not a number!"));
|
||
+ goto restore;
|
||
+ }
|
||
+ }
|
||
+#endif
|
||
+
|
||
/* Insert relaxation. */
|
||
exp.X_op = O_symbol;
|
||
|
||
+ /* for each instruction in the hint group */
|
||
while (pattern_now)
|
||
{
|
||
- /* Choose the match fixup by instruction. */
|
||
+ if (count >= relax_code_size / 4)
|
||
+ count = 0;
|
||
+ /* Choose the match fix-up by instruction. */
|
||
code_insn = CLEAN_REG (*(code_seq + count));
|
||
if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
|
||
{
|
||
+ /* try search from head again */
|
||
count = 0;
|
||
code_insn = CLEAN_REG (*(code_seq + count));
|
||
|
||
@@ -4996,8 +5694,11 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
count++;
|
||
if (count >= relax_code_size / 4)
|
||
{
|
||
- as_bad (_("Internal error: Relax hint error. %s: %x"),
|
||
- now_seg->name, pattern_now->opcode->value);
|
||
+ as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
|
||
+ key,
|
||
+ now_seg->name,
|
||
+ pattern_now->opcode->opcode,
|
||
+ pattern_now->opcode->value);
|
||
goto restore;
|
||
}
|
||
code_insn = CLEAN_REG (*(code_seq + count));
|
||
@@ -5024,7 +5725,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
}
|
||
fixup_size = fixup_now->size;
|
||
|
||
- /* Insert all fixup. */
|
||
+ /* Insert all fix-up. */
|
||
while (fixup_size != 0 && fixup_now->offset == offset)
|
||
{
|
||
/* Set the real instruction size in element. */
|
||
@@ -5093,7 +5794,108 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
{
|
||
/* For EMPTY relocation save the true symbol. */
|
||
exp.X_add_symbol = hi_sym;
|
||
- exp.X_add_number = branch_offset;
|
||
+ exp.X_add_number = hi_branch_offset;
|
||
+ }
|
||
+ else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
|
||
+ {
|
||
+ /* do the same as NDS32_SYM */
|
||
+ exp.X_add_symbol = hi_sym;
|
||
+ exp.X_add_number = hi_branch_offset;
|
||
+
|
||
+ /* extra to NDS32_SYM */
|
||
+ /* detect if DESC_FUNC relax type do apply */
|
||
+ if ((REG_GP == N32_RA5 (pattern_now->insn))
|
||
+ || (REG_GP == N32_RB5 (pattern_now->insn)))
|
||
+ {
|
||
+ fixP = fix_new_exp (fragP, where - fragP->fr_literal,
|
||
+ fixup_size, &exp, pcrel,
|
||
+ BFD_RELOC_NDS32_TLS_DESC_FUNC);
|
||
+ fixP->fx_addnumber = fixP->fx_offset;
|
||
+
|
||
+ fixup_size = 0;
|
||
+ }
|
||
+ /* else do as usual */
|
||
+ }
|
||
+ else if (fixup_now->ramp & NDS32_PTR_PATTERN)
|
||
+ {
|
||
+ /* find out PTR_RESOLVED code pattern */
|
||
+ nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
|
||
+ uint32_t resolved_pattern = 0;
|
||
+ while (next_fixup->offset)
|
||
+ {
|
||
+ if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
|
||
+ {
|
||
+ uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
|
||
+ if (!resolved_pattern)
|
||
+ resolved_pattern = new_pattern;
|
||
+ else if (new_pattern != resolved_pattern)
|
||
+ {
|
||
+ as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED patterns are not supported yet!"));
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ ++next_fixup;
|
||
+ }
|
||
+
|
||
+ /* find matched code and insert fix-ups */
|
||
+ struct nds32_relocs_pattern *next_pattern = pattern_now->next;
|
||
+ /* This relocation has to point to another instruction. Make
|
||
+ sure each resolved relocation has to be pointed. */
|
||
+ /* All instruction in relax_table should be 32-bit. */
|
||
+ while (next_pattern)
|
||
+ {
|
||
+ uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
|
||
+ if (cur_pattern == resolved_pattern)
|
||
+ {
|
||
+ ptr_offset = next_pattern->where
|
||
+ - next_pattern->frag->fr_literal;
|
||
+ exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
|
||
+ next_pattern->frag);
|
||
+ exp.X_add_number = 0;
|
||
+ fixP = fix_new_exp (fragP, where - fragP->fr_literal,
|
||
+ fixup_size, &exp, 0,
|
||
+ fixup_now->r_type);
|
||
+ fixP->fx_addnumber = fixP->fx_offset;
|
||
+ }
|
||
+ next_pattern = next_pattern->next;
|
||
+ }
|
||
+
|
||
+ fixup_size = 0;
|
||
+ }
|
||
+ else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
|
||
+ {
|
||
+ /* find each PTR_RESOLVED pattern after PTR */
|
||
+ nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
|
||
+ while (next_fixup->offset)
|
||
+ {
|
||
+ if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
|
||
+ {
|
||
+ uint32_t pattern = code_seq[next_fixup->offset >> 2];
|
||
+ /* find matched code to insert fix-ups */
|
||
+ struct nds32_relocs_pattern *next_insn = pattern_now->next;
|
||
+ while (next_insn)
|
||
+ {
|
||
+ uint32_t insn_pattern = GET_OPCODE(
|
||
+ next_insn->opcode->value);
|
||
+ if (insn_pattern == pattern)
|
||
+ {
|
||
+ ptr_offset = next_insn->where
|
||
+ - next_insn->frag->fr_literal;
|
||
+ exp.X_add_symbol = symbol_temp_new (
|
||
+ now_seg, ptr_offset, next_insn->frag);
|
||
+ exp.X_add_number = 0;
|
||
+ fixP = fix_new_exp (fragP,
|
||
+ where - fragP->fr_literal,
|
||
+ fixup_size, &exp, 0,
|
||
+ fixup_now->r_type);
|
||
+ fixP->fx_addnumber = fixP->fx_offset;
|
||
+ }
|
||
+ next_insn = next_insn->next;
|
||
+ }
|
||
+ }
|
||
+ ++next_fixup;
|
||
+ }
|
||
+ fixup_size = 0;
|
||
}
|
||
else
|
||
{
|
||
@@ -5110,6 +5912,19 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
|
||
fixup_now++;
|
||
fixup_size = fixup_now->size;
|
||
}
|
||
+
|
||
+#ifdef NDS32_LINUX_TOOLCHAIN
|
||
+ /* Insert group relocation for each relax hint. */
|
||
+ if (key)
|
||
+ {
|
||
+ exp.X_add_symbol = hi_sym; /* for eyes only */
|
||
+ exp.X_add_number = group_id;
|
||
+ fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
|
||
+ &exp, pcrel, BFD_RELOC_NDS32_GROUP);
|
||
+ fixP->fx_addnumber = fixP->fx_offset;
|
||
+ }
|
||
+#endif
|
||
+
|
||
if (count < relax_code_size / 4)
|
||
count++;
|
||
pattern_now = pattern_now->next;
|
||
@@ -5120,6 +5935,19 @@ restore:
|
||
frchain_now = frchain_bak;
|
||
}
|
||
|
||
+static void
|
||
+nds32_str_tolower (const char *src, char *dest)
|
||
+{
|
||
+ unsigned int i, len;
|
||
+
|
||
+ len = strlen (src);
|
||
+
|
||
+ for (i = 0; i < len; i++)
|
||
+ *(dest + i) = TOLOWER (*(src + i));
|
||
+
|
||
+ *(dest + i) = '\0';
|
||
+}
|
||
+
|
||
/* Check instruction if it can be used for the baseline. */
|
||
|
||
static bfd_boolean
|
||
@@ -5127,6 +5955,28 @@ nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
|
||
{
|
||
int attr = insn.attr & ATTR_ALL;
|
||
static int baseline_isa = 0;
|
||
+ char *s;
|
||
+
|
||
+ s = alloca (strlen (str) + 1);
|
||
+ nds32_str_tolower (str, s);
|
||
+ if (verbatim && inline_asm
|
||
+ && (((insn.opcode->value == ALU2 (MTUSR)
|
||
+ || insn.opcode->value == ALU2 (MFUSR))
|
||
+ && (strstr (s, "lc")
|
||
+ || strstr (s, "le")
|
||
+ || strstr (s, "lb")))
|
||
+ || (insn.attr & NASM_ATTR_ZOL)))
|
||
+ {
|
||
+ as_bad (_("Not support instruction %s in verbatim."), str);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ if (!enable_16bit && insn.opcode->isize == 2)
|
||
+ {
|
||
+ as_bad (_("16-bit instruction is disabled: %s."), str);
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
/* No isa setting or all isa can use. */
|
||
if (attr == 0 || attr == ATTR_ALL)
|
||
return TRUE;
|
||
@@ -5150,28 +6000,70 @@ nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
|
||
|
||
if ((baseline_isa & attr) == 0)
|
||
{
|
||
- as_bad (_("Instruction %s not supported in the baseline."), str);
|
||
+ as_bad (_("Not support instruction %s in the baseline."), str);
|
||
return FALSE;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
+/* Clear security and insert relocation. */
|
||
+static void
|
||
+nds32_set_crc (fragS *fragP, struct nds32_asm_insn *insn, char *out)
|
||
+{
|
||
+ expressionS exp;
|
||
+
|
||
+ /* The security region begin. */
|
||
+ if (strcmp (insn->opcode->opcode, "isps") == 0)
|
||
+ {
|
||
+ exp.X_op = O_symbol;
|
||
+ exp.X_add_symbol = abs_section_sym;
|
||
+ /* Meet the new crc in previos crc region. */
|
||
+ if (crcing == TRUE)
|
||
+ {
|
||
+ exp.X_add_number = NDS32_SECURITY_RESTART;
|
||
+ fix_new_exp (fragP, out - fragP->fr_literal, 0, &exp,
|
||
+ 0, BFD_RELOC_NDS32_SECURITY_16);
|
||
+ }
|
||
+ crcing = TRUE;
|
||
+ /* For security used only. */
|
||
+ exp.X_add_number = NDS32_SECURITY_START;
|
||
+ fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
|
||
+ &exp, 0 /* pcrel */, BFD_RELOC_NDS32_SECURITY_16);
|
||
+ }
|
||
+ /* Turn off security region when meeting branch. */
|
||
+ else if (crcing && ((insn->attr & NASM_ATTR_BRANCH)
|
||
+ || insn->opcode->value == MISC (SYSCALL)
|
||
+ || insn->opcode->value == MISC (TRAP)
|
||
+ || insn->opcode->value == MISC (TEQZ)
|
||
+ || insn->opcode->value == MISC (TNEZ)
|
||
+ || insn->opcode->value == MISC (IRET)
|
||
+ || insn->attr & NASM_ATTR_IFC_EXT))
|
||
+ {
|
||
+ crcing = FALSE;
|
||
+ exp.X_op = O_symbol;
|
||
+ exp.X_add_symbol = abs_section_sym;
|
||
+ exp.X_add_number = NDS32_SECURITY_END;
|
||
+ fix_new_exp (fragP, out - fragP->fr_literal, 0, &exp,
|
||
+ 0, BFD_RELOC_NDS32_SECURITY_16);
|
||
+ }
|
||
+}
|
||
+
|
||
/* Stub of machine dependent. */
|
||
|
||
void
|
||
md_assemble (char *str)
|
||
{
|
||
struct nds32_asm_insn insn;
|
||
- expressionS expr;
|
||
char *out;
|
||
struct nds32_pseudo_opcode *popcode;
|
||
const struct nds32_field *fld = NULL;
|
||
fixS *fixP;
|
||
uint16_t insn_16;
|
||
struct nds32_relocs_pattern *relocs_temp;
|
||
- expressionS *pexp;
|
||
+ struct nds32_relocs_group *group_temp;
|
||
fragS *fragP;
|
||
int label = label_exist;
|
||
+ static bfd_boolean pseudo_hint = FALSE;
|
||
|
||
popcode = nds32_lookup_pseudo_opcode (str);
|
||
/* Note that we need to check 'verbatim' and
|
||
@@ -5180,11 +6072,23 @@ md_assemble (char *str)
|
||
need to perform pseudo instruction expansion/transformation. */
|
||
if (popcode && !(verbatim && popcode->physical_op))
|
||
{
|
||
+ /* Pseudo instruction is with relax_hint. */
|
||
+ if (relaxing)
|
||
+ pseudo_hint = TRUE;
|
||
pseudo_opcode = TRUE;
|
||
nds32_pseudo_opcode_wrapper (str, popcode);
|
||
pseudo_opcode = FALSE;
|
||
+ pseudo_hint = FALSE;
|
||
nds32_elf_append_relax_relocs (NULL, relocs_list);
|
||
|
||
+ /* Free relax_hint group list. */
|
||
+ while (nds32_relax_hint_current)
|
||
+ {
|
||
+ group_temp = nds32_relax_hint_current->next;
|
||
+ free (nds32_relax_hint_current);
|
||
+ nds32_relax_hint_current = group_temp;
|
||
+ }
|
||
+
|
||
/* Free pseudo list. */
|
||
relocs_temp = relocs_list;
|
||
while (relocs_temp)
|
||
@@ -5193,12 +6097,11 @@ md_assemble (char *str)
|
||
free (relocs_temp);
|
||
relocs_temp = relocs_list;
|
||
}
|
||
-
|
||
return;
|
||
}
|
||
|
||
label_exist = 0;
|
||
- insn.info = & expr;
|
||
+ insn.info = (expressionS *) alloca (sizeof (expressionS));
|
||
asm_desc.result = NASM_OK;
|
||
nds32_assemble (&asm_desc, &insn, str);
|
||
|
||
@@ -5235,11 +6138,13 @@ md_assemble (char *str)
|
||
|
||
/* Make sure the beginning of text being 2-byte align. */
|
||
nds32_adjust_label (1);
|
||
+ add_mapping_symbol (MAP_CODE, 0, 0);
|
||
fld = insn.field;
|
||
/* Try to allocate the max size to guarantee relaxable same branch
|
||
instructions in the same fragment. */
|
||
frag_grow (NDS32_MAXCHAR);
|
||
fragP = frag_now;
|
||
+
|
||
if (fld && (insn.attr & NASM_ATTR_BRANCH)
|
||
&& (pseudo_opcode || (insn.opcode->value != INSN_JAL
|
||
&& insn.opcode->value != INSN_J))
|
||
@@ -5247,7 +6152,7 @@ md_assemble (char *str)
|
||
{
|
||
/* User assembly code branch relax for it. */
|
||
/* If fld is not NULL, it is a symbol. */
|
||
- /* Branch must relax to proper pattern in user assembly code exclude
|
||
+ /* Branch msut relax to proper pattern in user assembly code exclude
|
||
J and JAL. Keep these two in original type for users which wants
|
||
to keep their size be fixed. In general, assembler does not convert
|
||
instruction generated by compiler. But jump instruction may be
|
||
@@ -5257,8 +6162,8 @@ md_assemble (char *str)
|
||
/* Get branch range type. */
|
||
dwarf2_emit_insn (0);
|
||
enum nds32_br_range range_type;
|
||
+ expressionS *pexp = insn.info;
|
||
|
||
- pexp = insn.info;
|
||
range_type = get_range_type (fld);
|
||
|
||
out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
|
||
@@ -5274,6 +6179,12 @@ md_assemble (char *str)
|
||
else if (insn.opcode->isize == 2)
|
||
bfd_putb16 (insn.insn, out);
|
||
fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
|
||
+
|
||
+ if (fld->bitsize == 24 && fld->shift == 1
|
||
+ && pexp->X_md == BFD_RELOC_NDS32_ICT)
|
||
+ fragP->tc_frag_data.flag |= NDS32_FRAG_ICT_BRANCH;
|
||
+
|
||
+ nds32_set_crc (fragP, &insn, out);
|
||
return;
|
||
/* md_convert_frag will insert relocations. */
|
||
}
|
||
@@ -5284,7 +6195,7 @@ md_assemble (char *str)
|
||
&& nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
|
||
{
|
||
/* Record this one is relaxable. */
|
||
- pexp = insn.info;
|
||
+ expressionS *pexp = insn.info;
|
||
dwarf2_emit_insn (0);
|
||
if (fld)
|
||
{
|
||
@@ -5304,7 +6215,7 @@ md_assemble (char *str)
|
||
fragP->tc_frag_data.insn = insn.insn;
|
||
fragP->fr_fix += 2;
|
||
|
||
- /* In original, we don't relax the instruction with label on it,
|
||
+ /* In original, we don't relax the instrucion with label on it,
|
||
but this may cause some redundant nop16. Therefore, tag this
|
||
relaxable instruction and relax it carefully. */
|
||
if (label)
|
||
@@ -5314,6 +6225,7 @@ md_assemble (char *str)
|
||
bfd_putb16 (insn_16, out);
|
||
else if (insn.opcode->isize == 2)
|
||
bfd_putb16 (insn.insn, out);
|
||
+ nds32_set_crc (fragP, &insn, out);
|
||
return;
|
||
}
|
||
else if ((verbatim || !relaxing) && optimize && label)
|
||
@@ -5322,7 +6234,7 @@ md_assemble (char *str)
|
||
expressionS exp;
|
||
out = frag_var (rs_machine_dependent, insn.opcode->isize,
|
||
0, 0, NULL, 0, NULL);
|
||
- /* If this instruction is branch target, it is not relaxable. */
|
||
+ /* If this insturction is branch target, it is not relaxable. */
|
||
fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
|
||
fragP->tc_frag_data.opcode = insn.opcode;
|
||
fragP->tc_frag_data.insn = insn.insn;
|
||
@@ -5343,18 +6255,20 @@ md_assemble (char *str)
|
||
|
||
if (insn.opcode->isize == 4)
|
||
bfd_putb32 (insn.insn, out);
|
||
- if (insn.opcode->isize == 2)
|
||
+ else if (insn.opcode->isize == 2)
|
||
bfd_putb16 (insn.insn, out);
|
||
|
||
dwarf2_emit_insn (insn.opcode->isize);
|
||
|
||
/* Compiler generating code and user assembly pseudo load-store, insert
|
||
fixup here. */
|
||
- pexp = insn.info;
|
||
+ expressionS *pexp = insn.info;
|
||
fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
|
||
/* Build relaxation pattern when relaxing is enable. */
|
||
if (relaxing)
|
||
- nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
|
||
+ nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
|
||
+ pseudo_hint);
|
||
+ nds32_set_crc (fragP, &insn, out);
|
||
}
|
||
|
||
/* md_macro_start */
|
||
@@ -5402,7 +6316,7 @@ md_section_align (segT segment, valueT size)
|
||
{
|
||
int align = bfd_get_section_alignment (stdoutput, segment);
|
||
|
||
- return ((size + (1 << align) - 1) & -(1 << align));
|
||
+ return ((size + (1 << align) - 1) & ((valueT) -1 << align));
|
||
}
|
||
|
||
/* GAS will call this function when a symbol table lookup fails, before it
|
||
@@ -5441,6 +6355,7 @@ nds32_calc_branch_offset (segT segment, fragS *fragP,
|
||
{
|
||
/* Calculate symbol-to-instruction offset. */
|
||
branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
|
||
+
|
||
/* If the destination symbol is beyond current frag address,
|
||
STRETCH will take effect to symbol's position. */
|
||
if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
|
||
@@ -5464,31 +6379,31 @@ nds32_convert_to_range_type (long offset)
|
||
{
|
||
enum nds32_br_range range_type;
|
||
|
||
- if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
|
||
+ if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
|
||
range_type = BR_RANGE_S256;
|
||
- else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
|
||
+ else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
|
||
range_type = BR_RANGE_S16K;
|
||
- else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
|
||
+ else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
|
||
range_type = BR_RANGE_S64K;
|
||
- else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
|
||
+ else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
|
||
range_type = BR_RANGE_S16M;
|
||
- else /* 4G bytes */
|
||
+ else /* 4G bytes */
|
||
range_type = BR_RANGE_U4G;
|
||
|
||
return range_type;
|
||
}
|
||
|
||
-/* Set instruction register mask. */
|
||
+/* Set insntruction register mask. */
|
||
|
||
static void
|
||
nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
|
||
uint32_t ori_insn, int range)
|
||
{
|
||
- nds32_cond_field_t *cond_fields = relax_info->cond_field;
|
||
+ nds32_cond_field_t *cond_fields;
|
||
+ cond_fields = relax_info->cond_field;
|
||
nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
|
||
uint32_t mask;
|
||
int i = 0;
|
||
-
|
||
/* The instruction has conditions. Collect condition values. */
|
||
while (code_seq_cond[i].bitmask != 0)
|
||
{
|
||
@@ -5525,24 +6440,45 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
|
||
int insn_size;
|
||
int code_seq_offset;
|
||
|
||
- /* Replace with gas_assert (fragP->fr_symbol != NULL); */
|
||
+ /* Replace with gas_assert (fragP->fr_symbol != NULL); */
|
||
if (fragP->fr_symbol == NULL)
|
||
return adjust;
|
||
|
||
- /* If frag_var is not enough room, the previous frag is fr_full and with
|
||
+ /* If frag_var is not enough room, the previos frag is fr_full and with
|
||
opcode. The new one is rs_dependent but without opcode. */
|
||
if (opcode == NULL)
|
||
return adjust;
|
||
|
||
+ /* Use U4G mode for b and bal in verbatim mode because lto may combine
|
||
+ functions into a file. And order the file in the last when linking.
|
||
+ Once there is multiple definition, the same function will be kicked.
|
||
+ This may cause relocation truncated error. */
|
||
+ if (verbatim && !nds32_pic
|
||
+ && (strcmp (opcode->opcode, "j") == 0
|
||
+ || strcmp (opcode->opcode, "jal") == 0))
|
||
+ {
|
||
+ fragP->fr_subtype = BR_RANGE_U4G;
|
||
+ if (init)
|
||
+ return 8;
|
||
+ else
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
|
||
|
||
if (relax_info == NULL)
|
||
return adjust;
|
||
|
||
if (init)
|
||
- branch_range_type = relax_info->br_range;
|
||
+ {
|
||
+ branch_range_type = relax_info->br_range;
|
||
+ i = BR_RANGE_S256;
|
||
+ }
|
||
else
|
||
- branch_range_type = fragP->fr_subtype;
|
||
+ {
|
||
+ branch_range_type = fragP->fr_subtype;
|
||
+ i = branch_range_type;
|
||
+ }
|
||
|
||
offset = nds32_calc_branch_offset (segment, fragP, stretch,
|
||
relax_info, branch_range_type);
|
||
@@ -5551,15 +6487,21 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
|
||
|
||
/* If actual range is equal to instruction jump range, do nothing. */
|
||
if (real_range_type == branch_range_type)
|
||
- return adjust;
|
||
+ {
|
||
+ fragP->fr_subtype = real_range_type;
|
||
+ return adjust;
|
||
+ }
|
||
|
||
/* Find out proper relaxation code sequence. */
|
||
- for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
|
||
+ for (; i < BR_RANGE_NUM; i++)
|
||
{
|
||
if (real_range_type <= (unsigned int) i)
|
||
{
|
||
if (init)
|
||
diff = relax_info->relax_code_size[i] - opcode->isize;
|
||
+ else if (real_range_type < (unsigned int) i)
|
||
+ diff = relax_info->relax_code_size[real_range_type]
|
||
+ - relax_info->relax_code_size[branch_range_type];
|
||
else
|
||
diff = relax_info->relax_code_size[i]
|
||
- relax_info->relax_code_size[branch_range_type];
|
||
@@ -5592,7 +6534,7 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
|
||
}
|
||
|
||
/* Update fr_subtype to new NDS32_BR_RANGE. */
|
||
- fragP->fr_subtype = i;
|
||
+ fragP->fr_subtype = real_range_type;
|
||
break;
|
||
}
|
||
}
|
||
@@ -5631,19 +6573,19 @@ nds32_get_align (addressT address, int align)
|
||
{
|
||
addressT mask, new_address;
|
||
|
||
- mask = ~((~0U) << align);
|
||
+ mask = ~((addressT) (~0) << align);
|
||
new_address = (address + mask) & (~mask);
|
||
return (new_address - address);
|
||
}
|
||
|
||
/* Check the prev_frag is legal. */
|
||
static void
|
||
-invalid_prev_frag (fragS * fragP, fragS **prev_frag)
|
||
+invalid_prev_frag (fragS * fragP, fragS **prev_frag, bfd_boolean relax)
|
||
{
|
||
addressT address;
|
||
fragS *frag_start = *prev_frag;
|
||
|
||
- if (!frag_start)
|
||
+ if (!frag_start || !relax)
|
||
return;
|
||
|
||
if (frag_start->last_fr_address >= fragP->last_fr_address)
|
||
@@ -5659,13 +6601,13 @@ invalid_prev_frag (fragS * fragP, fragS **prev_frag)
|
||
|| frag_t->fr_type == rs_align_code
|
||
|| frag_t->fr_type == rs_align_test)
|
||
{
|
||
- /* Relax instruction can not walk across label. */
|
||
+ /* Relax instruction can not walk across lable. */
|
||
if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
|
||
{
|
||
prev_frag = NULL;
|
||
return;
|
||
}
|
||
- /* Relax previous relaxable to align rs_align frag. */
|
||
+ /* Relax previos relaxable to align rs_align frag. */
|
||
address = frag_t->fr_address + frag_t->fr_fix;
|
||
addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
|
||
if (offset & 0x2)
|
||
@@ -5711,7 +6653,7 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
|
||
static fragS *prev_frag = NULL;
|
||
int adjust = 0;
|
||
|
||
- invalid_prev_frag (fragP, &prev_frag);
|
||
+ invalid_prev_frag (fragP, &prev_frag, TRUE);
|
||
|
||
if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
|
||
adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
|
||
@@ -5720,8 +6662,8 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
|
||
if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
|
||
&& (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
|
||
/* Here is considered relaxed case originally. But it may cause
|
||
- an endless loop when relaxing. Once the instruction is relaxed,
|
||
- it can not be undone. */
|
||
+ unendless loop when relaxing. Once the instruction is relaxed,
|
||
+ it can not be undo. */
|
||
prev_frag = fragP;
|
||
|
||
return adjust;
|
||
@@ -5744,11 +6686,11 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
|
||
1. relax for branch
|
||
2. relax for 32-bits to 16-bits */
|
||
|
||
- /* Save previous relaxable frag. */
|
||
+ /* Save previos relaxable frag. */
|
||
static fragS *prev_frag = NULL;
|
||
int adjust = 0;
|
||
|
||
- invalid_prev_frag (fragP, &prev_frag);
|
||
+ invalid_prev_frag (fragP, &prev_frag, FALSE);
|
||
|
||
if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
|
||
adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
|
||
@@ -5798,12 +6740,14 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
|
||
nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
|
||
/* Save the 1st instruction is converted to 16 bit or not. */
|
||
unsigned int branch_size;
|
||
+ bfd_boolean is_ict_sym;
|
||
+ enum bfd_reloc_code_real final_r_type;
|
||
|
||
- /* Replace with gas_assert (branch_symbol != NULL); */
|
||
+ /* Replace with gas_assert (branch_symbol != NULL); */
|
||
if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
|
||
return;
|
||
|
||
- /* If frag_var is not enough room, the previous frag is fr_full and with
|
||
+ /* If frag_var is not enough room, the previos frag is fr_full and with
|
||
opcode. The new one is rs_dependent but without opcode. */
|
||
if (opcode == NULL)
|
||
return;
|
||
@@ -5872,6 +6816,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
|
||
/* Branch instruction adjust and append relocations. */
|
||
relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
|
||
|
||
+ is_ict_sym = fragP->tc_frag_data.flag & NDS32_FRAG_ICT_BRANCH;
|
||
+
|
||
if (relax_info == NULL)
|
||
return;
|
||
|
||
@@ -5902,8 +6848,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
|
||
/* Fill in frag. */
|
||
i = 0;
|
||
k = 0;
|
||
- offset = 0; /* code_seq offset */
|
||
- buf_offset = 0; /* fr_buffer offset */
|
||
+ offset = 0; /* code_seq offset */
|
||
+ buf_offset = 0; /* fr_buffer offset */
|
||
while (offset < code_size)
|
||
{
|
||
insn = code_seq[i];
|
||
@@ -5921,7 +6867,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
|
||
origin_insn, branch_range_type);
|
||
|
||
/* Try to convert to 16-bits instruction. Currently, only the first
|
||
- instruction in pattern can be converted. EX: bnez sethi ori jr,
|
||
+ insntruction in pattern can be converted. EX: bnez sethi ori jr,
|
||
only bnez can be converted to 16 bit and ori can't. */
|
||
|
||
while (fixup_info[k].size != 0
|
||
@@ -5978,9 +6924,20 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
|
||
|
||
if (fixup_info[i].r_type != 0)
|
||
{
|
||
+ final_r_type = fixup_info[i].r_type;
|
||
+
|
||
+ /* Convert reloc type to ICT style if this frag is
|
||
+ handle for ICT symbol. */
|
||
+ if (is_ict_sym && final_r_type == BFD_RELOC_NDS32_HI20)
|
||
+ final_r_type = BFD_RELOC_NDS32_ICT_HI20;
|
||
+ else if (is_ict_sym && final_r_type == BFD_RELOC_NDS32_LO12S0_ORI)
|
||
+ final_r_type = BFD_RELOC_NDS32_ICT_LO12;
|
||
+ else if (is_ict_sym && fixup_info[i].ramp & NDS32_HINT)
|
||
+ continue;
|
||
+
|
||
fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
|
||
fixup_size, &exp, pcrel,
|
||
- fixup_info[i].r_type);
|
||
+ final_r_type);
|
||
fixP->fx_addnumber = fixP->fx_offset;
|
||
}
|
||
}
|
||
@@ -6003,7 +6960,7 @@ nds32_relaxable_section (asection *sec)
|
||
&& strcmp (sec->name, ".eh_frame") != 0);
|
||
}
|
||
|
||
-/* TC_FORCE_RELOCATION */
|
||
+/* TC_FORCE_RELOCATION */
|
||
int
|
||
nds32_force_relocation (fixS * fix)
|
||
{
|
||
@@ -6041,8 +6998,8 @@ nds32_force_relocation (fixS * fix)
|
||
&& nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
|
||
case BFD_RELOC_64:
|
||
if (fix->fx_subsy)
|
||
- as_bad ("Double word for difference between two symbols "
|
||
- "is not supported across relaxation.");
|
||
+ as_bad ("Double word for difference between two symbols is not "
|
||
+ "supported across relaxation.");
|
||
default:
|
||
;
|
||
}
|
||
@@ -6202,14 +7159,16 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
|
||
fixS *fixp;
|
||
|
||
seginfo = seg_info (sec);
|
||
+ if (symbol_find ("_INDIRECT_CALL_TABLE_BASE_"))
|
||
+ ict_exist = TRUE;
|
||
if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
|
||
return;
|
||
- /* If there is no relocation and relax is disabled, it is not necessary to
|
||
- insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization. */
|
||
+
|
||
for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
|
||
if (!fixp->fx_done)
|
||
break;
|
||
- if (!fixp && !enable_relax_ex9 && !verbatim)
|
||
+
|
||
+ if (!fixp && !verbatim && (!ict_exist || ict_flag == ICT_NONE))
|
||
return;
|
||
|
||
subseg_change (sec, 0);
|
||
@@ -6217,21 +7176,21 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
|
||
/* Set RELAX_ENTRY flags for linker. */
|
||
fragP = seginfo->frchainP->frch_root;
|
||
exp.X_op = O_symbol;
|
||
- exp.X_add_symbol = section_symbol (sec);
|
||
+ exp.X_add_symbol = abs_section_sym;
|
||
exp.X_add_number = 0;
|
||
if (!enable_relax_relocs)
|
||
exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
|
||
else
|
||
{
|
||
/* These flags are only enabled when global relax is enabled.
|
||
- Maybe we can check DISABLE_RELAX_FLAG at link-time,
|
||
+ Maybe we can check DISABLE_RELAX_FLAG at linke-time,
|
||
so we set them anyway. */
|
||
- if (enable_relax_ex9)
|
||
- exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
|
||
- if (enable_relax_ifc)
|
||
- exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
|
||
if (verbatim)
|
||
exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
|
||
+ if (ict_exist && ict_flag == ICT_SMALL)
|
||
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL;
|
||
+ else if (ict_exist && ict_flag == ICT_LARGE)
|
||
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE;
|
||
}
|
||
if (optimize)
|
||
exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
|
||
@@ -6282,9 +7241,28 @@ nds32_elf_insert_final_frag (void)
|
||
}
|
||
}
|
||
|
||
+static void
|
||
+nds32_create_section_compatible_abi (void)
|
||
+{
|
||
+ segT comp_section = subseg_new (".note.v2abi_compatible", 0);
|
||
+ bfd_set_section_flags (stdoutput, comp_section,
|
||
+ SEC_READONLY | SEC_DATA | SEC_EXCLUDE);
|
||
+
|
||
+ /* Set content to .v2abi_compatible section. */
|
||
+ now_seg = comp_section;
|
||
+ frag_grow (NDS32_MAXCHAR);
|
||
+ char *out = frag_more (4);
|
||
+ if (compatible_abi)
|
||
+ bfd_putb32 ((bfd_vma) 1, out);
|
||
+ else
|
||
+ bfd_putb32 ((bfd_vma) 0, out);
|
||
+}
|
||
+
|
||
void
|
||
md_end (void)
|
||
{
|
||
+ if (compatible_abi)
|
||
+ nds32_create_section_compatible_abi ();
|
||
nds32_elf_insert_final_frag ();
|
||
nds32_elf_analysis_relax_hint ();
|
||
bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
|
||
@@ -6390,6 +7368,8 @@ nds32_fix_adjustable (fixS *fixP)
|
||
case BFD_RELOC_NDS32_LONGJUMP5:
|
||
case BFD_RELOC_NDS32_LONGJUMP6:
|
||
case BFD_RELOC_NDS32_LONGJUMP7:
|
||
+ case BFD_RELOC_NDS32_10IFCU_PCREL:
|
||
+ case BFD_RELOC_NDS32_17IFC_PCREL:
|
||
return 1;
|
||
default:
|
||
return 0;
|
||
@@ -6407,7 +7387,7 @@ elf_nds32_final_processing (void)
|
||
&& !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
|
||
{
|
||
/* Since only FPU_COM instructions are used and no other FPU instructions
|
||
- are used. The nds32_elf_flags will be decided by the enabled options
|
||
+ are used. The nds32_elf_flags will be decided by the enabled options
|
||
by command line or default configuration. */
|
||
if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
|
||
{
|
||
@@ -6430,9 +7410,6 @@ elf_nds32_final_processing (void)
|
||
nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
|
||
}
|
||
|
||
- if (nds32_pic)
|
||
- nds32_elf_flags |= E_NDS32_HAS_PIC;
|
||
-
|
||
if (nds32_gpr16)
|
||
nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
|
||
|
||
@@ -6440,7 +7417,7 @@ elf_nds32_final_processing (void)
|
||
elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
|
||
}
|
||
|
||
-/* Implement md_apply_fix. Apply the fix-up or transform the fix-up for
|
||
+/* Implement md_apply_fix. Apply the fix-up or tranform the fix-up for
|
||
later relocation generation. */
|
||
|
||
void
|
||
@@ -6463,14 +7440,10 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||
fixP->fx_addnumber = value;
|
||
fixP->tc_fix_data = NULL;
|
||
|
||
- /* Transform specific relocations here for later relocation generation.
|
||
- Tag data here for ex9 relaxation and tag tls data for linker. */
|
||
+ /* Tranform specific relocations here for later relocation generation.
|
||
+ Tag tls data here for linker. */
|
||
switch (fixP->fx_r_type)
|
||
{
|
||
- case BFD_RELOC_NDS32_DATA:
|
||
- if (!enable_relax_ex9)
|
||
- fixP->fx_done = 1;
|
||
- break;
|
||
case BFD_RELOC_NDS32_TPOFF:
|
||
case BFD_RELOC_NDS32_TLS_LE_HI20:
|
||
case BFD_RELOC_NDS32_TLS_LE_LO12:
|
||
@@ -6479,6 +7452,12 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||
case BFD_RELOC_NDS32_GOTTPOFF:
|
||
case BFD_RELOC_NDS32_TLS_IE_HI20:
|
||
case BFD_RELOC_NDS32_TLS_IE_LO12S2:
|
||
+ case BFD_RELOC_NDS32_TLS_DESC_HI20:
|
||
+ case BFD_RELOC_NDS32_TLS_DESC_LO12:
|
||
+ case BFD_RELOC_NDS32_TLS_IE_LO12:
|
||
+ case BFD_RELOC_NDS32_TLS_IEGP_HI20:
|
||
+ case BFD_RELOC_NDS32_TLS_IEGP_LO12:
|
||
+ case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
|
||
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
||
break;
|
||
default:
|
||
@@ -6519,7 +7498,7 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||
---- 8< ---- 8< ---- 8< ---- 8< ----
|
||
|
||
We use a single relocation entry for this expression.
|
||
- * The initial distance value is stored directly in that location
|
||
+ * The initial distance value is stored direcly in that location
|
||
specified by r_offset (i.e., foo in this example.)
|
||
* The begin of the region, i.e., .LBEGIN, is specified by
|
||
r_info/R_SYM and r_addend, e.g., .text + 0x32.
|
||
@@ -6605,7 +7584,6 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||
break;
|
||
case BFD_RELOC_64:
|
||
md_number_to_chars (where, value, 8);
|
||
- break;
|
||
default:
|
||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||
_("Internal error: Unknown fixup type %d (`%s')"),
|
||
@@ -6624,9 +7602,9 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
|
||
arelent *reloc;
|
||
bfd_reloc_code_real_type code;
|
||
|
||
- reloc = XNEW (arelent);
|
||
+ reloc = (arelent *) xmalloc (sizeof (arelent));
|
||
|
||
- reloc->sym_ptr_ptr = XNEW (asymbol *);
|
||
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
|
||
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
|
||
reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
|
||
|
||
@@ -6661,13 +7639,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
|
||
return reloc;
|
||
}
|
||
|
||
-struct suffix_name suffix_table[] =
|
||
+static struct suffix_name suffix_table[] =
|
||
{
|
||
- {"GOTOFF", BFD_RELOC_NDS32_GOTOFF, 1},
|
||
- {"GOT", BFD_RELOC_NDS32_GOT20, 1},
|
||
- {"TPOFF", BFD_RELOC_NDS32_TPOFF, 0},
|
||
- {"PLT", BFD_RELOC_NDS32_25_PLTREL, 1},
|
||
- {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF, 0}
|
||
+ {"GOTOFF", BFD_RELOC_NDS32_GOTOFF},
|
||
+ {"GOT", BFD_RELOC_NDS32_GOT20},
|
||
+ {"TPOFF", BFD_RELOC_NDS32_TPOFF},
|
||
+ {"PLT", BFD_RELOC_NDS32_25_PLTREL},
|
||
+ {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF},
|
||
+ {"TLSDESC", BFD_RELOC_NDS32_TLS_DESC},
|
||
+ {"ICT", BFD_RELOC_NDS32_ICT}
|
||
};
|
||
|
||
/* Implement md_parse_name. */
|
||
@@ -6686,9 +7666,9 @@ nds32_parse_name (char const *name, expressionS *exprP,
|
||
exprP->X_op = O_symbol;
|
||
exprP->X_add_number = 0;
|
||
|
||
- /* Check the special name if a symbol. */
|
||
+ /* Check the specail name if a symbol. */
|
||
segment = S_GET_SEGMENT (exprP->X_add_symbol);
|
||
- if (segment != undefined_section)
|
||
+ if ((segment != undefined_section) && (*nextcharP != '@'))
|
||
return 0;
|
||
|
||
if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
|
||
@@ -6702,13 +7682,11 @@ nds32_parse_name (char const *name, expressionS *exprP,
|
||
char *next;
|
||
for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
|
||
{
|
||
- next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
|
||
+ next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
|
||
if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
|
||
strlen (suffix_table[i].suffix)) == 0
|
||
&& !is_part_of_name (*next))
|
||
{
|
||
- if (!nds32_pic && suffix_table[i].pic)
|
||
- as_bad (_("need PIC qualifier with symbol."));
|
||
exprP->X_md = suffix_table[i].reloc;
|
||
*input_line_pointer = *nextcharP;
|
||
input_line_pointer = next;
|
||
@@ -6718,6 +7696,10 @@ nds32_parse_name (char const *name, expressionS *exprP,
|
||
}
|
||
}
|
||
}
|
||
+
|
||
+ if (exprP->X_md == BFD_RELOC_NDS32_ICT)
|
||
+ ict_exist = TRUE;
|
||
+
|
||
return 1;
|
||
}
|
||
|
||
diff --git binutils-2.30/gas/config/tc-nds32.h binutils-2.30-nds32/gas/config/tc-nds32.h
|
||
index 178ca4ec33..bcea94afe0 100644
|
||
--- binutils-2.30/gas/config/tc-nds32.h
|
||
+++ binutils-2.30-nds32/gas/config/tc-nds32.h
|
||
@@ -24,13 +24,28 @@
|
||
|
||
#include "bfd_stdint.h"
|
||
|
||
+/* Enum mapping symbol. */
|
||
+enum mstate
|
||
+{
|
||
+ MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */
|
||
+ MAP_DATA,
|
||
+ MAP_CODE,
|
||
+};
|
||
+#define TC_SEGMENT_INFO_TYPE struct nds32_segment_info_type
|
||
+
|
||
+/* For mapping symbol. */
|
||
+struct nds32_segment_info_type
|
||
+{
|
||
+ enum mstate mapstate;
|
||
+};
|
||
+
|
||
#define LISTING_HEADER \
|
||
(target_big_endian ? "NDS32 GAS" : "NDS32 GAS Little Endian")
|
||
|
||
/* The target BFD architecture. */
|
||
#define TARGET_ARCH bfd_arch_nds32
|
||
|
||
-/* mapping to mach_table[5] */
|
||
+/* mapping to mach_table[5] */
|
||
#define ISA_V1 bfd_mach_n1h
|
||
#define ISA_V2 bfd_mach_n1h_v2
|
||
#define ISA_V3 bfd_mach_n1h_v3
|
||
@@ -42,29 +57,28 @@
|
||
#define TARGET_BYTES_BIG_ENDIAN 1
|
||
#endif
|
||
|
||
-/* as.c. */
|
||
-/* Extend GAS command line option handling capability. */
|
||
+/* as.c */
|
||
+/* Extend GAS command line option handling capability */
|
||
extern int nds32_parse_option (int, const char *);
|
||
extern void nds32_after_parse_args (void);
|
||
/* The endianness of the target format may change based on command
|
||
line arguments. */
|
||
-extern const char * nds32_target_format (void);
|
||
-
|
||
+extern const char *nds32_target_format (void);
|
||
#define md_parse_option(optc, optarg) nds32_parse_option (optc, optarg)
|
||
#define md_after_parse_args() nds32_after_parse_args ()
|
||
#define TARGET_FORMAT nds32_target_format()
|
||
|
||
-/* expr.c */
|
||
+/* expr.c */
|
||
extern int nds32_parse_name (char const *, expressionS *, enum expr_mode, char *);
|
||
extern bfd_boolean nds32_allow_local_subtract (expressionS *, expressionS *, segT);
|
||
#define md_parse_name(name, exprP, mode, nextcharP) \
|
||
nds32_parse_name (name, exprP, mode, nextcharP)
|
||
#define md_allow_local_subtract(lhs,rhs,sect) nds32_allow_local_subtract (lhs, rhs, sect)
|
||
|
||
-/* dwarf2dbg.c. */
|
||
+/* dwarf2dbg.c */
|
||
#define DWARF2_USE_FIXED_ADVANCE_PC 1
|
||
|
||
-/* write.c. */
|
||
+/* write.c */
|
||
extern long nds32_pcrel_from_section (struct fix *, segT);
|
||
extern bfd_boolean nds32_fix_adjustable (struct fix *);
|
||
extern void nds32_frob_file (void);
|
||
@@ -73,14 +87,13 @@ extern void nds32_frob_file_before_fix (void);
|
||
extern void elf_nds32_final_processing (void);
|
||
extern int nds32_validate_fix_sub (struct fix *, segT);
|
||
extern int nds32_force_relocation (struct fix *);
|
||
-extern void nds32_set_section_relocs (asection *, arelent ** , unsigned int);
|
||
+extern void nds32_set_section_relocs (asection *, arelent **, unsigned int);
|
||
|
||
/* Fill in rs_align_code fragments. TODO: Review this. */
|
||
extern void nds32_handle_align (fragS *);
|
||
extern int nds32_relax_frag (segT, fragS *, long);
|
||
extern int tc_nds32_regname_to_dw2regnum (char *);
|
||
extern void tc_nds32_frame_initial_instructions (void);
|
||
-
|
||
#define MD_PCREL_FROM_SECTION(fix, sect) nds32_pcrel_from_section (fix, sect)
|
||
#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 0
|
||
#define tc_fix_adjustable(FIX) nds32_fix_adjustable (FIX)
|
||
@@ -103,7 +116,7 @@ extern void tc_nds32_frame_initial_instructions (void);
|
||
#define md_relax_frag(segment, fragP, stretch) nds32_relax_frag (segment, fragP, stretch)
|
||
#define WORKING_DOT_WORD /* We don't need to handle .word strangely. */
|
||
/* Using to chain fixup with previous fixup. */
|
||
-#define TC_FIX_TYPE struct fix *
|
||
+#define TC_FIX_TYPE struct fix*
|
||
#define TC_INIT_FIX_DATA(fixP) \
|
||
do \
|
||
{ \
|
||
@@ -111,8 +124,8 @@ extern void tc_nds32_frame_initial_instructions (void);
|
||
} \
|
||
while (0)
|
||
|
||
-/* read.c. */
|
||
-/* Extend GAS macro handling capability. */
|
||
+/* read.c */
|
||
+/* Extend GAS macro handling capability */
|
||
extern void nds32_macro_start (void);
|
||
extern void nds32_macro_end (void);
|
||
extern void nds32_macro_info (void *);
|
||
@@ -128,7 +141,6 @@ extern void nds32_check_label (symbolS *);
|
||
extern void nds32_frob_label (symbolS *);
|
||
extern void nds32_pre_do_align (int, char *, int, int);
|
||
extern void nds32_do_align (int);
|
||
-
|
||
#define md_macro_start() nds32_macro_start ()
|
||
#define md_macro_end() nds32_macro_end ()
|
||
#define md_macro_info(args) nds32_macro_info (args)
|
||
@@ -143,7 +155,7 @@ extern void nds32_do_align (int);
|
||
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
||
nds32_pre_do_align (N, FILL, LEN, MAX); \
|
||
if ((N) > 1 && (subseg_text_p (now_seg) \
|
||
- || strncmp (now_seg->name, ".gcc_except_table", sizeof(".gcc_except_table") - 1) == 0)) \
|
||
+ || strncmp (now_seg->name, ".gcc_except_table", sizeof (".gcc_except_table") - 1) == 0)) \
|
||
nds32_do_align (N); \
|
||
goto LABEL;
|
||
#define md_elf_section_change_hook() nds32_elf_section_change_hook ()
|
||
@@ -151,7 +163,7 @@ extern void nds32_do_align (int);
|
||
#define md_cleanup() nds32_cleanup ()
|
||
#define LOCAL_LABELS_FB 1 /* Permit temporary numeric labels. */
|
||
|
||
-/* frags.c. */
|
||
+/* frags.c */
|
||
|
||
enum FRAG_ATTR
|
||
{
|
||
@@ -161,7 +173,8 @@ enum FRAG_ATTR
|
||
NDS32_FRAG_LABEL = 0x8,
|
||
NDS32_FRAG_FINAL = 0x10,
|
||
NDS32_FRAG_RELAXABLE_BRANCH = 0x20,
|
||
- NDS32_FRAG_ALIGN = 0x40
|
||
+ NDS32_FRAG_ALIGN = 0x40,
|
||
+ NDS32_FRAG_ICT_BRANCH = 0x80
|
||
};
|
||
|
||
struct nds32_frag_type
|
||
@@ -231,7 +244,11 @@ enum nds32_ramp
|
||
NDS32_FIX = (1 << 7),
|
||
NDS32_ADDEND = (1 << 8),
|
||
NDS32_SYM = (1 << 9),
|
||
- NDS32_PCREL = (1 << 10)
|
||
+ NDS32_PCREL = (1 << 10),
|
||
+ NDS32_PTR_PATTERN = (1 << 11),
|
||
+ NDS32_PTR_MULTIPLE = (1 << 12),
|
||
+ NDS32_GROUP = (1 << 13),
|
||
+ NDS32_SYM_DESC_MEM = (1 << 14)
|
||
};
|
||
|
||
typedef struct nds32_relax_fixup_info
|
||
@@ -255,7 +272,7 @@ typedef struct nds32_cond_field
|
||
#define NDS32_MAXCHAR 20
|
||
/* In current, the max extended number of instruction for one pseudo instruction
|
||
is 4, but its number of relocation may be 12. */
|
||
-#define MAX_RELAX_NUM 4
|
||
+#define MAX_RELAX_NUM 6
|
||
#define MAX_RELAX_FIX 12
|
||
|
||
typedef struct nds32_relax_info
|
||
@@ -275,8 +292,18 @@ typedef struct nds32_relax_info
|
||
enum nds32_relax_hint_type
|
||
{
|
||
NDS32_RELAX_HINT_NONE = 0,
|
||
- NDS32_RELAX_HINT_LA,
|
||
- NDS32_RELAX_HINT_LS
|
||
+ NDS32_RELAX_HINT_LA_FLSI,
|
||
+ NDS32_RELAX_HINT_LALS,
|
||
+ NDS32_RELAX_HINT_LA_PLT,
|
||
+ NDS32_RELAX_HINT_LA_GOT,
|
||
+ NDS32_RELAX_HINT_LA_GOTOFF,
|
||
+ NDS32_RELAX_HINT_TLS_START = 0x100,
|
||
+ NDS32_RELAX_HINT_TLS_LE_LS,
|
||
+ NDS32_RELAX_HINT_TLS_IE_LS,
|
||
+ NDS32_RELAX_HINT_TLS_IE_LA,
|
||
+ NDS32_RELAX_HINT_TLS_IEGP_LA,
|
||
+ NDS32_RELAX_HINT_TLS_DESC_LS,
|
||
+ NDS32_RELAX_HINT_ICT_LA,
|
||
};
|
||
|
||
struct nds32_relax_hint_table
|
||
@@ -287,4 +314,4 @@ struct nds32_relax_hint_table
|
||
nds32_relax_fixup_info_t relax_fixup[MAX_RELAX_FIX];
|
||
};
|
||
|
||
-#endif /* TC_NDS32 */
|
||
+#endif /* TC_NDS32 */
|
||
diff --git binutils-2.30/gas/configure binutils-2.30-nds32/gas/configure
|
||
index 0d5422572f..41a83a2998 100755
|
||
--- binutils-2.30/gas/configure
|
||
+++ binutils-2.30-nds32/gas/configure
|
||
@@ -12491,6 +12491,11 @@ _ACEOF
|
||
;;
|
||
|
||
nds32)
|
||
+ # setup NDS32_LINUX_TOOLCHAIN definition
|
||
+ if test "linux" = $em; then
|
||
+$as_echo "#define NDS32_LINUX_TOOLCHAIN 1" >>confdefs.h
|
||
+ fi
|
||
+
|
||
# Decide BASELINE, REDUCED_REGS, FPU_DP_EXT, FPU_SP_EXT features
|
||
# based on arch_name.
|
||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5
|
||
@@ -12582,6 +12587,34 @@ $as_echo "#define NDS32_DEFAULT_AUDIO_EXT 1" >>confdefs.h
|
||
fi
|
||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_audio_ext" >&5
|
||
$as_echo "$enable_audio_ext" >&6; }
|
||
+
|
||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-dsp-ext" >&5
|
||
+$as_echo_n "checking for default configuration of --enable-dsp-ext... " >&6; }
|
||
+ if test "x${enable_dsp_ext}" == xno; then
|
||
+
|
||
+$as_echo "#define NDS32_DEFAULT_DSP_EXT 0" >>confdefs.h
|
||
+
|
||
+ else
|
||
+
|
||
+$as_echo "#define NDS32_DEFAULT_DSP_EXT 1" >>confdefs.h
|
||
+
|
||
+ fi
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dsp_ext" >&5
|
||
+$as_echo "$enable_dsp_ext" >&6; }
|
||
+
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-zol-ext" >&5
|
||
+$as_echo_n "checking for default configuration of --enable-zol-ext... " >&6; }
|
||
+ if test "x${enable_zol_ext}" == xno; then
|
||
+
|
||
+$as_echo "#define NDS32_DEFAULT_ZOL_EXT 0" >>confdefs.h
|
||
+
|
||
+ else
|
||
+
|
||
+$as_echo "#define NDS32_DEFAULT_ZOL_EXT 1" >>confdefs.h
|
||
+
|
||
+ fi
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_zol_ext" >&5
|
||
+$as_echo "$enable_zol_ext" >&6; }
|
||
;;
|
||
|
||
aarch64 | i386 | riscv | s390 | sparc)
|
||
diff --git binutils-2.30/include/dis-asm.h binutils-2.30-nds32/include/dis-asm.h
|
||
index eebdaf874f..5cbe83aad7 100644
|
||
--- binutils-2.30/include/dis-asm.h
|
||
+++ binutils-2.30-nds32/include/dis-asm.h
|
||
@@ -261,11 +261,13 @@ extern void print_arm_disassembler_options (FILE *);
|
||
extern void print_arc_disassembler_options (FILE *);
|
||
extern void print_s390_disassembler_options (FILE *);
|
||
extern void print_wasm32_disassembler_options (FILE *);
|
||
+extern void print_nds32_disassembler_options (FILE *);
|
||
extern bfd_boolean aarch64_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||
extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||
extern void disassemble_init_powerpc (struct disassemble_info *);
|
||
extern void disassemble_init_s390 (struct disassemble_info *);
|
||
extern void disassemble_init_wasm32 (struct disassemble_info *);
|
||
+extern void disassemble_init_nds32 (struct disassemble_info *);
|
||
extern const disasm_options_t *disassembler_options_powerpc (void);
|
||
extern const disasm_options_t *disassembler_options_arm (void);
|
||
extern const disasm_options_t *disassembler_options_s390 (void);
|
||
diff --git binutils-2.30/include/elf/nds32.h binutils-2.30-nds32/include/elf/nds32.h
|
||
index 1b3a3219d0..7250f2bb0c 100644
|
||
--- binutils-2.30/include/elf/nds32.h
|
||
+++ binutils-2.30-nds32/include/elf/nds32.h
|
||
@@ -107,9 +107,9 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
|
||
RELOC_NUMBER (R_NDS32_SDA17S2_RELA, 74)
|
||
RELOC_NUMBER (R_NDS32_SDA18S1_RELA, 75)
|
||
RELOC_NUMBER (R_NDS32_SDA19S0_RELA, 76)
|
||
- RELOC_NUMBER (R_NDS32_DWARF2_OP1_RELA, 77)
|
||
- RELOC_NUMBER (R_NDS32_DWARF2_OP2_RELA, 78)
|
||
- RELOC_NUMBER (R_NDS32_DWARF2_LEB_RELA, 79)
|
||
+ RELOC_NUMBER (R_NDS32_DWARF2_OP1_RELA, 77) /* This is obsoleted. */
|
||
+ RELOC_NUMBER (R_NDS32_DWARF2_OP2_RELA, 78) /* This is obsoleted. */
|
||
+ RELOC_NUMBER (R_NDS32_DWARF2_LEB_RELA, 79) /* This is obsoleted. */
|
||
RELOC_NUMBER (R_NDS32_UPDATE_TA_RELA, 80) /* This is obsoleted. */
|
||
RELOC_NUMBER (R_NDS32_9_PLTREL, 81)
|
||
RELOC_NUMBER (R_NDS32_PLT_GOTREL_LO20, 82)
|
||
@@ -128,15 +128,6 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
|
||
RELOC_NUMBER (R_NDS32_25_ABS_RELA, 95)
|
||
RELOC_NUMBER (R_NDS32_17IFC_PCREL_RELA, 96)
|
||
RELOC_NUMBER (R_NDS32_10IFCU_PCREL_RELA, 97)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_HI20, 98)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_LO12, 99)
|
||
- RELOC_NUMBER (R_NDS32_TLS_IE_HI20, 100)
|
||
- RELOC_NUMBER (R_NDS32_TLS_IE_LO12S2, 101)
|
||
- RELOC_NUMBER (R_NDS32_TLS_TPOFF, 102)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_20, 103)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_15S0, 104)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_15S1, 105)
|
||
- RELOC_NUMBER (R_NDS32_TLS_LE_15S2, 106)
|
||
RELOC_NUMBER (R_NDS32_LONGCALL4, 107)
|
||
RELOC_NUMBER (R_NDS32_LONGCALL5, 108)
|
||
RELOC_NUMBER (R_NDS32_LONGCALL6, 109)
|
||
@@ -144,7 +135,37 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
|
||
RELOC_NUMBER (R_NDS32_LONGJUMP5, 111)
|
||
RELOC_NUMBER (R_NDS32_LONGJUMP6, 112)
|
||
RELOC_NUMBER (R_NDS32_LONGJUMP7, 113)
|
||
+ RELOC_NUMBER (R_NDS32_SECURITY_16, 114)
|
||
+ /* TLS support { */
|
||
+ RELOC_NUMBER (R_NDS32_TLS_TPOFF, 102)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_HI20, 98)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_LO12, 99)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_20, 103)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_15S0, 104)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_15S1, 105)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_LE_15S2, 106)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IE_HI20, 100)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IE_LO12, 115)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IE_LO12S2, 101)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IEGP_HI20, 116)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IEGP_LO12, 117)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IEGP_LO12S2, 118)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC, 119)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_HI20, 120)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_LO12, 121)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_20, 122)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_SDA17S2, 123)
|
||
+ /* TLS support } */
|
||
+ /* new relocation type add here. */
|
||
+ RELOC_NUMBER (R_NDS32_RELOC_NEXT, 124)
|
||
+
|
||
+ /* Jump-patch table relocations. */
|
||
+ RELOC_NUMBER (R_NDS32_ICT_HI20, 125)
|
||
+ RELOC_NUMBER (R_NDS32_ICT_LO12, 126)
|
||
+ RELOC_NUMBER (R_NDS32_ICT_25PC, 127)
|
||
+ RELOC_NUMBER (R_NDS32_ICT_LO12S2, 128)
|
||
|
||
+ /* relax only following */
|
||
RELOC_NUMBER (R_NDS32_RELAX_ENTRY, 192)
|
||
RELOC_NUMBER (R_NDS32_GOT_SUFF, 193)
|
||
RELOC_NUMBER (R_NDS32_GOTOFF_SUFF, 194)
|
||
@@ -164,9 +185,21 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
|
||
RELOC_NUMBER (R_NDS32_DIFF_ULEB128, 208)
|
||
RELOC_NUMBER (R_NDS32_DATA, 209)
|
||
RELOC_NUMBER (R_NDS32_TRAN, 210)
|
||
+ RELOC_NUMBER (R_NDS32_EMPTY, 213)
|
||
+ /* TLS support { */
|
||
RELOC_NUMBER (R_NDS32_TLS_LE_ADD, 211)
|
||
RELOC_NUMBER (R_NDS32_TLS_LE_LS, 212)
|
||
- RELOC_NUMBER (R_NDS32_EMPTY, 213)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_IEGP_LW, 220)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_ADD, 214)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_FUNC, 215)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_CALL, 216)
|
||
+ RELOC_NUMBER (R_NDS32_TLS_DESC_MEM, 217)
|
||
+ RELOC_NUMBER (R_NDS32_RELAX_REMOVE, 218)
|
||
+ RELOC_NUMBER (R_NDS32_RELAX_GROUP, 219)
|
||
+ /* TLS support } */
|
||
+ /* new relaxation type add here. */
|
||
+ RELOC_NUMBER (R_NDS32_LSI, 221)
|
||
+ RELOC_NUMBER (R_NDS32_RELAX_NEXT, 222)
|
||
|
||
END_RELOC_NUMBERS (R_NDS32_max)
|
||
|
||
@@ -259,10 +292,10 @@ END_RELOC_NUMBERS (R_NDS32_max)
|
||
#define E_NDS32_FPU_REG_32SP_32DP 0x3
|
||
/* FPU MAC instruction used. */
|
||
#define E_NDS32_HAS_FPU_MAC_INST 0x01000000
|
||
-/* <<<Empty Check>>>. */
|
||
-#define E_NDS32_NULL 0x02000000
|
||
-/* PIC enabled. */
|
||
-#define E_NDS32_HAS_PIC 0x04000000
|
||
+/* DSP extension. */
|
||
+#define E_NDS32_HAS_DSP_INST 0x02000000
|
||
+/* Hardware zero-overhead loop enabled. */
|
||
+#define E_NDS32_HAS_ZOL (1 << 26)
|
||
/* Use custom section. */
|
||
#define E_NDS32_HAS_CUSTOM_SEC 0x08000000
|
||
|
||
diff --git binutils-2.30/include/opcode/nds32.h binutils-2.30-nds32/include/opcode/nds32.h
|
||
index 4d113be8b8..04a02b5222 100644
|
||
--- binutils-2.30/include/opcode/nds32.h
|
||
+++ binutils-2.30-nds32/include/opcode/nds32.h
|
||
@@ -21,31 +21,32 @@
|
||
#define OPCODE_NDS32_H
|
||
|
||
/* Registers. */
|
||
-#define REG_R5 5
|
||
-#define REG_R8 8
|
||
-#define REG_R10 10
|
||
-#define REG_R12 12
|
||
-#define REG_R15 15
|
||
-#define REG_R16 16
|
||
-#define REG_R20 20
|
||
-#define REG_TA 15
|
||
-#define REG_TP 27
|
||
-#define REG_FP 28
|
||
-#define REG_GP 29
|
||
-#define REG_LP 30
|
||
-#define REG_SP 31
|
||
+#define REG_R0 (0)
|
||
+#define REG_R5 (5)
|
||
+#define REG_R8 (8)
|
||
+#define REG_R10 (10)
|
||
+#define REG_R12 (12)
|
||
+#define REG_R15 (15)
|
||
+#define REG_R16 (16)
|
||
+#define REG_R20 (20)
|
||
+#define REG_TA (15)
|
||
+#define REG_TP (25)
|
||
+#define REG_FP (28)
|
||
+#define REG_GP (29)
|
||
+#define REG_LP (30)
|
||
+#define REG_SP (31)
|
||
|
||
/* Macros for extracting fields or making an instruction. */
|
||
static const int nds32_r45map[] ATTRIBUTE_UNUSED =
|
||
{
|
||
- 0, 1, 2, 3, 4, 5, 6, 7,
|
||
+ 0, 1, 2, 3, 4, 5, 6, 7,
|
||
8, 9, 10, 11, 16, 17, 18, 19
|
||
};
|
||
|
||
static const int nds32_r54map[] ATTRIBUTE_UNUSED =
|
||
{
|
||
- 0, 1, 2, 3, 4, 5, 6, 7,
|
||
- 8, 9, 10, 11, -1, -1, -1, -1,
|
||
+ 0, 1, 2, 3, 4, 5, 6, 7,
|
||
+ 8, 9, 10, 11, -1, -1, -1, -1,
|
||
12, 13, 14, 15, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1
|
||
};
|
||
@@ -146,6 +147,7 @@ static const int nds32_r54map[] ATTRIBUTE_UNUSED =
|
||
#define N32_RD5(insn) (((insn) >> 5) & 0x1f)
|
||
#define N32_SH5(insn) (((insn) >> 5) & 0x1f)
|
||
#define N32_SUB5(insn) (((insn) >> 0) & 0x1f)
|
||
+#define N32_SUB6(insn) (((insn) >> 0) & 0x3f)
|
||
#define N32_SWID(insn) (((insn) >> 5) & 0x3ff)
|
||
#define N32_IMMU(insn, bs) ((insn) & __MASK (bs))
|
||
#define N32_IMMS(insn, bs) ((signed) __SEXT (((insn) & __MASK (bs)), bs))
|
||
@@ -275,7 +277,7 @@ enum n32_opcodes
|
||
N32_BR1_BNE = 1,
|
||
|
||
/* bit[16:19] */
|
||
- N32_BR2_IFCALL = 0,
|
||
+ N32_BR2_SOP0 = 0,
|
||
N32_BR2_BEQZ = 2,
|
||
N32_BR2_BNEZ = 3,
|
||
N32_BR2_BGEZ = 4,
|
||
@@ -365,7 +367,8 @@ enum n32_opcodes
|
||
N32_ALU2_FFZMISM,
|
||
N32_ALU2_KADD = 0x18,
|
||
N32_ALU2_KSUB,
|
||
- N32_ALU2_KSLRA,
|
||
+ N32_ALU2_KSLRAW,
|
||
+ N32_ALU2_KSLRAWu,
|
||
N32_ALU2_MFUSR = 0x20,
|
||
N32_ALU2_MTUSR,
|
||
N32_ALU2_0x22,
|
||
@@ -381,20 +384,173 @@ enum n32_opcodes
|
||
N32_ALU2_MSUB64,
|
||
N32_ALU2_DIVS,
|
||
N32_ALU2_DIV,
|
||
- N32_ALU2_0x30 = 0x30,
|
||
+ N32_ALU2_ADD64 = 0x30,
|
||
N32_ALU2_MULT32,
|
||
- N32_ALU2_0x32,
|
||
+ N32_ALU2_SMAL,
|
||
N32_ALU2_MADD32,
|
||
- N32_ALU2_0x34,
|
||
+ N32_ALU2_SUB64,
|
||
N32_ALU2_MSUB32,
|
||
-
|
||
- /* bit[0:5], where bit[6:9] != 0 */
|
||
+ N32_ALU2_0x36,
|
||
+ N32_ALU2_0x37,
|
||
+ N32_ALU2_RADD64 = 0x38,
|
||
+ N32_ALU2_URADD64,
|
||
+ N32_ALU2_KADD64,
|
||
+ N32_ALU2_UKADD64,
|
||
+ N32_ALU2_RSUB64,
|
||
+ N32_ALU2_URSUB64,
|
||
+ N32_ALU2_KSUB64,
|
||
+ N32_ALU2_UKSUB64,
|
||
+
|
||
+ /* bit[0:5], where bit[6:9] = 0001 */
|
||
+ N32_ALU2_SMAR64 = 0x0,
|
||
+ N32_ALU2_UMAR64,
|
||
+ N32_ALU2_SMSR64,
|
||
+ N32_ALU2_UMSR64,
|
||
+ N32_ALU2_KMAR64,
|
||
+ N32_ALU2_UKMAR64,
|
||
+ N32_ALU2_KMSR64,
|
||
+ N32_ALU2_UKMSR64,
|
||
+ N32_ALU2_SMALDA = 0x8,
|
||
+ N32_ALU2_SMSLDA,
|
||
+ N32_ALU2_SMALDS,
|
||
+ N32_ALU2_SMALBB,
|
||
N32_ALU2_FFBI = 0xe,
|
||
N32_ALU2_FLMISM = 0xf,
|
||
+ N32_ALU2_SMALXDA = 0x10,
|
||
+ N32_ALU2_SMSLXDA,
|
||
+ N32_ALU2_SMALXDS,
|
||
+ N32_ALU2_SMALBT,
|
||
+ N32_ALU2_SMALDRS = 0x1a,
|
||
+ N32_ALU2_SMALTT,
|
||
+ N32_ALU2_RDOV = 0x20,
|
||
+ N32_ALU2_CLROV,
|
||
N32_ALU2_MULSR64 = 0x28,
|
||
N32_ALU2_MULR64 = 0x29,
|
||
- N32_ALU2_MADDR32 = 0x33,
|
||
- N32_ALU2_MSUBR32 = 0x35,
|
||
+ N32_ALU2_SMDS = 0x30,
|
||
+ N32_ALU2_SMXDS,
|
||
+ N32_ALU2_SMDRS,
|
||
+ N32_ALU2_MADDR32,
|
||
+ N32_ALU2_KMADRS,
|
||
+ N32_ALU2_MSUBR32,
|
||
+ N32_ALU2_KMADS,
|
||
+ N32_ALU2_KMAXDS,
|
||
+
|
||
+ /* bit[0:5], where bit[6:9] = 0010 */
|
||
+ N32_ALU2_KADD16 = 0x0,
|
||
+ N32_ALU2_KSUB16,
|
||
+ N32_ALU2_KCRAS16,
|
||
+ N32_ALU2_KCRSA16,
|
||
+ N32_ALU2_KADD8,
|
||
+ N32_ALU2_KSUB8,
|
||
+ N32_ALU2_WEXT,
|
||
+ N32_ALU2_WEXTI,
|
||
+ N32_ALU2_UKADD16 = 0x8,
|
||
+ N32_ALU2_UKSUB16,
|
||
+ N32_ALU2_UKCRAS16,
|
||
+ N32_ALU2_UKCRSA16,
|
||
+ N32_ALU2_UKADD8,
|
||
+ N32_ALU2_UKSUB8,
|
||
+ N32_ALU2_ONEOP = 0xf,
|
||
+ N32_ALU2_SMBB = 0x10,
|
||
+ N32_ALU2_SMBT,
|
||
+ N32_ALU2_SMTT,
|
||
+ N32_ALU2_KMABB = 0x15,
|
||
+ N32_ALU2_KMABT,
|
||
+ N32_ALU2_KMATT,
|
||
+ N32_ALU2_KMDA = 0x18,
|
||
+ N32_ALU2_KMXDA,
|
||
+ N32_ALU2_KMADA,
|
||
+ N32_ALU2_KMAXDA,
|
||
+ N32_ALU2_KMSDA,
|
||
+ N32_ALU2_KMSXDA,
|
||
+ N32_ALU2_RADD16 = 0x20,
|
||
+ N32_ALU2_RSUB16,
|
||
+ N32_ALU2_RCRAS16,
|
||
+ N32_ALU2_RCRSA16,
|
||
+ N32_ALU2_RADD8,
|
||
+ N32_ALU2_RSUB8,
|
||
+ N32_ALU2_RADDW,
|
||
+ N32_ALU2_RSUBW,
|
||
+ N32_ALU2_URADD16 = 0x28,
|
||
+ N32_ALU2_URSUB16,
|
||
+ N32_ALU2_URCRAS16,
|
||
+ N32_ALU2_URCRSA16,
|
||
+ N32_ALU2_URADD8,
|
||
+ N32_ALU2_URSUB8,
|
||
+ N32_ALU2_URADDW,
|
||
+ N32_ALU2_URSUBW,
|
||
+ N32_ALU2_ADD16 = 0x30,
|
||
+ N32_ALU2_SUB16,
|
||
+ N32_ALU2_CRAS16,
|
||
+ N32_ALU2_CRSA16,
|
||
+ N32_ALU2_ADD8,
|
||
+ N32_ALU2_SUB8,
|
||
+ N32_ALU2_BITREV,
|
||
+ N32_ALU2_BITREVI,
|
||
+ N32_ALU2_SMMUL = 0x38,
|
||
+ N32_ALU2_SMMULu,
|
||
+ N32_ALU2_KMMAC,
|
||
+ N32_ALU2_KMMACu,
|
||
+ N32_ALU2_KMMSB,
|
||
+ N32_ALU2_KMMSBu,
|
||
+ N32_ALU2_KWMMUL,
|
||
+ N32_ALU2_KWMMULu,
|
||
+
|
||
+ /* bit[0:5], where bit[6:9] = 0011 */
|
||
+ N32_ALU2_SMMWB = 0x0,
|
||
+ N32_ALU2_SMMWBu,
|
||
+ N32_ALU2_SMMWT,
|
||
+ N32_ALU2_SMMWTu,
|
||
+ N32_ALU2_KMMAWB,
|
||
+ N32_ALU2_KMMAWBu,
|
||
+ N32_ALU2_KMMAWT,
|
||
+ N32_ALU2_KMMAWTu,
|
||
+ N32_ALU2_PKTT16 = 0x8,
|
||
+ N32_ALU2_PKTB16,
|
||
+ N32_ALU2_PKBT16,
|
||
+ N32_ALU2_PKBB16,
|
||
+ N32_ALU2_0x10 = 0x10,
|
||
+ N32_ALU2_SCLIP16,
|
||
+ N32_ALU2_0x12,
|
||
+ N32_ALU2_SMAX16,
|
||
+ N32_ALU2_SMAX8 = 0x17,
|
||
+ N32_ALU2_0x18 = 0x18,
|
||
+ N32_ALU2_UCLIP16,
|
||
+ N32_ALU2_0x1a,
|
||
+ N32_ALU2_UMAX16,
|
||
+ N32_ALU2_UMAX8 = 0x1f,
|
||
+ N32_ALU2_SRA16 = 0x20,
|
||
+ N32_ALU2_SRA16u,
|
||
+ N32_ALU2_SRL16,
|
||
+ N32_ALU2_SRL16u,
|
||
+ N32_ALU2_SLL16,
|
||
+ N32_ALU2_KSLRA16,
|
||
+ N32_ALU2_KSLRA16u,
|
||
+ N32_ALU2_SRAu,
|
||
+ N32_ALU2_SRAI16 = 0x28,
|
||
+ N32_ALU2_SRAI16u,
|
||
+ N32_ALU2_SRLI16,
|
||
+ N32_ALU2_SRLI16u,
|
||
+ N32_ALU2_SLLI16,
|
||
+ N32_ALU2_KSLLI16,
|
||
+ N32_ALU2_KSLLI,
|
||
+ N32_ALU2_SRAIu,
|
||
+ N32_ALU2_CMPEQ16 = 0x30,
|
||
+ N32_ALU2_SCMPLT16,
|
||
+ N32_ALU2_SCMPLE16,
|
||
+ N32_ALU2_SMIN16,
|
||
+ N32_ALU2_CMPEQ8,
|
||
+ N32_ALU2_SCMPLT8,
|
||
+ N32_ALU2_SCMPLE8,
|
||
+ N32_ALU2_SMIN8,
|
||
+ N32_ALU2_0x38,
|
||
+ N32_ALU2_UCMPLT16 = 0x39,
|
||
+ N32_ALU2_UCMPLE16,
|
||
+ N32_ALU2_UMIN16,
|
||
+ N32_ALU2_0x3c,
|
||
+ N32_ALU2_UCMPLT8,
|
||
+ N32_ALU2_UCMPLE8,
|
||
+ N32_ALU2_UMIN8,
|
||
|
||
/* bit[0:5] */
|
||
N32_MEM_LB = 0,
|
||
@@ -459,7 +615,8 @@ enum n32_opcodes
|
||
N32_MISC_MSYNC,
|
||
N32_MISC_ISYNC,
|
||
N32_MISC_TLBOP,
|
||
- N32_MISC_0xf,
|
||
+ N32_MISC_SPECL,
|
||
+ N32_MISC_BPICK = 0x10,
|
||
|
||
/* bit[0:4] */
|
||
N32_SIMD_PBSAD = 0,
|
||
@@ -582,7 +739,7 @@ enum n32_opcodes
|
||
N32_FPU_MTCP_XR = 0xc,
|
||
|
||
/* MTCP/XR b[14:10] */
|
||
- N32_FPU_MTCP_XR_FMTCSR = 0x1
|
||
+ N32_FPU_MTCP_XR_FMTCSR = 0x1,
|
||
};
|
||
|
||
enum n16_opcodes
|
||
@@ -675,7 +832,7 @@ enum n16_opcodes
|
||
N16_BFMI333_XLSB33 = 4,
|
||
N16_BFMI333_X11B33 = 5,
|
||
N16_BFMI333_BMSKI33 = 6,
|
||
- N16_BFMI333_FEXTI33 = 7
|
||
+ N16_BFMI333_FEXTI33 = 7,
|
||
};
|
||
|
||
/* These macros a deprecated. DO NOT use them anymore.
|
||
@@ -704,6 +861,7 @@ enum n16_opcodes
|
||
#define INSN_ANDI 0x54000000
|
||
#define INSN_LDI 0x06000000
|
||
#define INSN_SDI 0x16000000
|
||
+#define INSN_LW 0x38000002
|
||
#define INSN_LWI 0x04000000
|
||
#define INSN_LWSI 0x24000000
|
||
#define INSN_LWIP 0x0c000000
|
||
diff --git binutils-2.30/ld/config.in binutils-2.30-nds32/ld/config.in
|
||
index a846743da6..9cc2f6303a 100644
|
||
--- binutils-2.30/ld/config.in
|
||
+++ binutils-2.30-nds32/ld/config.in
|
||
@@ -63,9 +63,18 @@
|
||
*/
|
||
#undef HAVE_DIRENT_H
|
||
|
||
+/* Define to 1 if you have the `dlclose' function. */
|
||
+#undef HAVE_DLCLOSE
|
||
+
|
||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||
#undef HAVE_DLFCN_H
|
||
|
||
+/* Define to 1 if you have the `dlopen' function. */
|
||
+#undef HAVE_DLOPEN
|
||
+
|
||
+/* Define to 1 if you have the `dlsym' function. */
|
||
+#undef HAVE_DLSYM
|
||
+
|
||
/* Define to 1 if you have the <elf-hints.h> header file. */
|
||
#undef HAVE_ELF_HINTS_H
|
||
|
||
@@ -168,6 +177,9 @@
|
||
*/
|
||
#undef LT_OBJDIR
|
||
|
||
+/* Define if linux toolchain is to be built. */
|
||
+#undef NDS32_LINUX_TOOLCHAIN
|
||
+
|
||
/* Name of package */
|
||
#undef PACKAGE
|
||
|
||
diff --git binutils-2.30/ld/configure binutils-2.30-nds32/ld/configure
|
||
index 48606ae36b..732630063d 100755
|
||
--- binutils-2.30/ld/configure
|
||
+++ binutils-2.30-nds32/ld/configure
|
||
@@ -17165,6 +17165,53 @@ do
|
||
|
||
. ${srcdir}/configure.tgt
|
||
|
||
+ case ${target_cpu} in
|
||
+ nds32*)
|
||
+ case ${targ} in
|
||
+ *-*-linux*)
|
||
+
|
||
+$as_echo "#define NDS32_LINUX_TOOLCHAIN 1" >>confdefs.h
|
||
+
|
||
+ ;;
|
||
+ esac
|
||
+
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-ifc-ext" >&5
|
||
+$as_echo_n "checking for default configuration of --enable-ifc-ext... " >&6; }
|
||
+ if test "x${enable_ifc_ext}" == xyes; then
|
||
+
|
||
+$as_echo "#define NDS32_IFC_EXT 1" >>confdefs.h
|
||
+
|
||
+ fi
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ifc_ext" >&5
|
||
+$as_echo "$enable_ifc_ext" >&6; }
|
||
+
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-ex9-ext" >&5
|
||
+$as_echo_n "checking for default configuration of --enable-ex9-ext... " >&6; }
|
||
+ if test "x${enable_ex9_ext}" == xyes; then
|
||
+
|
||
+$as_echo "#define NDS32_EX9_EXT 1" >>confdefs.h
|
||
+
|
||
+ fi
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ex9_ext" >&5
|
||
+$as_echo "$enable_ex9_ext" >&6; }
|
||
+
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-16m-addr" >&5
|
||
+$as_echo_n "checking for default configuration of --enable-16m-addr... " >&6; }
|
||
+ if test "x${enable_16m_addr}" == xyes; then
|
||
+ case ${targ} in
|
||
+ nds32*le-*-elf*)
|
||
+ targ_emul=nds32elf16m
|
||
+ ;;
|
||
+ nds32*be-*-elf*)
|
||
+ targ_emul=nds32belf16m
|
||
+ ;;
|
||
+ esac
|
||
+ fi
|
||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_16m-addr" >&5
|
||
+$as_echo "$enable_16m-addr" >&6; }
|
||
+ ;;
|
||
+ esac
|
||
+
|
||
if test "$targ" = "$target"; then
|
||
EMUL=$targ_emul
|
||
fi
|
||
diff --git binutils-2.30/ld/configure.tgt binutils-2.30-nds32/ld/configure.tgt
|
||
index 6183a85b3d..b3d285faaa 100644
|
||
--- binutils-2.30/ld/configure.tgt
|
||
+++ binutils-2.30-nds32/ld/configure.tgt
|
||
@@ -583,8 +583,8 @@ nds32*le-*-elf*) targ_emul=nds32elf
|
||
nds32*be-*-elf*) targ_emul=nds32belf
|
||
targ_extra_emuls="nds32elf nds32elf16m nds32belf16m"
|
||
;;
|
||
-nds32*le-*-linux-gnu*) targ_emul=nds32elf_linux ;;
|
||
-nds32*be-*-linux-gnu*) targ_emul=nds32belf_linux ;;
|
||
+nds32*le-*-linux*) targ_emul=nds32elf_linux ;;
|
||
+nds32*be-*-linux*) targ_emul=nds32belf_linux ;;
|
||
nios2*-*-linux*) targ_emul=nios2linux ;;
|
||
nios2*-*-*) targ_emul=nios2elf ;;
|
||
ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;;
|
||
diff --git binutils-2.30/ld/emulparams/nds32elf.sh binutils-2.30-nds32/ld/emulparams/nds32elf.sh
|
||
index f0a7c31329..e2fde5d0a2 100644
|
||
--- binutils-2.30/ld/emulparams/nds32elf.sh
|
||
+++ binutils-2.30-nds32/ld/emulparams/nds32elf.sh
|
||
@@ -14,5 +14,9 @@ MAXPAGESIZE=0x20
|
||
EMBEDDED=yes
|
||
COMMONPAGESIZE=0x20
|
||
|
||
-# Use external linker script files.
|
||
-COMPILE_IN=no
|
||
+# Instruct genscripts.sh not to compile scripts in by COMPILE_IN
|
||
+# in order to use external linker scripts files.
|
||
+EMULATION_LIBPATH=
|
||
+
|
||
+GENERATE_SHLIB_SCRIPT=yes
|
||
+GENERATE_PIE_SCRIPT=yes
|
||
diff --git binutils-2.30/ld/emulparams/nds32elf16m.sh binutils-2.30-nds32/ld/emulparams/nds32elf16m.sh
|
||
index deb8699004..7d3b063abd 100644
|
||
--- binutils-2.30/ld/emulparams/nds32elf16m.sh
|
||
+++ binutils-2.30-nds32/ld/emulparams/nds32elf16m.sh
|
||
@@ -14,5 +14,6 @@ MAXPAGESIZE=0x20
|
||
EMBEDDED=yes
|
||
COMMONPAGESIZE=0x20
|
||
|
||
-# Use external linker script files.
|
||
-COMPILE_IN=no
|
||
+# Instruct genscripts.sh not to compile scripts in by COMPILE_IN
|
||
+# in order to use external linker scripts files.
|
||
+EMULATION_LIBPATH=
|
||
diff --git binutils-2.30/ld/emulparams/nds32elf_linux.sh binutils-2.30-nds32/ld/emulparams/nds32elf_linux.sh
|
||
index 1145c0eeea..6d89f7924f 100644
|
||
--- binutils-2.30/ld/emulparams/nds32elf_linux.sh
|
||
+++ binutils-2.30-nds32/ld/emulparams/nds32elf_linux.sh
|
||
@@ -31,5 +31,6 @@ fi
|
||
GENERATE_SHLIB_SCRIPT=yes
|
||
GENERATE_PIE_SCRIPT=yes
|
||
|
||
-# Use external linker script files.
|
||
-COMPILE_IN=no
|
||
+# Instruct genscripts.sh not to compile scripts in by COMPILE_IN
|
||
+# in order to use external linker scripts files.
|
||
+EMULATION_LIBPATH=
|
||
diff --git binutils-2.30/ld/emultempl/elf32.em binutils-2.30-nds32/ld/emultempl/elf32.em
|
||
index c0925fc9b9..e5f109d3ce 100644
|
||
--- binutils-2.30/ld/emultempl/elf32.em
|
||
+++ binutils-2.30-nds32/ld/emultempl/elf32.em
|
||
@@ -114,7 +114,7 @@ fi
|
||
if test x"$LDEMUL_AFTER_PARSE" != xgld"$EMULATION_NAME"_after_parse; then
|
||
fragment <<EOF
|
||
|
||
-static void
|
||
+ATTRIBUTE_UNUSED static void
|
||
gld${EMULATION_NAME}_after_parse (void)
|
||
{
|
||
if (bfd_link_pie (&link_info))
|
||
diff --git binutils-2.30/ld/emultempl/nds32elf.em binutils-2.30-nds32/ld/emultempl/nds32elf.em
|
||
index 27b3b0c2b7..123c6ca2f9 100644
|
||
--- binutils-2.30/ld/emultempl/nds32elf.em
|
||
+++ binutils-2.30-nds32/ld/emultempl/nds32elf.em
|
||
@@ -22,25 +22,23 @@
|
||
|
||
fragment <<EOF
|
||
|
||
+#include "libbfd.h"
|
||
#include "elf-bfd.h"
|
||
#include "elf/nds32.h"
|
||
-#include "bfd_stdint.h"
|
||
#include "elf32-nds32.h"
|
||
+#include "bfd_stdint.h"
|
||
|
||
static int relax_fp_as_gp = 1; /* --mrelax-omit-fp */
|
||
static int eliminate_gc_relocs = 0; /* --meliminate-gc-relocs */
|
||
static FILE *sym_ld_script = NULL; /* --mgen-symbol-ld-script=<file> */
|
||
+static int hyper_relax = 1; /* --mhyper-relax */
|
||
/* Disable if linking a dynamically linked executable. */
|
||
static int load_store_relax = 1;
|
||
static int target_optimize = 0; /* Switch optimization. */
|
||
static int relax_status = 0; /* Finished optimization. */
|
||
static int relax_round = 0; /* Going optimization. */
|
||
-static FILE *ex9_export_file = NULL; /* --mexport-ex9=<file> */
|
||
-static FILE *ex9_import_file = NULL; /* --mimport-ex9=<file> */
|
||
-static int update_ex9_table = 0; /* --mupdate-ex9. */
|
||
-static int ex9_limit = 511;
|
||
-static bfd_boolean ex9_loop_aware = FALSE; /* Ignore ex9 if inside a loop. */
|
||
-static bfd_boolean ifc_loop_aware = FALSE; /* Ignore ifc if inside a loop. */
|
||
+static int tls_desc_trampoline = 0; /* --m[no]tlsdesc-trampoline. */
|
||
+static char *set_output_abi = NULL; /* --mabi. */
|
||
|
||
/* Save the target options into output bfd to avoid using to many global
|
||
variables. Do this after the output has been created, but before
|
||
@@ -61,39 +59,41 @@ nds32_elf_create_output_section_statements (void)
|
||
sym_ld_script,
|
||
load_store_relax,
|
||
target_optimize, relax_status, relax_round,
|
||
- ex9_export_file, ex9_import_file,
|
||
- update_ex9_table, ex9_limit,
|
||
- ex9_loop_aware, ifc_loop_aware);
|
||
+ hyper_relax,
|
||
+ tls_desc_trampoline,
|
||
+ set_output_abi);
|
||
}
|
||
|
||
static void
|
||
nds32_elf_after_parse (void)
|
||
{
|
||
+#ifdef NDS32_LINUX_TOOLCHAIN
|
||
+ if (RELAXATION_ENABLED)
|
||
+ {
|
||
+ einfo ("%P: warning: The relaxation isn't supported yet.\n");
|
||
+ DISABLE_RELAXATION;
|
||
+ }
|
||
+#endif
|
||
+
|
||
if (bfd_link_relocatable (&link_info))
|
||
DISABLE_RELAXATION;
|
||
|
||
if (!RELAXATION_ENABLED)
|
||
{
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
|
||
+ target_optimize &= ~(NDS32_RELAX_IFC_ON | NDS32_RELAX_EX9_ON);
|
||
relax_fp_as_gp = 0;
|
||
}
|
||
|
||
- if (ex9_import_file != NULL)
|
||
- {
|
||
- ex9_export_file = NULL;
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
|
||
- }
|
||
- else
|
||
- update_ex9_table = 0;
|
||
-
|
||
if (bfd_link_pic (&link_info))
|
||
{
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
|
||
+ target_optimize &= ~(NDS32_RELAX_IFC_ON | NDS32_RELAX_EX9_ON);
|
||
}
|
||
|
||
- gld${EMULATION_NAME}_after_parse ();
|
||
+ after_parse_default ();
|
||
+
|
||
+ /* Backward compatible for linker script output_format. */
|
||
+ if (output_target && strcmp (output_target, "elf32-nds32") == 0)
|
||
+ output_target = default_target;
|
||
}
|
||
|
||
static void
|
||
@@ -107,10 +107,15 @@ nds32_elf_after_open (void)
|
||
We may try to merge object files with different architecture together. */
|
||
for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
|
||
{
|
||
- if (arch_ver == (unsigned int)-1 && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH))
|
||
+ if (arch_ver == (unsigned int)-1
|
||
+ && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH))
|
||
arch_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ARCH ;
|
||
|
||
- if (abi_ver == (unsigned int)-1)
|
||
+ if (set_output_abi != NULL)
|
||
+ {
|
||
+ /* do not check ABI. */
|
||
+ }
|
||
+ else if (abi_ver == (unsigned int)-1)
|
||
{
|
||
/* Initialize ABI version, if not ABI0.
|
||
(OS uses empty file to create empty ELF with ABI0). */
|
||
@@ -120,67 +125,34 @@ nds32_elf_after_open (void)
|
||
else if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0
|
||
&& abi_ver != (elf_elfheader (abfd)->e_flags & EF_NDS_ABI))
|
||
{
|
||
+ asection *section = NULL;
|
||
+ bfd_byte *contents = NULL;
|
||
+ section = bfd_get_section_by_name (abfd, ".note.v2abi_compatible");
|
||
+ if (section)
|
||
+ bfd_get_full_section_contents (abfd, section, &contents);
|
||
+
|
||
/* Incompatible objects. */
|
||
- einfo (_("%F%B: ABI version of object files mismatched\n"), abfd);
|
||
+ if ((contents == NULL)
|
||
+ || bfd_getb32 (contents) != 1
|
||
+ || abi_ver != E_NDS_ABI_V2FP_PLUS)
|
||
+ einfo (_("%F%B: ABI version of object files mismatched\n"), abfd);
|
||
}
|
||
|
||
-#if defined NDS32_EX9_EXT
|
||
- /* Append .ex9.itable section in the last input object file. */
|
||
- if (abfd->link_next == NULL && (target_optimize & NDS32_RELAX_EX9_ON))
|
||
- {
|
||
- asection *itable;
|
||
- struct bfd_link_hash_entry *h;
|
||
- itable = bfd_make_section_with_flags (abfd, ".ex9.itable",
|
||
- SEC_CODE | SEC_ALLOC | SEC_LOAD
|
||
- | SEC_HAS_CONTENTS | SEC_READONLY
|
||
- | SEC_IN_MEMORY | SEC_KEEP);
|
||
- if (itable)
|
||
- {
|
||
- itable->gc_mark = 1;
|
||
- itable->alignment_power = 2;
|
||
- itable->size = 0x1000;
|
||
- itable->contents = bfd_zalloc (abfd, itable->size);
|
||
-
|
||
- /* Add a symbol in the head of ex9.itable to objdump clearly. */
|
||
- h = bfd_link_hash_lookup (link_info.hash, "_EX9_BASE_",
|
||
- FALSE, FALSE, FALSE);
|
||
- _bfd_generic_link_add_one_symbol
|
||
- (&link_info, link_info.output_bfd, "_EX9_BASE_",
|
||
- BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE,
|
||
- get_elf_backend_data (link_info.output_bfd)->collect, &h);
|
||
- }
|
||
- }
|
||
-#endif
|
||
+ /* Append target needed section in the last input object file. */
|
||
+ if (abfd->link.next == NULL)
|
||
+ bfd_elf32_nds32_append_section (&link_info, abfd);
|
||
}
|
||
|
||
/* Check object files if the target is dynamic linked executable
|
||
or shared object. */
|
||
if (elf_hash_table (&link_info)->dynamic_sections_created
|
||
- || bfd_link_pic (&link_info))
|
||
+ || bfd_link_pic (&link_info) || bfd_link_pie (&link_info))
|
||
{
|
||
- for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
|
||
- {
|
||
- if (!(elf_elfheader (abfd)->e_flags & E_NDS32_HAS_PIC))
|
||
- {
|
||
- /* Non-PIC object file is used. */
|
||
- if (bfd_link_pic (&link_info))
|
||
- {
|
||
- /* For PIE or shared object, all input must be PIC. */
|
||
- einfo (_("%B: must use -fpic to compile this file "
|
||
- "for shared object or PIE\n"), abfd);
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Dynamic linked executable with SDA and non-PIC.
|
||
- Turn off load/store relaxtion. */
|
||
- /* TODO: This may support in the future. */
|
||
- load_store_relax = 0 ;
|
||
- relax_fp_as_gp = 0;
|
||
- }
|
||
- }
|
||
- }
|
||
- /* Turn off relax when building shared object or PIE
|
||
- until we can support their relaxation. */
|
||
+ /* Dynamic linked executable with SDA and non-PIC.
|
||
+ Turn off load/store relaxtion. */
|
||
+ /* TODO: This may support in the future. */
|
||
+ load_store_relax = 0 ;
|
||
+ relax_fp_as_gp = 0;
|
||
}
|
||
|
||
/* Call the standard elf routine. */
|
||
@@ -190,19 +162,26 @@ nds32_elf_after_open (void)
|
||
static void
|
||
nds32_elf_after_allocation (void)
|
||
{
|
||
- if (target_optimize & NDS32_RELAX_EX9_ON
|
||
- || (ex9_import_file != NULL && update_ex9_table == 1))
|
||
- {
|
||
- /* Initialize ex9 hash table. */
|
||
- if (!nds32_elf_ex9_init ())
|
||
- return;
|
||
- }
|
||
+ struct bfd_link_hash_entry *h;
|
||
|
||
/* Call default after allocation callback.
|
||
1. This is where relaxation is done.
|
||
2. It calls gld${EMULATION_NAME}_map_segments to build ELF segment table.
|
||
3. Any relaxation requires relax being done must be called after it. */
|
||
gld${EMULATION_NAME}_after_allocation ();
|
||
+
|
||
+ /* Add a symbol for linker script check the max size. */
|
||
+ if (link_info.output_bfd->sections)
|
||
+ {
|
||
+ h = bfd_link_hash_lookup (link_info.hash, "_RELAX_END_",
|
||
+ FALSE, FALSE, FALSE);
|
||
+ if (!h)
|
||
+ _bfd_generic_link_add_one_symbol
|
||
+ (&link_info, link_info.output_bfd, "_RELAX_END_",
|
||
+ BSF_GLOBAL | BSF_WEAK, link_info.output_bfd->sections,
|
||
+ 0, (const char *) NULL, FALSE,
|
||
+ get_elf_backend_data (link_info.output_bfd)->collect, &h);
|
||
+ }
|
||
}
|
||
|
||
EOF
|
||
@@ -217,31 +196,19 @@ PARSE_AND_LIST_PROLOGUE='
|
||
#define OPTION_REDUCE_FP_UPDATE (OPTION_BASELINE + 4)
|
||
#define OPTION_NO_REDUCE_FP_UPDATE (OPTION_BASELINE + 5)
|
||
#define OPTION_EXPORT_SYMBOLS (OPTION_BASELINE + 6)
|
||
-
|
||
-/* These are only available to ex9. */
|
||
-#if defined NDS32_EX9_EXT
|
||
-#define OPTION_EX9_BASELINE 320
|
||
-#define OPTION_EX9_TABLE (OPTION_EX9_BASELINE + 1)
|
||
-#define OPTION_NO_EX9_TABLE (OPTION_EX9_BASELINE + 2)
|
||
-#define OPTION_EXPORT_EX9 (OPTION_EX9_BASELINE + 3)
|
||
-#define OPTION_IMPORT_EX9 (OPTION_EX9_BASELINE + 4)
|
||
-#define OPTION_UPDATE_EX9 (OPTION_EX9_BASELINE + 5)
|
||
-#define OPTION_EX9_LIMIT (OPTION_EX9_BASELINE + 6)
|
||
-#define OPTION_EX9_LOOP (OPTION_EX9_BASELINE + 7)
|
||
-#endif
|
||
-
|
||
-/* These are only available to link-time ifc. */
|
||
-#if defined NDS32_IFC_EXT
|
||
-#define OPTION_IFC_BASELINE 340
|
||
-#define OPTION_JUMP_IFC (OPTION_IFC_BASELINE + 1)
|
||
-#define OPTION_NO_JUMP_IFC (OPTION_IFC_BASELINE + 2)
|
||
-#define OPTION_IFC_LOOP (OPTION_IFC_BASELINE + 3)
|
||
-#endif
|
||
+#define OPTION_HYPER_RELAX (OPTION_BASELINE + 7)
|
||
+#define OPTION_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 8)
|
||
+#define OPTION_NO_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 9)
|
||
+#define OPTION_SET_ABI (OPTION_BASELINE + 10)
|
||
'
|
||
PARSE_AND_LIST_LONGOPTS='
|
||
{ "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP},
|
||
{ "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP},
|
||
{ "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
|
||
+ { "mhyper-relax", required_argument, NULL, OPTION_HYPER_RELAX},
|
||
+ { "mtlsdesc-trampoline", no_argument, NULL, OPTION_TLSDESC_TRAMPOLINE},
|
||
+ { "mno-tlsdesc-trampoline", no_argument, NULL, OPTION_NO_TLSDESC_TRAMPOLINE},
|
||
+ { "mabi", required_argument, NULL, OPTION_SET_ABI},
|
||
/* These are deprecated options. Remove them in the future. */
|
||
{ "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE},
|
||
{ "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE},
|
||
@@ -250,46 +217,14 @@ PARSE_AND_LIST_LONGOPTS='
|
||
{ "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP},
|
||
{ "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP},
|
||
{ "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
|
||
- /* These are specific optioins for ex9-ext support. */
|
||
-#if defined NDS32_EX9_EXT
|
||
- { "mex9", no_argument, NULL, OPTION_EX9_TABLE},
|
||
- { "mno-ex9", no_argument, NULL, OPTION_NO_EX9_TABLE},
|
||
- { "mexport-ex9", required_argument, NULL, OPTION_EXPORT_EX9},
|
||
- { "mimport-ex9", required_argument, NULL, OPTION_IMPORT_EX9},
|
||
- { "mupdate-ex9", no_argument, NULL, OPTION_UPDATE_EX9},
|
||
- { "mex9-limit", required_argument, NULL, OPTION_EX9_LIMIT},
|
||
- { "mex9-loop-aware", no_argument, NULL, OPTION_EX9_LOOP},
|
||
-#endif
|
||
- /* These are specific optioins for ifc-ext support. */
|
||
-#if defined NDS32_IFC_EXT
|
||
- { "mifc", no_argument, NULL, OPTION_JUMP_IFC},
|
||
- { "mno-ifc", no_argument, NULL, OPTION_NO_JUMP_IFC},
|
||
- { "mifc-loop-aware", no_argument, NULL, OPTION_IFC_LOOP},
|
||
-#endif
|
||
'
|
||
PARSE_AND_LIST_OPTIONS='
|
||
fprintf (file, _("\
|
||
--m[no-]fp-as-gp Disable/enable fp-as-gp relaxation\n\
|
||
--mexport-symbols=FILE Exporting symbols in linker script\n\
|
||
+ --mhyper-relax=level Adjust relax level (low|medium|high). default: medium\n\
|
||
+ --m[no-]tlsdesc-trampoline Disable/enable TLS DESC trampoline\n\
|
||
"));
|
||
-
|
||
-#if defined NDS32_EX9_EXT
|
||
- fprintf (file, _("\
|
||
- --m[no-]ex9 Disable/enable link-time EX9 relaxation\n\
|
||
- --mexport-ex9=FILE Export EX9 table after linking\n\
|
||
- --mimport-ex9=FILE Import Ex9 table for EX9 relaxation\n\
|
||
- --mupdate-ex9 Update existing EX9 table\n\
|
||
- --mex9-limit=NUM Maximum number of entries in ex9 table\n\
|
||
- --mex9-loop-aware Avoid generate EX9 instruction inside loop\n\
|
||
-"));
|
||
-#endif
|
||
-
|
||
-#if defined NDS32_IFC_EXT
|
||
- fprintf (file, _("\
|
||
- --m[no-]ifc Disable/enable link-time IFC optimization\n\
|
||
- --mifc-loop-aware Avoid generate IFC instruction inside loop\n\
|
||
-"));
|
||
-#endif
|
||
'
|
||
PARSE_AND_LIST_ARGS_CASES='
|
||
case OPTION_BASELINE:
|
||
@@ -319,65 +254,33 @@ PARSE_AND_LIST_ARGS_CASES='
|
||
einfo (_("%P%F: cannot open map file %s: %E.\n"), optarg);
|
||
}
|
||
break;
|
||
-#if defined NDS32_EX9_EXT
|
||
- case OPTION_EX9_TABLE:
|
||
- target_optimize = target_optimize | NDS32_RELAX_EX9_ON;
|
||
- break;
|
||
- case OPTION_NO_EX9_TABLE:
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
|
||
- break;
|
||
- case OPTION_EXPORT_EX9:
|
||
+ case OPTION_HYPER_RELAX:
|
||
if (!optarg)
|
||
- einfo (_("Missing file for --mexport-ex9=<file>.\n"));
|
||
+ einfo (_("Valid arguments to --mhyper-relax=(low|medium|high).\n"));
|
||
|
||
- if(strcmp (optarg, "-") == 0)
|
||
- ex9_export_file = stdout;
|
||
+ if (strcmp (optarg, "low") == 0)
|
||
+ hyper_relax = 0;
|
||
+ else if (strcmp (optarg, "medium") == 0)
|
||
+ hyper_relax = 1;
|
||
+ else if (strcmp (optarg, "high") == 0)
|
||
+ hyper_relax = 2;
|
||
else
|
||
- {
|
||
- ex9_export_file = fopen (optarg, "wb");
|
||
- if(ex9_export_file == NULL)
|
||
- einfo (_("ERROR %P%F: cannot open ex9 export file %s.\n"), optarg);
|
||
- }
|
||
- break;
|
||
- case OPTION_IMPORT_EX9:
|
||
- if (!optarg)
|
||
- einfo (_("Missing file for --mimport-ex9=<file>.\n"));
|
||
+ einfo (_("Valid arguments to --mhyper-relax=(low|medium|high).\n"));
|
||
|
||
- ex9_import_file = fopen (optarg, "rb+");
|
||
- if(ex9_import_file == NULL)
|
||
- einfo (_("ERROR %P%F: cannot open ex9 import file %s.\n"), optarg);
|
||
+ break;
|
||
+ case OPTION_TLSDESC_TRAMPOLINE:
|
||
+ tls_desc_trampoline = 1;
|
||
break;
|
||
- case OPTION_UPDATE_EX9:
|
||
- update_ex9_table = 1;
|
||
- break;
|
||
- case OPTION_EX9_LIMIT:
|
||
- if (optarg)
|
||
- {
|
||
- ex9_limit = atoi (optarg);
|
||
- if (ex9_limit > 511 || ex9_limit < 1)
|
||
- {
|
||
- einfo (_("ERROR: the range of ex9_limit must between 1 and 511\n"));
|
||
- exit (1);
|
||
- }
|
||
- }
|
||
+ case OPTION_NO_TLSDESC_TRAMPOLINE:
|
||
+ tls_desc_trampoline = 0;
|
||
break;
|
||
- case OPTION_EX9_LOOP:
|
||
- target_optimize = target_optimize | NDS32_RELAX_EX9_ON;
|
||
- ex9_loop_aware = 1;
|
||
- break;
|
||
-#endif
|
||
-#if defined NDS32_IFC_EXT
|
||
- case OPTION_JUMP_IFC:
|
||
- target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON;
|
||
- break;
|
||
- case OPTION_NO_JUMP_IFC:
|
||
- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
|
||
- break;
|
||
- case OPTION_IFC_LOOP:
|
||
- target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON;
|
||
- ifc_loop_aware = 1;
|
||
+ case OPTION_SET_ABI:
|
||
+ if (strcmp (optarg, "AABI") != 0
|
||
+ && strcmp (optarg, "V2FP+") != 0)
|
||
+ einfo (_("Valid arguments to --mabi=(AABI|V2FP+).\n"));
|
||
+ else
|
||
+ set_output_abi = optarg;
|
||
break;
|
||
-#endif
|
||
'
|
||
LDEMUL_AFTER_OPEN=nds32_elf_after_open
|
||
LDEMUL_AFTER_PARSE=nds32_elf_after_parse
|
||
diff --git binutils-2.30/ld/scripttempl/nds32elf.sc binutils-2.30-nds32/ld/scripttempl/nds32elf.sc
|
||
index dd9a0c11f7..6c09275e4d 100644
|
||
--- binutils-2.30/ld/scripttempl/nds32elf.sc
|
||
+++ binutils-2.30-nds32/ld/scripttempl/nds32elf.sc
|
||
@@ -185,7 +185,7 @@ test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS="
|
||
*(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
|
||
${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
|
||
}"
|
||
-if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
|
||
+if test "${ENABLE_INITFINI_ARRAY}" = "no"; then
|
||
SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))"
|
||
SORT_FINI_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))"
|
||
CTORS_IN_INIT_ARRAY="EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o $OTHER_EXCLUDE_FILES) .ctors"
|
||
@@ -335,6 +335,9 @@ eval $COMBRELOCCAT <<EOF
|
||
.rela.init ${RELOCATING-0} : { *(.rela.init) }
|
||
.rel.text ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) }
|
||
.rela.text ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) }
|
||
+
|
||
+ ${RELOCATING+PROVIDE (__rel_dyn_start = .);}
|
||
+
|
||
.rel.fini ${RELOCATING-0} : { *(.rel.fini) }
|
||
.rela.fini ${RELOCATING-0} : { *(.rela.fini) }
|
||
.rel.${RODATA_NAME} ${RELOCATING-0} : { *(.rel.${RODATA_NAME}${RELOCATING+ .rel.${RODATA_NAME}.* .rel.gnu.linkonce.r.*}) }
|
||
@@ -402,6 +405,9 @@ cat >> ldscripts/dyntmp.$$ <<EOF
|
||
${IREL_IN_PLT+${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__rela_iplt_end = .);}}}
|
||
}
|
||
${OTHER_PLT_RELOC_SECTIONS}
|
||
+
|
||
+ ${RELOCATING+PROVIDE (__rel_dyn_end = .);}
|
||
+
|
||
EOF
|
||
|
||
emit_dyn()
|
||
diff --git binutils-2.30/opcodes/disassemble.c binutils-2.30-nds32/opcodes/disassemble.c
|
||
index ae48f5367b..6c05b9ad6d 100644
|
||
--- binutils-2.30/opcodes/disassemble.c
|
||
+++ binutils-2.30-nds32/opcodes/disassemble.c
|
||
@@ -591,6 +591,9 @@ disassembler_usage (FILE *stream ATTRIBUTE_UNUSED)
|
||
#ifdef ARCH_wasm32
|
||
print_wasm32_disassembler_options (stream);
|
||
#endif
|
||
+#ifdef ARCH_nds32
|
||
+ print_nds32_disassembler_options (stream);
|
||
+#endif
|
||
|
||
return;
|
||
}
|
||
@@ -676,6 +679,11 @@ disassemble_init_for_target (struct disassemble_info * info)
|
||
disassemble_init_s390 (info);
|
||
break;
|
||
#endif
|
||
+#ifdef ARCH_nds32
|
||
+ case bfd_arch_nds32:
|
||
+ disassemble_init_nds32 (info);
|
||
+ break;
|
||
+#endif
|
||
default:
|
||
break;
|
||
}
|
||
diff --git binutils-2.30/opcodes/nds32-asm.c binutils-2.30-nds32/opcodes/nds32-asm.c
|
||
index c483dce13a..cb6d0a05b1 100644
|
||
--- binutils-2.30/opcodes/nds32-asm.c
|
||
+++ binutils-2.30-nds32/opcodes/nds32-asm.c
|
||
@@ -26,6 +26,7 @@
|
||
#include <stdint.h>
|
||
#include <string.h>
|
||
#include <assert.h>
|
||
+#include <dlfcn.h>
|
||
|
||
#include "safe-ctype.h"
|
||
#include "libiberty.h"
|
||
@@ -43,8 +44,8 @@
|
||
#define MAX_KEYWORD_LEN 32
|
||
/* This LEX is a plain char or operand. */
|
||
#define IS_LEX_CHAR(c) (((c) >> 7) == 0)
|
||
-#define LEX_SET_FIELD(c) ((c) | SYN_FIELD)
|
||
-#define LEX_GET_FIELD(c) operand_fields[((c) & 0xff)]
|
||
+#define LEX_SET_FIELD(k,c) ((c) | (((k) + 1) << 8))
|
||
+#define LEX_GET_FIELD(k,c) (nds32_field_table[k])[((c) & 0xff)]
|
||
/* Get the char in this lexical element. */
|
||
#define LEX_CHAR(c) ((c) & 0xff)
|
||
|
||
@@ -60,7 +61,8 @@ static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
|
||
char **, int64_t *);
|
||
static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
|
||
char **, int64_t *);
|
||
-static int parse_aext_reg (char **, int *, int);
|
||
+static int parse_aext_reg (struct nds32_asm_desc *, char **,
|
||
+ int *, int);
|
||
static int parse_a30b20 (struct nds32_asm_desc *, struct nds32_asm_insn *,
|
||
char **, int64_t *);
|
||
static int parse_rt21 (struct nds32_asm_desc *, struct nds32_asm_insn *,
|
||
@@ -159,6 +161,7 @@ const field_t operand_fields[] =
|
||
{"i14s1", 0, 14, 1, HW_INT, NULL},
|
||
{"i15s1", 0, 15, 1, HW_INT, NULL},
|
||
{"i16s1", 0, 16, 1, HW_INT, NULL},
|
||
+ {"i16u5", 5, 16, 0, HW_UINT, NULL},
|
||
{"i18s1", 0, 18, 1, HW_INT, NULL},
|
||
{"i24s1", 0, 24, 1, HW_INT, NULL},
|
||
{"i8s2", 0, 8, 2, HW_INT, NULL},
|
||
@@ -170,7 +173,6 @@ const field_t operand_fields[] =
|
||
{"i5u", 0, 5, 0, HW_UINT, NULL},
|
||
{"ib5u", 10, 5, 0, HW_UINT, NULL}, /* imm5 field in ALU. */
|
||
{"ib5s", 10, 5, 0, HW_INT, NULL}, /* imm5 field in ALU. */
|
||
- {"i9u", 0, 9, 0, HW_UINT, NULL}, /* for ex9.it. */
|
||
{"ia3u", 3, 3, 0, HW_UINT, NULL}, /* for bmski33, fexti33. */
|
||
{"i8u", 0, 8, 0, HW_UINT, NULL},
|
||
{"ib8u", 7, 8, 0, HW_UINT, NULL}, /* for ffbi. */
|
||
@@ -183,6 +185,8 @@ const field_t operand_fields[] =
|
||
{"i7u2", 0, 7, 2, HW_UINT, NULL},
|
||
{"i5u3", 0, 5, 3, HW_UINT, NULL}, /* for pop25/pop25. */
|
||
{"i15s3", 0, 15, 3, HW_INT, NULL}, /* for dprefi.d. */
|
||
+ {"ib4u", 10, 4, 0, HW_UINT, NULL}, /* imm5 field in ALU. */
|
||
+ {"ib2u", 10, 2, 0, HW_UINT, NULL}, /* imm5 field in ALU. */
|
||
|
||
{"a_rt", 15, 5, 0, HW_GPR, NULL}, /* for audio-extension. */
|
||
{"a_ru", 10, 5, 0, HW_GPR, NULL}, /* for audio-extension. */
|
||
@@ -199,7 +203,9 @@ const field_t operand_fields[] =
|
||
{"aridx", 0, 5, 0, HW_AEXT_ARIDX, NULL}, /* for audio-extension. */
|
||
{"aridx2", 0, 5, 0, HW_AEXT_ARIDX2, NULL}, /* for audio-extension. */
|
||
{"aridxi", 16, 4, 0, HW_AEXT_ARIDXI, NULL}, /* for audio-extension. */
|
||
- {"imm16", 0, 16, 0, HW_UINT, NULL}, /* for audio-extension. */
|
||
+ {"aridxi_mx", 16, 4, 0, HW_AEXT_ARIDXI_MX, NULL}, /* for audio-extension. */
|
||
+ {"imm16s", 0, 16, 0, HW_INT, NULL}, /* for audio-extension. */
|
||
+ {"imm16u", 0, 16, 0, HW_UINT, NULL}, /* for audio-extension. */
|
||
{"im5_i", 0, 5, 0, HW_AEXT_IM_I, parse_im5_ip}, /* for audio-extension. */
|
||
{"im5_m", 0, 5, 0, HW_AEXT_IM_M, parse_im5_mr}, /* for audio-extension. */
|
||
{"im6_ip", 0, 2, 0, HW_AEXT_IM_I, parse_im6_ip}, /* for audio-extension. */
|
||
@@ -209,6 +215,7 @@ const field_t operand_fields[] =
|
||
{"cp45", 4, 2, 0, HW_CP, NULL}, /* for cop-extension. */
|
||
{"i12u", 8, 12, 0, HW_UINT, NULL}, /* for cop-extension. */
|
||
{"cpi19", 6, 19, 0, HW_UINT, NULL}, /* for cop-extension. */
|
||
+
|
||
{NULL, 0, 0, 0, 0, NULL}
|
||
};
|
||
|
||
@@ -294,7 +301,6 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"jrnez", "%rb", JREG (JRNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
|
||
{"jralnez", "%rt,%rb", JREG (JRALNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
|
||
{"ret", "%rb", JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"ifret", "", JREG (JR) | JREG_IFC | JREG_RET, 4, ATTR (BRANCH) | ATTR (IFC_EXT), 0, NULL, 0, NULL},
|
||
{"jral", "%rb", JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"jralnez", "%rb", JREG (JRALNEZ) | RT (30), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
|
||
{"ret", "", JREG (JR) | JREG_RET | RB (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
@@ -306,8 +312,6 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"beq", "%rt,%ra,%i14s1", OP6 (BR1), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"bne", "%rt,%ra,%i14s1", OP6 (BR1) | N32_BIT (14), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
/* seg-BR2. */
|
||
-#define BR2(sub) (OP6 (BR2) | (N32_BR2_ ## sub << 16))
|
||
- {"ifcall", "%i16s1", BR2 (IFCALL), 4, ATTR (IFC_EXT), 0, NULL, 0, NULL},
|
||
{"beqz", "%rt,%i16s1", BR2 (BEQZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"bnez", "%rt,%i16s1", BR2 (BNEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"bgez", "%rt,%i16s1", BR2 (BGEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
@@ -377,10 +381,10 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"bse", "=rt,%ra,=rb", ALU2 (BSE), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
|
||
{"bsp", "=rt,%ra,=rb", ALU2 (BSP), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
|
||
{"ffzmism", "=rt,%ra,%rb", ALU2 (FFZMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
- {"mfusr", "=rt,%usr", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
|
||
- {"mtusr", "%rt,%usr", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
|
||
- {"mfusr", "=rt,%ridx", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
|
||
- {"mtusr", "%rt,%ridx", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
|
||
+ {"mfusr", "=rt,%usr", ALU2 (MFUSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"mtusr", "%rt,%usr", ALU2 (MTUSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"mfusr", "=rt,%ridx", ALU2 (MFUSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"mtusr", "%rt,%ridx", ALU2 (MTUSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"mul", "=rt,%ra,%rb", ALU2 (MUL), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"madds64", "=dt,%ra,%rb", ALU2 (MADDS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"madd64", "=dt,%ra,%rb", ALU2 (MADD64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
@@ -392,22 +396,22 @@ struct nds32_opcode nds32_opcodes[] =
|
||
|
||
/* seg-ALU2_FFBI. */
|
||
{"ffb", "=rt,%ra,%rb", ALU2 (FFB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
- {"ffbi", "=rt,%ra,%ib8u", ALU2 (FFBI) | N32_BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
+ {"ffbi", "=rt,%ra,%ib8u", ALU2_1 (FFBI), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
/* seg-ALU2_FLMISM. */
|
||
{"ffmism", "=rt,%ra,%rb", ALU2 (FFMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
- {"flmism", "=rt,%ra,%rb", ALU2 (FLMISM) | N32_BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
+ {"flmism", "=rt,%ra,%rb", ALU2_1 (FLMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
|
||
/* seg-ALU2_MULSR64. */
|
||
{"mults64", "=dt,%ra,%rb", ALU2 (MULTS64), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"mulsr64", "=rt,%ra,%rb", ALU2 (MULSR64)| N32_BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
|
||
+ {"mulsr64", "=rt,%ra,%rb", ALU2_1 (MULSR64), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
|
||
/* seg-ALU2_MULR64. */
|
||
{"mult64", "=dt,%ra,%rb", ALU2 (MULT64), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"mulr64", "=rt,%ra,%rb", ALU2 (MULR64) | N32_BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
|
||
+ {"mulr64", "=rt,%ra,%rb", ALU2_1 (MULR64), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
|
||
/* seg-ALU2_MADDR32. */
|
||
{"madd32", "=dt,%ra,%rb", ALU2 (MADD32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"maddr32", "=rt,%ra,%rb", ALU2 (MADDR32) | N32_BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
|
||
+ {"maddr32", "=rt,%ra,%rb", ALU2_1 (MADDR32), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
|
||
/* seg-ALU2_MSUBR32. */
|
||
{"msub32", "=dt,%ra,%rb", ALU2 (MSUB32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"msubr32", "=rt,%ra,%rb", ALU2 (MSUBR32) | N32_BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
|
||
+ {"msubr32", "=rt,%ra,%rb", ALU2_1 (MSUBR32), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
|
||
|
||
/* seg-MISC. */
|
||
{"standby", "%stdby_st", MISC (STANDBY), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
@@ -439,8 +443,12 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"tlbop", "%ra,%tlbop_st", MISC (TLBOP), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"tlbop", "%ra,%tlbop_stx", MISC (TLBOP), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"tlbop", "%rt,%ra,pb", MISC (TLBOP) | (5 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"tlbop", "%rt,%ra,probe", MISC (TLBOP) | (5 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"tlbop", "flua", MISC (TLBOP) | (7 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
{"tlbop", "flushall", MISC (TLBOP) | (7 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ /* seg-MISC_SPECL. */
|
||
+ {"isps", "%i16u5", MISC (SPECL), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"isps", "", MISC (SPECL), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
|
||
/* seg-MEM. */
|
||
{"lb", "=rt,[%ra+(%rb<<%sv)]", MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL},
|
||
@@ -542,7 +550,6 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"fnmsubs", "=fst,%fsa,%fsb", FS1 (FNMSUBS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
|
||
{"fmuls", "=fst,%fsa,%fsb", FS1 (FMULS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
|
||
{"fdivs", "=fst,%fsa,%fsb", FS1 (FDIVS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
|
||
-
|
||
/* seg-FPU_FS1_F2OP. */
|
||
{"fs2d", "=fdt,%fsa", FS1_F2OP (FS2D), 4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
|
||
{"fsqrts", "=fst,%fsa", FS1_F2OP (FSQRTS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
|
||
@@ -601,7 +608,6 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"fmfcfg", "=rt", MFCP_XR(FMFCFG), 4, ATTR (FPU), 0, NULL, 0, NULL},
|
||
{"fmfcsr", "=rt", MFCP_XR(FMFCSR), 4, ATTR (FPU), 0, NULL, 0, NULL},
|
||
/* seg-FPU_MTCP. */
|
||
-
|
||
{"fmtsr", "%rt,=fsa", MTCP (FMTSR), 4, ATTR (FPU), 0, NULL, 0, NULL},
|
||
{"fmtdr", "%rt,=fda", MTCP (FMTDR), 4, ATTR (FPU), 0, NULL, 0, NULL},
|
||
/* seg-FPU_MTCP_XR. */
|
||
@@ -707,14 +713,14 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"swi37", "%rt38,[$fp{+%i7u2}]", 0xb880, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL},
|
||
/* SEG10_1 if Rt3=5. */
|
||
{"j8", "%i8s1", 0xd500, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ /* SEG11_1 if Rt3=5. */
|
||
/* SEG11_2 bit7~bit5. */
|
||
- {"jr5", "%ra5", 0xdd00, 2, ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"jral5", "%ra5", 0xdd20, 2, ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"ex9.it", "%i5u", 0xdd40, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL},
|
||
- {"ret5", "%ra5", 0xdd80, 2, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"jr5", "%ra5", 0xdd00, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL},
|
||
+ {"jral5", "%ra5", 0xdd20, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL},
|
||
+ {"ret5", "%ra5", 0xdd80, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL},
|
||
{"add5.pc", "%ra5", 0xdda0, 2, ATTR_V3, 0, NULL, 0, NULL},
|
||
/* SEG11_3 if Ra5=30. */
|
||
- {"ret5", "", 0xdd80 | RA5 (30), 2, ATTR_ALL, 0, NULL, 0, NULL},
|
||
+ {"ret5", "", 0xdd80 | RA5 (30), 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL},
|
||
/* SEG12 bit10~bit9. */
|
||
{"slts45", "%rt4,%ra5", 0xe000, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
|
||
{"slt45", "%rt4,%ra5", 0xe200, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
|
||
@@ -727,13 +733,10 @@ struct nds32_opcode nds32_opcodes[] =
|
||
/* SEG13_1 bit8. */
|
||
{"beqzs8", "%i8s1", 0xe800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (15), NULL, 0, NULL},
|
||
{"bnezs8", "%i8s1", 0xe900, 2, ATTR_PCREL | ATTR_ALL, USE_REG (15), NULL, 0, NULL},
|
||
- /* SEG13_2 bit8~bit5. */
|
||
- {"ex9.it", "%i9u", 0xea00, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL},
|
||
/* SEG14 bit7. */
|
||
{"lwi37.sp", "=rt38,[+%i7u2]", 0xf000, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL},
|
||
{"swi37.sp", "%rt38,[+%i7u2]", 0xf080, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL},
|
||
/* SEG15 bit10~bit9. */
|
||
- {"ifcall9", "%i9u1", 0xf800, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL},
|
||
{"movpi45", "=rt4,%pi5", 0xfa00, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
/* SEG15_1 bit8. */
|
||
{"movd44", "=rt5e,%ra5e", 0xfd00, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
@@ -749,7 +752,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"fexti33", "=rt3,%ia3u", 0x9607, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
/* SEG-PUSHPOP25 bit8~bit7. */
|
||
{"push25", "%re2,%i5u3", 0xfc00, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
|
||
- {"pop25", "%re2,%i5u3", 0xfc80, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
|
||
+ {"pop25", "%re2,%i5u3", 0xfc80, 2, ATTR_V3MUP | ATTR (BRANCH), USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
|
||
/* SEG-MISC33 bit2~bit0. */
|
||
{"neg33", "=rt3,%ra3", 0xfe02, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
{"not33", "=rt3,%ra3", 0xfe03, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
@@ -759,29 +762,31 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"or33", "=rt3,%ra3", 0xfe07, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
|
||
/* SEG-Alias instructions. */
|
||
{"nop16", "", 0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL},
|
||
- {"ifret16", "", 0x83ff, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL},
|
||
|
||
/* Saturation ext ISA. */
|
||
{"kaddw", "=rt,%ra,%rb", ALU2 (KADD), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"ksubw", "=rt,%ra,%rb", ALU2 (KSUB), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"kaddh", "=rt,%ra,%rb", ALU2 (KADD) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"ksubh", "=rt,%ra,%rb", ALU2 (KSUB) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"kaddh", "=rt,%ra,%rb", ALU2_1 (KADD), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"ksubh", "=rt,%ra,%rb", ALU2_1 (KSUB), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"kdmbb", "=rt,%ra,%rb", ALU2 (KMxy), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"kdmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"kdmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"kdmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
{"khmbb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"khmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"khmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"khmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (6) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"kslraw", "=rt,%ra,%rb", ALU2 (KSLRA), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"rdov", "=rt", ALU2 (MFUSR) | N32_BIT (6) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
- {"clrov", "", ALU2 (MTUSR) | N32_BIT (6) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"khmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"khmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (7) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"khmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (7) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"kslraw", "=rt,%ra,%rb", ALU2 (KSLRAW), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"ksll", "=rt,%ra,%rb", ALU2 (KSLRAW), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"kslraw.u", "=rt,%ra,%rb", ALU2 (KSLRAWu), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"rdov", "=rt", ALU2_1 (RDOV) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
+ {"clrov", "", ALU2_1 (CLROV) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL},
|
||
|
||
/* Audio ext. instructions. */
|
||
|
||
- {"amtari", "%aridxi,%imm16", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMADD */
|
||
+ {"amtari", "%aridxi,%imm16u", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"amtari", "%aridxi_mx,%imm16s", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* N32_AEXT_AMADD. */
|
||
{"alr2", "=a_rt,=a_ru,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMADD) | (0x1 << 6), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amaddl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMADD) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amaddl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMADD) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -791,7 +796,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"alr", "=a_rt,[%im5_i],%im5_m", AUDIO (AMADD) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amadd", "=a_dx,%ra,%rb", AUDIO (AMADD), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabbs", "=a_dx,%ra,%rb", AUDIO (AMADD) | 0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMSUB */
|
||
+ /* N32_AEXT_AMSUB. */
|
||
{"amsubl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amsubl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amsubl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMSUB) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -800,7 +805,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"asr", "%ra,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amsub", "=a_dx,%ra,%rb", AUDIO (AMSUB), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabts", "=a_dx,%ra,%rb", AUDIO (AMSUB) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMULT */
|
||
+ /* N32_AEXT_AMULT. */
|
||
{"amultl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMULT) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amultl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMULT) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amultl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMULT) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -811,14 +816,14 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"amatbs", "=a_dx,%ra,%rb", AUDIO (AMULT) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"asats48", "=a_dx", AUDIO (AMULT) | (0x02 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"awext", "%ra,%a_dx,%i5u", AUDIO (AMULT) | (0x03 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMFAR */
|
||
+ /* N32_AEXT_AMFAR. */
|
||
{"amatts", "=a_dx,%ra,%rb", AUDIO (AMFAR) | 0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"asa", "=dxh,[%im5_i],%im5_m", AUDIO (AMFAR) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtar", "%ra,%aridx", AUDIO (AMFAR) | (0x02 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtar2", "%ra,%aridx2", AUDIO (AMFAR) | (0x12 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amfar", "=ra,%aridx", AUDIO (AMFAR) | (0x03 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amfar2", "=ra,%aridx2", AUDIO (AMFAR) | (0x13 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMADDS */
|
||
+ /* N32_AEXT_AMADDS. */
|
||
{"amaddsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMADDS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amaddsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMADDS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amaddsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMADDS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -828,7 +833,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"amadds", "=a_dx,%ra,%rb", AUDIO (AMADDS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambbs", "=a_dx,%ra,%rb", AUDIO (AMADDS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawbs", "=a_dx,%ra,%rb", AUDIO (AMADDS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMSUBS */
|
||
+ /* N32_AEXT_AMSUBS. */
|
||
{"amsubsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMSUBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amsubsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMSUBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amsubsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMSUBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -837,7 +842,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"amsubs", "=a_dx,%ra,%rb", AUDIO (AMSUBS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambts", "=a_dx,%ra,%rb", AUDIO (AMSUBS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawts", "=a_dx,%ra,%rb", AUDIO (AMSUBS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMULTS */
|
||
+ /* N32_AEXT_AMULTS. */
|
||
{"amultsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMULTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amultsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMULTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amultsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMULTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -846,7 +851,7 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"amults", "=a_dx,%ra,%rb", AUDIO (AMULTS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtbs", "=a_dx,%ra,%rb", AUDIO (AMULTS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbs", "=a_dx,%ra,%rb", AUDIO (AMULTS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMNEGS */
|
||
+ /* N32_AEXT_AMNEGS. */
|
||
{"amnegsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMNEGS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amnegsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMNEGS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amnegsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMNEGS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
@@ -855,82 +860,258 @@ struct nds32_opcode nds32_opcodes[] =
|
||
{"amnegs", "=a_dx,%ra,%rb", AUDIO (AMNEGS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtts", "=a_dx,%ra,%rb", AUDIO (AMNEGS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwts", "=a_dx,%ra,%rb", AUDIO (AMNEGS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AADDL */
|
||
+ /* N32_AEXT_AADDL. */
|
||
{"aaddl", "=a_rte69,%ra,%rb,%a_rte69_1,[%im5_i],%im5_m", AUDIO (AADDL), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"asubl", "=a_rte69,%ra,%rb,%a_rte69_1,[%im5_i],%im5_m", AUDIO (AADDL) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMAWBS */
|
||
+ /* N32_AEXT_AMAWBS. */
|
||
{"amawbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMAWTS */
|
||
+ /* N32_AEXT_AMAWTS. */
|
||
{"amawtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amawtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMWBS */
|
||
+ /* N32_AEXT_AMWBS. */
|
||
{"amwbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMWTS */
|
||
+ /* N32_AEXT_AMWTS. */
|
||
{"amwtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amwtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMABBS */
|
||
+ /* N32_AEXT_AMABBS. */
|
||
{"amabbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMABTS */
|
||
+ /* N32_AEXT_AMABTS. */
|
||
{"amabtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amabtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMATBS */
|
||
+ /* N32_AEXT_AMATBS. */
|
||
{"amatbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amatbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amatbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amatbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amatbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMATTS */
|
||
+ /* N32_AEXT_AMATTS. */
|
||
{"amattsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amattsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amattsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amattsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amattssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMBBS */
|
||
+ /* N32_AEXT_AMBBS. */
|
||
{"ambbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMBTS */
|
||
+ /* N32_AEXT_AMBTS. */
|
||
{"ambtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"ambtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMTBS */
|
||
+ /* N32_AEXT_AMTBS. */
|
||
{"amtbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amtbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
- /* N32_AEXT_AMTTS */
|
||
+ /* N32_AEXT_AMTTS. */
|
||
{"amttsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amttsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amttsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amttsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
{"amttssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL},
|
||
+
|
||
+ /* DSP ISA. */
|
||
+ /* ALU2 Bit 9-6 = 0000. */
|
||
+ {"add64", "=rt,%ra,%rb", ALU2 (ADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sub64", "=rt,%ra,%rb", ALU2 (SUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smal", "=rt,%ra,%rb", ALU2 (SMAL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"radd64", "=rt,%ra,%rb", ALU2 (RADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rsub64", "=rt,%ra,%rb", ALU2 (RSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uradd64", "=rt,%ra,%rb", ALU2 (URADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ursub64", "=rt,%ra,%rb", ALU2 (URSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kadd64", "=rt,%ra,%rb", ALU2 (KADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ksub64", "=rt,%ra,%rb", ALU2 (KSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukadd64", "=rt,%ra,%rb", ALU2 (UKADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uksub64", "=rt,%ra,%rb", ALU2 (UKSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* ALU2 Bit 9-6 = 0001. */
|
||
+ {"smar64", "=rt,%ra,%rb", ALU2_1 (SMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umar64", "=rt,%ra,%rb", ALU2_1 (UMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smsr64", "=rt,%ra,%rb", ALU2_1 (SMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umsr64", "=rt,%ra,%rb", ALU2_1 (UMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmar64", "=rt,%ra,%rb", ALU2_1 (KMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukmar64", "=rt,%ra,%rb", ALU2_1 (UKMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmsr64", "=rt,%ra,%rb", ALU2_1 (KMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukmsr64", "=rt,%ra,%rb", ALU2_1 (UKMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalda", "=rt,%ra,%rb", ALU2_1 (SMALDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smslda", "=rt,%ra,%rb", ALU2_1 (SMSLDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalds", "=rt,%ra,%rb", ALU2_1 (SMALDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalbb", "=rt,%ra,%rb", ALU2_1 (SMALBB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalxda", "=rt,%ra,%rb", ALU2_1 (SMALXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smslxda", "=rt,%ra,%rb", ALU2_1 (SMSLXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalxds", "=rt,%ra,%rb", ALU2_1 (SMALXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalbt", "=rt,%ra,%rb", ALU2_1 (SMALBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smalbt", "=rt,%ra,%rb", ALU2_1 (SMALBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smaldrs", "=rt,%ra,%rb", ALU2_1 (SMALDRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smaltt", "=rt,%ra,%rb", ALU2_1 (SMALTT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smds", "=rt,%ra,%rb", ALU2_1 (SMDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smxds", "=rt,%ra,%rb", ALU2_1 (SMXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smdrs", "=rt,%ra,%rb", ALU2_1 (SMDRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmadrs", "=rt,%ra,%rb", ALU2_1 (KMADRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmads", "=rt,%ra,%rb", ALU2_1 (KMADS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmaxds", "=rt,%ra,%rb", ALU2_1 (KMAXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* DSP MISC. */
|
||
+ {"bpick", "=rt,%ra,%rb,%rd", MISC (BPICK), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* ALU_2 KMxy. */
|
||
+ {"khm16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"khmx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (8) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smul16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smulx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umul16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (7), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umulx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (7) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* ALU2 Bit 9-6 = 0010. */
|
||
+ {"kadd16", "=rt,%ra,%rb", ALU2_2 (KADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ksub16", "=rt,%ra,%rb", ALU2_2 (KSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kcras16", "=rt,%ra,%rb", ALU2_2 (KCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kcrsa16", "=rt,%ra,%rb", ALU2_2 (KCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kadd8", "=rt,%ra,%rb", ALU2_2 (KADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ksub8", "=rt,%ra,%rb", ALU2_2 (KSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"wext", "=rt,%ra,%rb", ALU2_2 (WEXT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"wexti", "=rt,%ra,%ib5u", ALU2_2 (WEXTI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukadd16", "=rt,%ra,%rb", ALU2_2 (UKADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uksub16", "=rt,%ra,%rb", ALU2_2 (UKSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukcras16", "=rt,%ra,%rb", ALU2_2 (UKCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukcrsa16", "=rt,%ra,%rb", ALU2_2 (UKCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ukadd8", "=rt,%ra,%rb", ALU2_2 (UKADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uksub8", "=rt,%ra,%rb", ALU2_2 (UKSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* ONEOP. */
|
||
+#define DSP_ONEOP(n) ((n) << 10)
|
||
+ {"sunpkd810", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x0), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sunpkd820", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x1), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sunpkd830", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x2), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sunpkd831", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x3), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"zunpkd810", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x4), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"zunpkd820", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x5), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"zunpkd830", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"zunpkd831", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x7), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kabs", "=rt,%ra", ALU2 (ABS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
|
||
+ {"kabs16", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kabs8", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0xc), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"insb", "=rt,%ra,%ib2u", ALU2_2 (ONEOP) | DSP_ONEOP (0x10), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smbb", "=rt,%ra,%rb", ALU2_2 (SMBB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smbt", "=rt,%ra,%rb", ALU2_2 (SMBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smtt", "=rt,%ra,%rb", ALU2_2 (SMTT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmabb", "=rt,%ra,%rb", ALU2_2 (KMABB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmabt", "=rt,%ra,%rb", ALU2_2 (KMABT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmatt", "=rt,%ra,%rb", ALU2_2 (KMATT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmda", "=rt,%ra,%rb", ALU2_2 (KMDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmxda", "=rt,%ra,%rb", ALU2_2 (KMXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmada", "=rt,%ra,%rb", ALU2_2 (KMADA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmaxda", "=rt,%ra,%rb", ALU2_2 (KMAXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmsda", "=rt,%ra,%rb", ALU2_2 (KMSDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmsxda", "=rt,%ra,%rb", ALU2_2 (KMSXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"radd16", "=rt,%ra,%rb", ALU2_2 (RADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rsub16", "=rt,%ra,%rb", ALU2_2 (RSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rcras16", "=rt,%ra,%rb", ALU2_2 (RCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rcrsa16", "=rt,%ra,%rb", ALU2_2 (RCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"radd8", "=rt,%ra,%rb", ALU2_2 (RADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rsub8", "=rt,%ra,%rb", ALU2_2 (RSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"raddw", "=rt,%ra,%rb", ALU2_2 (RADDW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"rsubw", "=rt,%ra,%rb", ALU2_2 (RSUBW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uradd16", "=rt,%ra,%rb", ALU2_2 (URADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ursub16", "=rt,%ra,%rb", ALU2_2 (URSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"urcras16", "=rt,%ra,%rb", ALU2_2 (URCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"urcrsa16", "=rt,%ra,%rb", ALU2_2 (URCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uradd8", "=rt,%ra,%rb", ALU2_2 (URADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ursub8", "=rt,%ra,%rb", ALU2_2 (URSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uraddw", "=rt,%ra,%rb", ALU2_2 (URADDW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ursubw", "=rt,%ra,%rb", ALU2_2 (URSUBW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"add16", "=rt,%ra,%rb", ALU2_2 (ADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sub16", "=rt,%ra,%rb", ALU2_2 (SUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"cras16", "=rt,%ra,%rb", ALU2_2 (CRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"crsa16", "=rt,%ra,%rb", ALU2_2 (CRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"add8", "=rt,%ra,%rb", ALU2_2 (ADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sub8", "=rt,%ra,%rb", ALU2_2 (SUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"bitrev", "=rt,%ra,%rb", ALU2_2 (BITREV), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"bitrevi", "=rt,%ra,%ib5u", ALU2_2 (BITREVI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smmul", "=rt,%ra,%rb", ALU2_2 (SMMUL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smmul.u", "=rt,%ra,%rb", ALU2_2 (SMMULu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmac", "=rt,%ra,%rb", ALU2_2 (KMMAC), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmac.u", "=rt,%ra,%rb", ALU2_2 (KMMACu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmsb", "=rt,%ra,%rb", ALU2_2 (KMMSB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmsb.u", "=rt,%ra,%rb", ALU2_2 (KMMSBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kwmmul", "=rt,%ra,%rb", ALU2_2 (KWMMUL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kwmmul.u", "=rt,%ra,%rb", ALU2_2 (KWMMULu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ /* ALU2 Bit 9-6 = 0010. */
|
||
+ {"smmwb", "=rt,%ra,%rb", ALU2_3 (SMMWB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smmwb.u", "=rt,%ra,%rb", ALU2_3 (SMMWBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smmwt", "=rt,%ra,%rb", ALU2_3 (SMMWT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smmwt.u", "=rt,%ra,%rb", ALU2_3 (SMMWTu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmawb", "=rt,%ra,%rb", ALU2_3 (KMMAWB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmawb.u", "=rt,%ra,%rb", ALU2_3 (KMMAWBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmawt", "=rt,%ra,%rb", ALU2_3 (KMMAWT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kmmawt.u", "=rt,%ra,%rb", ALU2_3 (KMMAWTu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"pktt16", "=rt,%ra,%rb", ALU2_3 (PKTT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"pktb16", "=rt,%ra,%rb", ALU2_3 (PKTB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"pkbt16", "=rt,%ra,%rb", ALU2_3 (PKBT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"pkbb16", "=rt,%ra,%rb", ALU2_3 (PKBB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sclip32", "=rt,%ra,%ib5u", ALU2 (CLIPS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
|
||
+ {"sclip16", "=rt,%ra,%ib4u", ALU2_3 (SCLIP16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smax16", "=rt,%ra,%rb", ALU2_3 (SMAX16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smax8", "=rt,%ra,%rb", ALU2_3 (SMAX8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"uclip32", "=rt,%ra,%ib5u", ALU2 (CLIP), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
|
||
+ {"uclip16", "=rt,%ra,%ib4u", ALU2_3 (UCLIP16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umax16", "=rt,%ra,%rb", ALU2_3 (UMAX16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umax8", "=rt,%ra,%rb", ALU2_3 (UMAX8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sra16", "=rt,%ra,%rb", ALU2_3 (SRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sra16.u", "=rt,%ra,%rb", ALU2_3 (SRA16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srl16", "=rt,%ra,%rb", ALU2_3 (SRL16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srl16.u", "=rt,%ra,%rb", ALU2_3 (SRL16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sll16", "=rt,%ra,%rb", ALU2_3 (SLL16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kslra16", "=rt,%ra,%rb", ALU2_3 (KSLRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ksll16", "=rt,%ra,%rb", ALU2_3 (KSLRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kslra16.u", "=rt,%ra,%rb", ALU2_3 (KSLRA16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"sra.u", "=rt,%ra,%rb", ALU2_3 (SRAu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srai16", "=rt,%ra,%ib4u", ALU2_3 (SRAI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srai16.u", "=rt,%ra,%ib4u", ALU2_3 (SRAI16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srli16", "=rt,%ra,%ib4u", ALU2_3 (SRLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srli16.u", "=rt,%ra,%ib4u", ALU2_3 (SRLI16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"slli16", "=rt,%ra,%ib4u", ALU2_3 (SLLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kslli16", "=rt,%ra,%ib4u", ALU2_3 (KSLLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"kslli", "=rt,%ra,%ib5u", ALU2_3 (KSLLI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"srai.u", "=rt,%ra,%ib5u", ALU2_3 (SRAIu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"cmpeq16", "=rt,%ra,%rb", ALU2_3 (CMPEQ16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"scmplt16", "=rt,%ra,%rb", ALU2_3 (SCMPLT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"scmple16", "=rt,%ra,%rb", ALU2_3 (SCMPLE16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smin16", "=rt,%ra,%rb", ALU2_3 (SMIN16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"cmpeq8", "=rt,%ra,%rb", ALU2_3 (CMPEQ8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"scmplt8", "=rt,%ra,%rb", ALU2_3 (SCMPLT8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"scmple8", "=rt,%ra,%rb", ALU2_3 (SCMPLE8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"smin8", "=rt,%ra,%rb", ALU2_3 (SMIN8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ucmplt16", "=rt,%ra,%rb", ALU2_3 (UCMPLT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ucmple16", "=rt,%ra,%rb", ALU2_3 (UCMPLE16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umin16", "=rt,%ra,%rb", ALU2_3 (UMIN16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ucmplt8", "=rt,%ra,%rb", ALU2_3 (UCMPLT8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"ucmple8", "=rt,%ra,%rb", ALU2_3 (UCMPLE8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"umin8", "=rt,%ra,%rb", ALU2_3 (UMIN8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL},
|
||
+ {"mtlbi", "%i16s1", BR2 (SOP0) | N32_BIT (20), 4, ATTR (ZOL) | ATTR (DSP_ISAEXT) | ATTR (PCREL), 0, NULL, 0, NULL},
|
||
+ {"mtlei", "%i16s1", BR2 (SOP0) | N32_BIT (21), 4, ATTR (ZOL) | ATTR (DSP_ISAEXT) | ATTR (PCREL), 0, NULL, 0, NULL},
|
||
{NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL},
|
||
};
|
||
|
||
@@ -986,6 +1167,9 @@ const keyword_t keyword_usr[] =
|
||
{"d0.hi", USRIDX (0, 1), 0},
|
||
{"d1.lo", USRIDX (0, 2), 0},
|
||
{"d1.hi", USRIDX (0, 3), 0},
|
||
+ {"lb", USRIDX (0, 25), 0},
|
||
+ {"le", USRIDX (0, 26), 0},
|
||
+ {"lc", USRIDX (0, 27), 0},
|
||
{"itb", USRIDX (0, 28), 0},
|
||
{"ifc_lp", USRIDX (0, 29), 0},
|
||
{"pc", USRIDX (0, 31), 0},
|
||
@@ -1040,6 +1224,7 @@ const keyword_t keyword_sr[] =
|
||
{"ipc", SRIDX (1, 5, 1), 0}, {"ir9", SRIDX (1, 5, 1), 0},
|
||
{"p_ipc", SRIDX (1, 5, 2), 0}, {"ir10", SRIDX (1, 5, 2), 0},
|
||
{"oipc", SRIDX (1, 5, 3), 0}, {"ir11", SRIDX (1, 5, 3), 0},
|
||
+ {"dipc", SRIDX (1, 5, 3), 0},
|
||
{"p_p0", SRIDX (1, 6, 2), 0}, {"ir12", SRIDX (1, 6, 2), 0},
|
||
{"p_p1", SRIDX (1, 7, 2), 0}, {"ir13", SRIDX (1, 7, 2), 0},
|
||
{"int_mask", SRIDX (1, 8, 0), 0}, {"ir14", SRIDX (1, 8, 0), 0},
|
||
@@ -1059,6 +1244,11 @@ const keyword_t keyword_sr[] =
|
||
{"int_pri2", SRIDX (1, 11, 1), 0}, {"ir28", SRIDX (1, 11, 1), 0},
|
||
{"int_trigger", SRIDX (1, 9, 4), 0}, {"ir29", SRIDX (1, 9, 4), 0},
|
||
{"int_gpr_push_dis", SRIDX(1, 1, 3), 0}, {"ir30", SRIDX (1, 1, 3), 0},
|
||
+ {"int_mask3", SRIDX(1, 8, 2), 0}, {"ir31", SRIDX (1, 8, 2), 0},
|
||
+ {"int_pend3", SRIDX(1, 9, 2), 0}, {"ir32", SRIDX (1, 9, 2), 0},
|
||
+ {"int_pri3", SRIDX(1, 11, 2), 0}, {"ir33", SRIDX (1, 11, 2), 0},
|
||
+ {"int_pri4", SRIDX(1, 11, 3), 0}, {"ir34", SRIDX (1, 11, 3), 0},
|
||
+ {"int_trigger2", SRIDX(1, 9, 5), 0}, {"ir35", SRIDX (1, 9, 5), 0},
|
||
|
||
{"mmu_ctl", SRIDX (2, 0, 0), 0}, {"mr0", SRIDX (2, 0, 0), 0},
|
||
{"l1_pptb", SRIDX (2, 1, 0), 0}, {"mr1", SRIDX (2, 1, 0), 0},
|
||
@@ -1077,9 +1267,12 @@ const keyword_t keyword_sr[] =
|
||
{"pfmc1", SRIDX (4, 0, 1), 0}, {"pfr1", SRIDX (4, 0, 1), 0},
|
||
{"pfmc2", SRIDX (4, 0, 2), 0}, {"pfr2", SRIDX (4, 0, 2), 0},
|
||
{"pfm_ctl", SRIDX (4, 1, 0), 0}, {"pfr3", SRIDX (4, 1, 0), 0},
|
||
+ {"pft_ctl", SRIDX (4, 2, 0), 0}, {"pfr4", SRIDX (4, 2, 0), 0},
|
||
{"hsp_ctl", SRIDX (4, 6, 0), 0}, {"hspr0", SRIDX (4, 6, 0), 0},
|
||
{"sp_bound", SRIDX (4, 6, 1), 0}, {"hspr1", SRIDX (4, 6, 1), 0},
|
||
{"sp_bound_priv", SRIDX (4, 6, 2), 0},{"hspr2", SRIDX (4, 6, 2), 0},
|
||
+ {"sp_base", SRIDX (4, 6, 3), 0}, {"hspr3", SRIDX (4, 6, 3), 0},
|
||
+ {"sp_base_priv", SRIDX (4, 6, 4), 0}, {"hspr4", SRIDX (4, 6, 4), 0},
|
||
|
||
{"dma_cfg", SRIDX (5, 0, 0), 0}, {"dmar0", SRIDX (5, 0, 0), 0},
|
||
{"dma_gcsw", SRIDX (5, 1, 0), 0}, {"dmar1", SRIDX (5, 1, 0), 0},
|
||
@@ -1102,51 +1295,51 @@ const keyword_t keyword_sr[] =
|
||
|
||
{"secur0", SRIDX (6, 0, 0), 0}, {"sfcr", SRIDX (6, 0, 0), 0},
|
||
{"secur1", SRIDX (6, 1, 0), 0}, {"sign", SRIDX (6, 1, 0), 0},
|
||
- {"secur2", SRIDX (6, 1, 1), 0}, {"isign", SRIDX (6, 1, 1), 0},
|
||
- {"secur3", SRIDX (6, 1, 2), 0}, {"p_isign", SRIDX (6, 1, 2), 0},
|
||
+ {"secur2", SRIDX (6, 1, 1), 0}, {"isign", SRIDX (6, 1, 1), 0},
|
||
+ {"secur3", SRIDX (6, 1, 2), 0}, {"p_isign", SRIDX (6, 1, 2), 0},
|
||
|
||
{"prusr_acc_ctl", SRIDX (4, 4, 0), 0},
|
||
{"fucpr", SRIDX (4, 5, 0), 0}, {"fucop_ctl", SRIDX (4, 5, 0), 0},
|
||
|
||
{"bpc0", SRIDX (3, 0, 0), 0}, {"dr0", SRIDX (3, 0, 0), 0},
|
||
- {"bpc1", SRIDX (3, 0, 1), 0}, {"dr1", SRIDX (3, 0, 1), 0},
|
||
- {"bpc2", SRIDX (3, 0, 2), 0}, {"dr2", SRIDX (3, 0, 2), 0},
|
||
- {"bpc3", SRIDX (3, 0, 3), 0}, {"dr3", SRIDX (3, 0, 3), 0},
|
||
- {"bpc4", SRIDX (3, 0, 4), 0}, {"dr4", SRIDX (3, 0, 4), 0},
|
||
- {"bpc5", SRIDX (3, 0, 5), 0}, {"dr5", SRIDX (3, 0, 5), 0},
|
||
- {"bpc6", SRIDX (3, 0, 6), 0}, {"dr6", SRIDX (3, 0, 6), 0},
|
||
- {"bpc7", SRIDX (3, 0, 7), 0}, {"dr7", SRIDX (3, 0, 7), 0},
|
||
- {"bpa0", SRIDX (3, 1, 0), 0}, {"dr8", SRIDX (3, 1, 0), 0},
|
||
- {"bpa1", SRIDX (3, 1, 1), 0}, {"dr9", SRIDX (3, 1, 1), 0},
|
||
- {"bpa2", SRIDX (3, 1, 2), 0}, {"dr10", SRIDX (3, 1, 2), 0},
|
||
- {"bpa3", SRIDX (3, 1, 3), 0}, {"dr11", SRIDX (3, 1, 3), 0},
|
||
- {"bpa4", SRIDX (3, 1, 4), 0}, {"dr12", SRIDX (3, 1, 4), 0},
|
||
- {"bpa5", SRIDX (3, 1, 5), 0}, {"dr13", SRIDX (3, 1, 5), 0},
|
||
- {"bpa6", SRIDX (3, 1, 6), 0}, {"dr14", SRIDX (3, 1, 6), 0},
|
||
- {"bpa7", SRIDX (3, 1, 7), 0}, {"dr15", SRIDX (3, 1, 7), 0},
|
||
- {"bpam0", SRIDX (3, 2, 0), 0}, {"dr16", SRIDX (3, 2, 0), 0},
|
||
- {"bpam1", SRIDX (3, 2, 1), 0}, {"dr17", SRIDX (3, 2, 1), 0},
|
||
- {"bpam2", SRIDX (3, 2, 2), 0}, {"dr18", SRIDX (3, 2, 2), 0},
|
||
- {"bpam3", SRIDX (3, 2, 3), 0}, {"dr19", SRIDX (3, 2, 3), 0},
|
||
- {"bpam4", SRIDX (3, 2, 4), 0}, {"dr20", SRIDX (3, 2, 4), 0},
|
||
- {"bpam5", SRIDX (3, 2, 5), 0}, {"dr21", SRIDX (3, 2, 5), 0},
|
||
- {"bpam6", SRIDX (3, 2, 6), 0}, {"dr22", SRIDX (3, 2, 6), 0},
|
||
- {"bpam7", SRIDX (3, 2, 7), 0}, {"dr23", SRIDX (3, 2, 7), 0},
|
||
- {"bpv0", SRIDX (3, 3, 0), 0}, {"dr24", SRIDX (3, 3, 0), 0},
|
||
- {"bpv1", SRIDX (3, 3, 1), 0}, {"dr25", SRIDX (3, 3, 1), 0},
|
||
- {"bpv2", SRIDX (3, 3, 2), 0}, {"dr26", SRIDX (3, 3, 2), 0},
|
||
- {"bpv3", SRIDX (3, 3, 3), 0}, {"dr27", SRIDX (3, 3, 3), 0},
|
||
- {"bpv4", SRIDX (3, 3, 4), 0}, {"dr28", SRIDX (3, 3, 4), 0},
|
||
- {"bpv5", SRIDX (3, 3, 5), 0}, {"dr29", SRIDX (3, 3, 5), 0},
|
||
- {"bpv6", SRIDX (3, 3, 6), 0}, {"dr30", SRIDX (3, 3, 6), 0},
|
||
- {"bpv7", SRIDX (3, 3, 7), 0}, {"dr31", SRIDX (3, 3, 7), 0},
|
||
- {"bpcid0", SRIDX (3, 4, 0), 0}, {"dr32", SRIDX (3, 4, 0), 0},
|
||
- {"bpcid1", SRIDX (3, 4, 1), 0}, {"dr33", SRIDX (3, 4, 1), 0},
|
||
- {"bpcid2", SRIDX (3, 4, 2), 0}, {"dr34", SRIDX (3, 4, 2), 0},
|
||
- {"bpcid3", SRIDX (3, 4, 3), 0}, {"dr35", SRIDX (3, 4, 3), 0},
|
||
- {"bpcid4", SRIDX (3, 4, 4), 0}, {"dr36", SRIDX (3, 4, 4), 0},
|
||
- {"bpcid5", SRIDX (3, 4, 5), 0}, {"dr37", SRIDX (3, 4, 5), 0},
|
||
- {"bpcid6", SRIDX (3, 4, 6), 0}, {"dr38", SRIDX (3, 4, 6), 0},
|
||
+ {"bpc1", SRIDX (3, 0, 1), 0}, {"dr5", SRIDX (3, 0, 1), 0},
|
||
+ {"bpc2", SRIDX (3, 0, 2), 0}, {"dr10", SRIDX (3, 0, 2), 0},
|
||
+ {"bpc3", SRIDX (3, 0, 3), 0}, {"dr15", SRIDX (3, 0, 3), 0},
|
||
+ {"bpc4", SRIDX (3, 0, 4), 0}, {"dr20", SRIDX (3, 0, 4), 0},
|
||
+ {"bpc5", SRIDX (3, 0, 5), 0}, {"dr25", SRIDX (3, 0, 5), 0},
|
||
+ {"bpc6", SRIDX (3, 0, 6), 0}, {"dr30", SRIDX (3, 0, 6), 0},
|
||
+ {"bpc7", SRIDX (3, 0, 7), 0}, {"dr35", SRIDX (3, 0, 7), 0},
|
||
+ {"bpa0", SRIDX (3, 1, 0), 0}, {"dr1", SRIDX (3, 1, 0), 0},
|
||
+ {"bpa1", SRIDX (3, 1, 1), 0}, {"dr6", SRIDX (3, 1, 1), 0},
|
||
+ {"bpa2", SRIDX (3, 1, 2), 0}, {"dr11", SRIDX (3, 1, 2), 0},
|
||
+ {"bpa3", SRIDX (3, 1, 3), 0}, {"dr16", SRIDX (3, 1, 3), 0},
|
||
+ {"bpa4", SRIDX (3, 1, 4), 0}, {"dr21", SRIDX (3, 1, 4), 0},
|
||
+ {"bpa5", SRIDX (3, 1, 5), 0}, {"dr26", SRIDX (3, 1, 5), 0},
|
||
+ {"bpa6", SRIDX (3, 1, 6), 0}, {"dr31", SRIDX (3, 1, 6), 0},
|
||
+ {"bpa7", SRIDX (3, 1, 7), 0}, {"dr36", SRIDX (3, 1, 7), 0},
|
||
+ {"bpam0", SRIDX (3, 2, 0), 0}, {"dr2", SRIDX (3, 2, 0), 0},
|
||
+ {"bpam1", SRIDX (3, 2, 1), 0}, {"dr7", SRIDX (3, 2, 1), 0},
|
||
+ {"bpam2", SRIDX (3, 2, 2), 0}, {"dr12", SRIDX (3, 2, 2), 0},
|
||
+ {"bpam3", SRIDX (3, 2, 3), 0}, {"dr17", SRIDX (3, 2, 3), 0},
|
||
+ {"bpam4", SRIDX (3, 2, 4), 0}, {"dr22", SRIDX (3, 2, 4), 0},
|
||
+ {"bpam5", SRIDX (3, 2, 5), 0}, {"dr27", SRIDX (3, 2, 5), 0},
|
||
+ {"bpam6", SRIDX (3, 2, 6), 0}, {"dr32", SRIDX (3, 2, 6), 0},
|
||
+ {"bpam7", SRIDX (3, 2, 7), 0}, {"dr37", SRIDX (3, 2, 7), 0},
|
||
+ {"bpv0", SRIDX (3, 3, 0), 0}, {"dr3", SRIDX (3, 3, 0), 0},
|
||
+ {"bpv1", SRIDX (3, 3, 1), 0}, {"dr8", SRIDX (3, 3, 1), 0},
|
||
+ {"bpv2", SRIDX (3, 3, 2), 0}, {"dr13", SRIDX (3, 3, 2), 0},
|
||
+ {"bpv3", SRIDX (3, 3, 3), 0}, {"dr18", SRIDX (3, 3, 3), 0},
|
||
+ {"bpv4", SRIDX (3, 3, 4), 0}, {"dr23", SRIDX (3, 3, 4), 0},
|
||
+ {"bpv5", SRIDX (3, 3, 5), 0}, {"dr28", SRIDX (3, 3, 5), 0},
|
||
+ {"bpv6", SRIDX (3, 3, 6), 0}, {"dr33", SRIDX (3, 3, 6), 0},
|
||
+ {"bpv7", SRIDX (3, 3, 7), 0}, {"dr38", SRIDX (3, 3, 7), 0},
|
||
+ {"bpcid0", SRIDX (3, 4, 0), 0}, {"dr4", SRIDX (3, 4, 0), 0},
|
||
+ {"bpcid1", SRIDX (3, 4, 1), 0}, {"dr9", SRIDX (3, 4, 1), 0},
|
||
+ {"bpcid2", SRIDX (3, 4, 2), 0}, {"dr14", SRIDX (3, 4, 2), 0},
|
||
+ {"bpcid3", SRIDX (3, 4, 3), 0}, {"dr19", SRIDX (3, 4, 3), 0},
|
||
+ {"bpcid4", SRIDX (3, 4, 4), 0}, {"dr24", SRIDX (3, 4, 4), 0},
|
||
+ {"bpcid5", SRIDX (3, 4, 5), 0}, {"dr29", SRIDX (3, 4, 5), 0},
|
||
+ {"bpcid6", SRIDX (3, 4, 6), 0}, {"dr34", SRIDX (3, 4, 6), 0},
|
||
{"bpcid7", SRIDX (3, 4, 7), 0}, {"dr39", SRIDX (3, 4, 7), 0},
|
||
{"edm_cfg", SRIDX (3, 5, 0), 0}, {"dr40", SRIDX (3, 5, 0), 0},
|
||
{"edmsw", SRIDX (3, 6, 0), 0}, {"dr41", SRIDX (3, 6, 0), 0},
|
||
@@ -1360,6 +1553,14 @@ const keyword_t keyword_aridxi[] =
|
||
{NULL, 0, 0}
|
||
};
|
||
|
||
+const keyword_t keyword_aridxi_mx[] =
|
||
+{
|
||
+ {"m1", 9, 0}, {"m2", 10, 0}, {"m3",11, 0},
|
||
+ {"m5",13, 0}, {"m6",14, 0}, {"m7",15, 0},
|
||
+ {NULL, 0, 0}
|
||
+};
|
||
+
|
||
+
|
||
const keyword_t *keywords[_HW_LAST] =
|
||
{
|
||
keyword_gpr, keyword_usr, keyword_dxr, keyword_sr, keyword_fsr,
|
||
@@ -1370,15 +1571,21 @@ const keyword_t *keywords[_HW_LAST] =
|
||
keyword_cctl_lv, keyword_tlbop_st, keyword_standby_st,
|
||
keyword_msync_st,
|
||
keyword_im5_i, keyword_im5_m,
|
||
- keyword_accumulator, keyword_aridx, keyword_aridx2, keyword_aridxi
|
||
+ keyword_accumulator, keyword_aridx, keyword_aridx2,
|
||
+ keyword_aridxi, keyword_aridxi_mx
|
||
};
|
||
+
|
||
+const keyword_t **nds32_keyword_table[NDS32_CORE_COUNT];
|
||
+static unsigned int nds32_keyword_count_table[NDS32_CORE_COUNT];
|
||
+const field_t *nds32_field_table[NDS32_CORE_COUNT];
|
||
+opcode_t *nds32_opcode_table[NDS32_CORE_COUNT];
|
||
|
||
/* Hash table for syntax lex. */
|
||
static htab_t field_htab;
|
||
/* Hash table for opcodes. */
|
||
static htab_t opcode_htab;
|
||
/* Hash table for hardware resources. */
|
||
-static htab_t hw_ktabs[_HW_LAST];
|
||
+static htab_t *hw_ktabs;
|
||
|
||
static hashval_t
|
||
htab_hash_hash (const void *p)
|
||
@@ -1396,44 +1603,198 @@ htab_hash_eq (const void *p, const void *q)
|
||
|
||
return strcmp (name, h->name) == 0;
|
||
}
|
||
+
|
||
|
||
-/* Build a hash table for array BASE. Each element is in size of SIZE,
|
||
- and it's first element is a pointer to the key of string.
|
||
- It stops inserting elements until reach an NULL key. */
|
||
+/* These functions parse "share library file name" specified for ACE. */
|
||
|
||
-static htab_t
|
||
-build_hash_table (const void *base, size_t size)
|
||
+static int
|
||
+nds32_parse_ace (const char *str, unsigned id)
|
||
{
|
||
- htab_t htab;
|
||
- hashval_t hash;
|
||
- const char *p;
|
||
+ void *obj, *dlc = dlopen (str, RTLD_NOW | RTLD_LOCAL);
|
||
+ char *err;
|
||
|
||
- htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
|
||
- NULL, xcalloc, free);
|
||
+ if (dlc == NULL)
|
||
+ err = (char*) dlerror ();
|
||
+ else
|
||
+ {
|
||
+ obj = dlsym (dlc, "keyword_count");
|
||
+ err = (char*) dlerror ();
|
||
+ if (err == NULL)
|
||
+ {
|
||
+ nds32_keyword_count_table[id] = *(unsigned int*) obj;
|
||
+ if (nds32_keyword_count_table[id] != 0)
|
||
+ {
|
||
+ nds32_keyword_table[id] =
|
||
+ (const keyword_t**) dlsym (dlc, "keywords");
|
||
+ err = (char*) dlerror ();
|
||
+ }
|
||
+ if (err == NULL)
|
||
+ {
|
||
+ nds32_field_table[id] =
|
||
+ (const field_t*) dlsym (dlc, "nds32_ace_field");
|
||
+ err = (char*) dlerror ();
|
||
+ }
|
||
+ if (err == NULL)
|
||
+ {
|
||
+ nds32_opcode_table[id] =
|
||
+ (opcode_t*) dlsym (dlc, "nds32_ace_opcode");
|
||
+ err = (char*) dlerror ();
|
||
+ }
|
||
+
|
||
+ if (err == NULL)
|
||
+ {
|
||
+ if (id != NDS32_ACE)
|
||
+ {
|
||
+ opcode_t *opc = nds32_opcode_table[id];
|
||
+ unsigned cpid = id - NDS32_COP0;
|
||
+ unsigned matched = 0;
|
||
+
|
||
+ /* Check whether the coprocessor ID encoded matches. */
|
||
+ /* If not, coprocessor ID is fixed for flexibitlity. */
|
||
+ if (N32_OP6 (opc->value) == N32_OP6_COP)
|
||
+ {
|
||
+ if (__GF (opc->value, 4, 2) == cpid)
|
||
+ matched = 1;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ if (__GF (opc->value, 13, 2) == cpid)
|
||
+ matched = 1;
|
||
+ }
|
||
+ if (!matched)
|
||
+ {
|
||
+ for (; opc->opcode != NULL; opc++)
|
||
+ {
|
||
+ if (N32_OP6 (opc->value) == N32_OP6_COP)
|
||
+ opc->value = (opc->value >> 6) | __MF(cpid, 4, 2)
|
||
+ | (opc->value & 0xf);
|
||
+ else
|
||
+ opc->value = (opc->value >> 15) | __MF(cpid, 13, 2)
|
||
+ | (opc->value & 0x1fff);
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return 1;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ printf("%s\n", err);
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+int
|
||
+nds32_parse_udi (const char *str)
|
||
+{
|
||
+ return nds32_parse_ace (str, NDS32_ACE);
|
||
+}
|
||
|
||
- p = base;
|
||
- while (1)
|
||
+int
|
||
+nds32_parse_cop0 (const char *str)
|
||
+{
|
||
+ return nds32_parse_ace (str, NDS32_COP0);
|
||
+}
|
||
+
|
||
+int
|
||
+nds32_parse_cop1 (const char *str)
|
||
+{
|
||
+ return nds32_parse_ace (str, NDS32_COP1);
|
||
+}
|
||
+
|
||
+int
|
||
+nds32_parse_cop2 (const char *str)
|
||
+{
|
||
+ return nds32_parse_ace (str, NDS32_COP2);
|
||
+}
|
||
+
|
||
+int
|
||
+nds32_parse_cop3 (const char *str)
|
||
+{
|
||
+ return nds32_parse_ace (str, NDS32_COP3);
|
||
+}
|
||
+
|
||
+static void
|
||
+build_operand_hash_table (void)
|
||
+{
|
||
+ unsigned k;
|
||
+
|
||
+ field_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
|
||
+ NULL, xcalloc, free);
|
||
+
|
||
+ for (k = 0; k < NDS32_CORE_COUNT; k++)
|
||
{
|
||
- struct nds32_hash_entry **slot;
|
||
- struct nds32_hash_entry *h;
|
||
+ const field_t *fld;
|
||
|
||
- h = (struct nds32_hash_entry *) p;
|
||
+ fld = nds32_field_table[k];
|
||
+ if (fld == NULL)
|
||
+ continue;
|
||
|
||
- if (h->name == NULL)
|
||
- break;
|
||
+ /* Add op-codes. */
|
||
+ while (fld->name != NULL)
|
||
+ {
|
||
+ hashval_t hash;
|
||
+ const field_t **slot;
|
||
|
||
- hash = htab_hash_string (h->name);
|
||
- slot = (struct nds32_hash_entry **)
|
||
- htab_find_slot_with_hash (htab, h->name, hash, INSERT);
|
||
+ hash = htab_hash_string (fld->name);
|
||
+ slot = (const field_t **)
|
||
+ htab_find_slot_with_hash (field_htab, fld->name, hash, INSERT);
|
||
|
||
- assert (slot != NULL && *slot == NULL);
|
||
+ assert (slot != NULL && *slot == NULL);
|
||
+ *slot = fld++;
|
||
+ }
|
||
+ }
|
||
+}
|
||
|
||
- *slot = h;
|
||
+static void
|
||
+build_keyword_hash_table (void)
|
||
+{
|
||
+ unsigned int i, j, k, n;
|
||
|
||
- p = p + size;
|
||
+ /* Count total keyword tables. */
|
||
+ for (n = 0, i = 0; i < NDS32_CORE_COUNT; i++)
|
||
+ {
|
||
+ n += nds32_keyword_count_table[i];
|
||
}
|
||
|
||
- return htab;
|
||
+ /* Allocate space. */
|
||
+ hw_ktabs = (htab_t *) malloc (n * sizeof (struct htab));
|
||
+ for (i = 0; i < n; i++)
|
||
+ {
|
||
+ hw_ktabs[i] = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
|
||
+ NULL, xcalloc, free);
|
||
+ }
|
||
+
|
||
+ for (n = 0, k = 0; k < NDS32_CORE_COUNT; k++, n += j)
|
||
+ {
|
||
+ const keyword_t **kwd;
|
||
+
|
||
+ if ((j = nds32_keyword_count_table[k]) == 0)
|
||
+ continue;
|
||
+
|
||
+ /* Add keywords. */
|
||
+ kwd = nds32_keyword_table[k];
|
||
+ for (i = 0; i < j; i++)
|
||
+ {
|
||
+ htab_t htab;
|
||
+ const keyword_t *kw;
|
||
+
|
||
+ kw = kwd[i];
|
||
+ htab = hw_ktabs[n + i];
|
||
+ while (kw->name != NULL)
|
||
+ {
|
||
+ hashval_t hash;
|
||
+ const keyword_t **slot;
|
||
+
|
||
+ hash = htab_hash_string (kw->name);
|
||
+ slot = (const keyword_t **)
|
||
+ htab_find_slot_with_hash (htab, kw->name, hash, INSERT);
|
||
+
|
||
+ assert (slot != NULL && *slot == NULL);
|
||
+ *slot = kw++;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
}
|
||
|
||
/* Build the syntax for a given opcode OPC. It parses the string
|
||
@@ -1458,36 +1819,31 @@ build_opcode_syntax (struct nds32_opcode *opc)
|
||
return;
|
||
|
||
opc->syntax = xmalloc (MAX_LEX_NUM * sizeof (lex_t));
|
||
+ memset (opc->syntax, 0, MAX_LEX_NUM * sizeof (lex_t));
|
||
|
||
str = opc->instruction;
|
||
plex = opc->syntax;
|
||
while (*str)
|
||
{
|
||
- int fidx;
|
||
+ int i, k, fidx;
|
||
|
||
switch (*str)
|
||
{
|
||
- case '%':
|
||
- *plex = SYN_INPUT;
|
||
- break;
|
||
- case '=':
|
||
- *plex = SYN_OUTPUT;
|
||
- break;
|
||
- case '&':
|
||
- *plex = SYN_INPUT | SYN_OUTPUT;
|
||
- break;
|
||
+ case '%': *plex = SYN_INPUT; break;
|
||
+ case '=': *plex = SYN_OUTPUT; break;
|
||
+ case '&': *plex = SYN_INPUT | SYN_OUTPUT; break;
|
||
case '{':
|
||
- *plex++ = SYN_LOPT;
|
||
- opt++;
|
||
- str++;
|
||
- continue;
|
||
+ *plex++ = SYN_LOPT;
|
||
+ opt++;
|
||
+ str++;
|
||
+ continue;
|
||
case '}':
|
||
- *plex++ = SYN_ROPT;
|
||
- str++;
|
||
- continue;
|
||
+ *plex++ = SYN_ROPT;
|
||
+ str++;
|
||
+ continue;
|
||
default:
|
||
- *plex++ = *str++;
|
||
- continue;
|
||
+ *plex++ = *str++;
|
||
+ continue;
|
||
}
|
||
str++;
|
||
|
||
@@ -1501,14 +1857,25 @@ build_opcode_syntax (struct nds32_opcode *opc)
|
||
|
||
hash = htab_hash_string (odstr);
|
||
fd = (field_t *) htab_find_with_hash (field_htab, odstr, hash);
|
||
- fidx = fd - operand_fields;
|
||
-
|
||
if (fd == NULL)
|
||
{
|
||
fprintf (stderr, "Internal error: Unknown operand, %s\n", str);
|
||
}
|
||
- assert (fd && fidx >= 0 && fidx < (int) ARRAY_SIZE (operand_fields));
|
||
- *plex |= LEX_SET_FIELD (fidx);
|
||
+
|
||
+ /* We are not sure how these tables are organized. */
|
||
+ /* Thus, the minimal index should be the right one. */
|
||
+ for (fidx = 256, k = 0, i = 0; i < NDS32_CORE_COUNT; i++)
|
||
+ {
|
||
+ int tmp;
|
||
+
|
||
+ tmp = fd - nds32_field_table[i];
|
||
+ if (tmp >= 0 && tmp < fidx)
|
||
+ {
|
||
+ fidx = tmp;
|
||
+ k = i;
|
||
+ }
|
||
+ }
|
||
+ *plex |= LEX_SET_FIELD (k, fidx);
|
||
|
||
str += len;
|
||
plex++;
|
||
@@ -1519,44 +1886,37 @@ build_opcode_syntax (struct nds32_opcode *opc)
|
||
return;
|
||
}
|
||
|
||
-/* Initialize the assembler. It must be called before assembling. */
|
||
-
|
||
-void
|
||
-nds32_asm_init (nds32_asm_desc_t *pdesc, int flags)
|
||
+static void
|
||
+build_opcode_hash_table (void)
|
||
{
|
||
- int i;
|
||
- hashval_t hash;
|
||
+ unsigned k;
|
||
|
||
- pdesc->flags = flags;
|
||
- pdesc->mach = flags & NASM_OPEN_ARCH_MASK;
|
||
-
|
||
- /* Build keyword tables. */
|
||
- field_htab = build_hash_table (operand_fields,
|
||
- sizeof (operand_fields[0]));
|
||
-
|
||
- for (i = 0; i < _HW_LAST; i++)
|
||
- hw_ktabs[i] = build_hash_table (keywords[i], sizeof (keyword_t));
|
||
-
|
||
- /* Build opcode table. */
|
||
- opcode_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
|
||
+ opcode_htab = htab_create_alloc (512, htab_hash_hash, htab_hash_eq,
|
||
NULL, xcalloc, free);
|
||
|
||
- for (i = 0; i < (int) ARRAY_SIZE (nds32_opcodes); i++)
|
||
+ for (k = 0; k < NDS32_CORE_COUNT; k++)
|
||
{
|
||
- struct nds32_opcode **slot;
|
||
- struct nds32_opcode *opc;
|
||
+ opcode_t *opc;
|
||
+
|
||
+ opc = nds32_opcode_table[k];
|
||
+ if (opc == NULL)
|
||
+ continue;
|
||
|
||
- opc = &nds32_opcodes[i];
|
||
- if ((opc->opcode != NULL) && (opc->instruction != NULL))
|
||
+ /* Add op-codes. */
|
||
+ while ((opc->opcode != NULL) && (opc->instruction != NULL))
|
||
{
|
||
+ hashval_t hash;
|
||
+ opcode_t **slot;
|
||
+
|
||
hash = htab_hash_string (opc->opcode);
|
||
- slot = (struct nds32_opcode **)
|
||
- htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, INSERT);
|
||
+ slot = (opcode_t **)
|
||
+ htab_find_slot_with_hash (opcode_htab, opc->opcode, hash,
|
||
+ INSERT);
|
||
|
||
#define NDS32_PREINIT_SYNTAX
|
||
#if defined (NDS32_PREINIT_SYNTAX)
|
||
- /* Initial SYNTAX when build opcode table, so bug in syntax can be
|
||
- found when initialized rather than used. */
|
||
+ /* Initial SYNTAX when build opcode table, so bug in syntax
|
||
+ can be found when initialized rather than used. */
|
||
build_opcode_syntax (opc);
|
||
#endif
|
||
|
||
@@ -1567,16 +1927,44 @@ nds32_asm_init (nds32_asm_desc_t *pdesc, int flags)
|
||
}
|
||
else
|
||
{
|
||
+ opcode_t *ptr;
|
||
+
|
||
/* Already exists. Append to the list. */
|
||
- opc = *slot;
|
||
- while (opc->next)
|
||
- opc = opc->next;
|
||
- opc->next = &nds32_opcodes[i];
|
||
+ ptr = *slot;
|
||
+ while (ptr->next)
|
||
+ ptr = ptr->next;
|
||
+ ptr->next = opc;
|
||
+ opc->next = NULL;
|
||
}
|
||
+ opc++;
|
||
}
|
||
}
|
||
}
|
||
|
||
+/* Initialize the assembler. It must be called before assembling. */
|
||
+
|
||
+void
|
||
+nds32_asm_init (nds32_asm_desc_t *pdesc, int flags)
|
||
+{
|
||
+ pdesc->flags = flags;
|
||
+ pdesc->mach = flags & NASM_OPEN_ARCH_MASK;
|
||
+
|
||
+ /* Setup main core. */
|
||
+ nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0];
|
||
+ nds32_keyword_count_table[NDS32_MAIN_CORE] = _HW_LAST;
|
||
+ nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
|
||
+ nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0];
|
||
+
|
||
+ /* Build operand hash table. */
|
||
+ build_operand_hash_table ();
|
||
+
|
||
+ /* Build keyword hash tables. */
|
||
+ build_keyword_hash_table ();
|
||
+
|
||
+ /* Build op-code hash table. */
|
||
+ build_opcode_hash_table ();
|
||
+}
|
||
+
|
||
/* Parse the input and store operand keyword string in ODSTR.
|
||
This function is only used for parsing keywords,
|
||
HW_INT/HW_UINT are parsed parse_operand callback handler. */
|
||
@@ -1617,6 +2005,11 @@ parse_re (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
if (__GF (pinsn->insn, 20, 5) > (unsigned int) k->value)
|
||
return NASM_ERR_OPERAND;
|
||
|
||
+ /* Register not allowed in reduced register. */
|
||
+ if ((pdesc->flags & NASM_OPEN_REDUCED_REG)
|
||
+ && (k->attr & ATTR (RDREG)) == 0)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
+
|
||
*value = k->value;
|
||
*pstr = end;
|
||
return NASM_R_CONST;
|
||
@@ -1644,6 +2037,11 @@ parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
if (k == NULL)
|
||
return NASM_ERR_OPERAND;
|
||
|
||
+ /* Register not allowed in reduced register. */
|
||
+ if ((pdesc->flags & NASM_OPEN_REDUCED_REG)
|
||
+ && (k->attr & ATTR (RDREG)) == 0)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
+
|
||
if (k->value == 6)
|
||
*value = 0;
|
||
else if (k->value == 8)
|
||
@@ -1699,7 +2097,8 @@ static int aext_im5_ip = 0;
|
||
static int aext_im6_ip = 0;
|
||
/* Parse the operand of audio ext. */
|
||
static int
|
||
-parse_aext_reg (char **pstr, int *value, int hw_res)
|
||
+parse_aext_reg (struct nds32_asm_desc *pdesc, char **pstr,
|
||
+ int *value, int hw_res)
|
||
{
|
||
char *end = *pstr;
|
||
char odstr[MAX_KEYWORD_LEN];
|
||
@@ -1716,20 +2115,27 @@ parse_aext_reg (char **pstr, int *value, int hw_res)
|
||
if (k == NULL)
|
||
return NASM_ERR_OPERAND;
|
||
|
||
+ if (hw_res == HW_GPR
|
||
+ && (pdesc->flags & NASM_OPEN_REDUCED_REG)
|
||
+ && (k->attr & ATTR (RDREG)) == 0)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
+
|
||
*value = k->value;
|
||
*pstr = end;
|
||
return NASM_R_CONST;
|
||
}
|
||
|
||
static int
|
||
-parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_a30b20 (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 15))
|
||
return NASM_ERR_OPERAND;
|
||
|
||
@@ -1739,14 +2145,16 @@ parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_rt21 (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret, tmp_value, tmp1, tmp2;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 15))
|
||
return NASM_ERR_OPERAND;
|
||
tmp1 = (aext_a30b20 & 0x08);
|
||
@@ -1762,14 +2170,16 @@ parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_rte_start (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret, tmp1, tmp2;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)
|
||
|| (rt_value & 0x01))
|
||
return NASM_ERR_OPERAND;
|
||
@@ -1786,13 +2196,16 @@ parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_rte_end (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret, tmp1, tmp2;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
+
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)
|
||
|| ((rt_value & 0x01) == 0)
|
||
|| (rt_value != (aext_rte + 1)))
|
||
@@ -1801,6 +2214,7 @@ parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
tmp2 = (rt_value & 0x08);
|
||
if (tmp1 != tmp2)
|
||
return NASM_ERR_OPERAND;
|
||
+
|
||
/* Rt=CONCAT(c, t21, 0), t21:bit11-10. */
|
||
rt_value = (rt_value & 0x06) << 4;
|
||
*value = rt_value;
|
||
@@ -1808,16 +2222,20 @@ parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_rte69_start (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
+
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND)
|
||
|| (rt_value & 0x01))
|
||
return NASM_ERR_OPERAND;
|
||
+
|
||
aext_rte = rt_value;
|
||
rt_value = (rt_value >> 1);
|
||
*value = rt_value;
|
||
@@ -1825,17 +2243,21 @@ parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_rte69_end (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_GPR);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR);
|
||
+
|
||
+ if (ret == NASM_ERR_REG_REDUCED)
|
||
+ return NASM_ERR_REG_REDUCED;
|
||
if ((ret == NASM_ERR_OPERAND)
|
||
|| ((rt_value & 0x01) == 0)
|
||
|| (rt_value != (aext_rte + 1)))
|
||
return NASM_ERR_OPERAND;
|
||
+
|
||
aext_rte = rt_value;
|
||
rt_value = (rt_value >> 1);
|
||
*value = rt_value;
|
||
@@ -1843,13 +2265,13 @@ parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im5_ip (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret, new_value;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I);
|
||
if (ret == NASM_ERR_OPERAND)
|
||
return NASM_ERR_OPERAND;
|
||
/* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
|
||
@@ -1861,13 +2283,13 @@ parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im5_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im5_mr (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret, new_value, tmp1, tmp2;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M);
|
||
if (ret == NASM_ERR_OPERAND)
|
||
return NASM_ERR_OPERAND;
|
||
/* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
|
||
@@ -1881,13 +2303,13 @@ parse_im5_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im6_ip (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I);
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 3))
|
||
return NASM_ERR_OPERAND;
|
||
/* p = 0.bit[1:0]. */
|
||
@@ -1897,13 +2319,13 @@ parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im6_iq (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im6_iq (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I);
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value < 4))
|
||
return NASM_ERR_OPERAND;
|
||
/* q = 1.bit[1:0]. */
|
||
@@ -1914,13 +2336,13 @@ parse_im6_iq (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im6_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im6_mr (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M);
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value > 3))
|
||
return NASM_ERR_OPERAND;
|
||
/* r = 0.bit[3:2]. */
|
||
@@ -1929,13 +2351,13 @@ parse_im6_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
}
|
||
|
||
static int
|
||
-parse_im6_ms (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
|
||
+parse_im6_ms (struct nds32_asm_desc *pdesc,
|
||
struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
|
||
char **pstr, int64_t *value)
|
||
{
|
||
int rt_value, ret;
|
||
|
||
- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M);
|
||
+ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M);
|
||
if ((ret == NASM_ERR_OPERAND) || (rt_value < 4))
|
||
return NASM_ERR_OPERAND;
|
||
/* s = 1.bit[5:4]. */
|
||
@@ -1952,9 +2374,9 @@ parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
|
||
char odstr[MAX_KEYWORD_LEN];
|
||
char *end;
|
||
hashval_t hash;
|
||
- const field_t *fld = &LEX_GET_FIELD (syn);
|
||
+ const field_t *fld = &LEX_GET_FIELD (((syn >> 8) & 0xff) - 1, syn);
|
||
keyword_t *k;
|
||
- int64_t value;
|
||
+ int64_t value = 0; /* 0x100000000; Big enough to overflow. */
|
||
int r;
|
||
uint64_t modifier = 0;
|
||
|
||
@@ -1963,23 +2385,31 @@ parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
|
||
if (fld->parse)
|
||
{
|
||
r = fld->parse (pdesc, pinsn, &end, &value);
|
||
- if (r == NASM_ERR_OPERAND)
|
||
+ if (r == NASM_ERR_OPERAND || r == NASM_ERR_REG_REDUCED)
|
||
{
|
||
- pdesc->result = NASM_ERR_OPERAND;
|
||
+ pdesc->result = r;
|
||
return 0;
|
||
}
|
||
goto done;
|
||
}
|
||
|
||
- if (fld->hw_res < _HW_LAST)
|
||
+ /* Check valid keyword group. */
|
||
+ if (fld->hw_res < HW_INT)
|
||
{
|
||
+ int n = 0, i;
|
||
+
|
||
+ /* Calculate index of keyword hash table. */
|
||
+ for (i = 0; i < (fld->hw_res >> 8); i++)
|
||
+ n += nds32_keyword_count_table[i];
|
||
+
|
||
/* Parse the operand in assembly code. */
|
||
if (*end == '$')
|
||
end++;
|
||
end = parse_to_delimiter (end, odstr);
|
||
|
||
hash = htab_hash_string (odstr);
|
||
- k = htab_find_with_hash (hw_ktabs[fld->hw_res], odstr, hash);
|
||
+ k = htab_find_with_hash (hw_ktabs[n + (fld->hw_res & 0xff)], odstr,
|
||
+ hash);
|
||
|
||
if (k == NULL)
|
||
{
|
||
@@ -2086,7 +2516,7 @@ done:
|
||
{
|
||
/* Sign-ext the value. */
|
||
if (((value >> 32) == 0) && (value & 0x80000000))
|
||
- value |= (int64_t) -1U << 31;
|
||
+ value |= (int64_t)((uint64_t) -1 << 31);
|
||
|
||
|
||
/* Shift the value to positive domain. */
|
||
diff --git binutils-2.30/opcodes/nds32-asm.h binutils-2.30-nds32/opcodes/nds32-asm.h
|
||
index c67e590c64..ea165833c3 100644
|
||
--- binutils-2.30/opcodes/nds32-asm.h
|
||
+++ binutils-2.30-nds32/opcodes/nds32-asm.h
|
||
@@ -77,6 +77,8 @@ enum
|
||
NASM_ATTR_SATURATION_EXT = 0x0400000,
|
||
NASM_ATTR_PCREL = 0x0800000,
|
||
NASM_ATTR_GPREL = 0x1000000,
|
||
+ NASM_ATTR_DSP_ISAEXT = 0x2000000,
|
||
+ NASM_ATTR_ZOL = (1 << 26),
|
||
|
||
/* Attributes for relocations. */
|
||
NASM_ATTR_HI20 = 0x10000000,
|
||
@@ -84,22 +86,30 @@ enum
|
||
NASM_ATTR_LO20 = 0x40000000,
|
||
|
||
/* Attributes for registers. */
|
||
- NASM_ATTR_RDREG = 0x000100
|
||
+ NASM_ATTR_RDREG = 0x000100,
|
||
+
|
||
};
|
||
|
||
+#define NDS32_CORE_COUNT 6
|
||
+#define NDS32_MAIN_CORE 0
|
||
+#define NDS32_ACE 1
|
||
+#define NDS32_COP0 2
|
||
+#define NDS32_COP1 3
|
||
+#define NDS32_COP2 4
|
||
+#define NDS32_COP3 5
|
||
+
|
||
enum
|
||
{
|
||
- /* This is a field (operand) of just a separator char. */
|
||
- SYN_FIELD = 0x100,
|
||
-
|
||
/* This operand is used for input or output. (define or use) */
|
||
- SYN_INPUT = 0x1000,
|
||
- SYN_OUTPUT = 0x2000,
|
||
- SYN_LOPT = 0x4000,
|
||
- SYN_ROPT = 0x8000,
|
||
-
|
||
- /* Hardware resources. */
|
||
- HW_GPR = 0,
|
||
+ SYN_INPUT = 0x10000,
|
||
+ SYN_OUTPUT = 0x20000,
|
||
+ SYN_LOPT = 0x40000,
|
||
+ SYN_ROPT = 0x80000,
|
||
+
|
||
+ /* Hardware resources:
|
||
+ Current set up allows up to 256 resources for each class
|
||
+ defined above. */
|
||
+ HW_GPR = NDS32_MAIN_CORE << 8,
|
||
HW_USR,
|
||
HW_DXR,
|
||
HW_SR,
|
||
@@ -128,14 +138,20 @@ enum
|
||
HW_AEXT_ARIDX,
|
||
HW_AEXT_ARIDX2,
|
||
HW_AEXT_ARIDXI,
|
||
+ HW_AEXT_ARIDXI_MX,
|
||
_HW_LAST,
|
||
/* TODO: Maybe we should add a new type to distinguish address and
|
||
- const int. Only the former allows symbols and relocations. */
|
||
- HW_INT,
|
||
+ const int. Only the former allows symbols and relocations. */
|
||
+ HW_ACE_BASE = NDS32_ACE << 8,
|
||
+ HW_COP0_BASE = NDS32_COP0 << 8,
|
||
+ HW_COP1_BASE = NDS32_COP1 << 8,
|
||
+ HW_COP2_BASE = NDS32_COP2 << 8,
|
||
+ HW_COP3_BASE = NDS32_COP3 << 8,
|
||
+ HW_INT = 0x1000,
|
||
HW_UINT
|
||
};
|
||
|
||
-/* for audio-extension. */
|
||
+/* For audio-extension. */
|
||
enum
|
||
{
|
||
N32_AEXT_AMADD = 0,
|
||
@@ -159,7 +175,7 @@ enum
|
||
N32_AEXT_AMBBS,
|
||
N32_AEXT_AMBTS,
|
||
N32_AEXT_AMTBS,
|
||
- N32_AEXT_AMTTS
|
||
+ N32_AEXT_AMTTS,
|
||
};
|
||
|
||
/* Macro for instruction attribute. */
|
||
@@ -212,7 +228,7 @@ typedef struct nds32_opcode
|
||
struct nds32_opcode *next;
|
||
|
||
/* TODO: Extra constrains and verification.
|
||
- For example, `mov55 $sp, $sp' is not allowed in v3. */
|
||
+ For example, `mov55 $sp, $sp' is not allowed in v3. */
|
||
} opcode_t;
|
||
|
||
typedef struct nds32_asm_insn
|
||
@@ -266,6 +282,11 @@ typedef struct nds32_field
|
||
|
||
extern void nds32_assemble (nds32_asm_desc_t *, nds32_asm_insn_t *, char *);
|
||
extern void nds32_asm_init (nds32_asm_desc_t *, int);
|
||
+extern int nds32_parse_udi (const char *);
|
||
+extern int nds32_parse_cop0 (const char *);
|
||
+extern int nds32_parse_cop1 (const char *);
|
||
+extern int nds32_parse_cop2 (const char *);
|
||
+extern int nds32_parse_cop3 (const char *);
|
||
|
||
#define OP6(op6) (N32_OP6_ ## op6 << 25)
|
||
|
||
@@ -277,6 +298,9 @@ extern void nds32_asm_init (nds32_asm_desc_t *, int);
|
||
#define SIMD(sub) (OP6 (SIMD) | N32_SIMD_ ## sub)
|
||
#define ALU1(sub) (OP6 (ALU1) | N32_ALU1_ ## sub)
|
||
#define ALU2(sub) (OP6 (ALU2) | N32_ALU2_ ## sub)
|
||
+#define ALU2_1(sub) (OP6 (ALU2) | N32_BIT (6) | N32_ALU2_ ## sub)
|
||
+#define ALU2_2(sub) (OP6 (ALU2) | N32_BIT (7) | N32_ALU2_ ## sub)
|
||
+#define ALU2_3(sub) (OP6 (ALU2) | N32_BIT (6) | N32_BIT (7) | N32_ALU2_ ## sub)
|
||
#define MISC(sub) (OP6 (MISC) | N32_MISC_ ## sub)
|
||
#define MEM(sub) (OP6 (MEM) | N32_MEM_ ## sub)
|
||
#define FPU_RA_IMMBI(sub) (OP6 (sub) | N32_BIT (12))
|
||
diff --git binutils-2.30/opcodes/nds32-dis.c binutils-2.30-nds32/opcodes/nds32-dis.c
|
||
index 418019ae87..bb5106f954 100644
|
||
--- binutils-2.30/opcodes/nds32-dis.c
|
||
+++ binutils-2.30-nds32/opcodes/nds32-dis.c
|
||
@@ -35,92 +35,71 @@
|
||
/* Get fields macro define. */
|
||
#define MASK_OP(insn, mask) ((insn) & (0x3f << 25 | (mask)))
|
||
|
||
+/* For mapping symbol. */
|
||
+enum map_type
|
||
+{
|
||
+ MAP_DATA0,
|
||
+ MAP_DATA1,
|
||
+ MAP_DATA2,
|
||
+ MAP_DATA3,
|
||
+ MAP_DATA4,
|
||
+ MAP_CODE,
|
||
+};
|
||
+
|
||
+struct nds32_private_data
|
||
+{
|
||
+ /* Whether any mapping symbols are present in the provided symbol
|
||
+ table. -1 if we do not know yet, otherwise 0 or 1. */
|
||
+ int has_mapping_symbols;
|
||
+
|
||
+ /* Track the last type (although this doesn't seem to be useful). */
|
||
+ enum map_type last_mapping_type;
|
||
+
|
||
+ /* Tracking symbol table information. */
|
||
+ int last_symbol_index;
|
||
+ bfd_vma last_addr;
|
||
+};
|
||
/* Default text to print if an instruction isn't recognized. */
|
||
#define UNKNOWN_INSN_MSG _("*unknown*")
|
||
+
|
||
#define NDS32_PARSE_INSN16 0x01
|
||
#define NDS32_PARSE_INSN32 0x02
|
||
-#define NDS32_PARSE_EX9IT 0x04
|
||
-#define NDS32_PARSE_EX9TAB 0x08
|
||
|
||
+static void print_insn16 (bfd_vma, disassemble_info *,
|
||
+ uint32_t, uint32_t);
|
||
+static void print_insn32 (bfd_vma, disassemble_info *, uint32_t,
|
||
+ uint32_t);
|
||
+static uint32_t nds32_mask_opcode (uint32_t);
|
||
+static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
|
||
+static int get_mapping_symbol_type (struct disassemble_info *, int,
|
||
+ enum map_type *);
|
||
+static int is_mapping_symbol (struct disassemble_info *, int,
|
||
+ enum map_type *);
|
||
+
|
||
+extern const field_t *nds32_field_table[NDS32_CORE_COUNT];
|
||
+extern opcode_t *nds32_opcode_table[NDS32_CORE_COUNT];
|
||
+extern keyword_t **nds32_keyword_table[NDS32_CORE_COUNT];
|
||
extern struct nds32_opcode nds32_opcodes[];
|
||
extern const field_t operand_fields[];
|
||
-extern const keyword_t *keywords[];
|
||
+extern keyword_t *keywords[];
|
||
extern const keyword_t keyword_gpr[];
|
||
-static void print_insn16 (bfd_vma pc, disassemble_info *info,
|
||
- uint32_t insn, uint32_t parse_mode);
|
||
-static void print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
|
||
- uint32_t parse_mode);
|
||
-static uint32_t nds32_mask_opcode (uint32_t);
|
||
-static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
|
||
|
||
-/* define in objdump.c. */
|
||
+/* Defined in objdump.c. */
|
||
struct objdump_disasm_info
|
||
{
|
||
- bfd * abfd;
|
||
- asection * sec;
|
||
- bfd_boolean require_sec;
|
||
- arelent ** dynrelbuf;
|
||
- long dynrelcount;
|
||
+ bfd *abfd;
|
||
+ asection *sec;
|
||
+ bfd_boolean require_sec;
|
||
+ arelent **dynrelbuf;
|
||
+ long dynrelcount;
|
||
disassembler_ftype disassemble_fn;
|
||
- arelent * reloc;
|
||
+ arelent *reloc;
|
||
};
|
||
|
||
-/* file_ptr ex9_filepos=NULL;. */
|
||
-bfd_byte *ex9_data = NULL;
|
||
-int ex9_ready = 0, ex9_base_offset = 0;
|
||
-
|
||
/* Hash function for disassemble. */
|
||
|
||
static htab_t opcode_htab;
|
||
|
||
-static void
|
||
-nds32_ex9_info (bfd_vma pc ATTRIBUTE_UNUSED,
|
||
- disassemble_info *info, uint32_t ex9_index)
|
||
-{
|
||
- uint32_t insn;
|
||
- static asymbol *itb = NULL;
|
||
- bfd_byte buffer[4];
|
||
- long unsigned int isec_vma;
|
||
-
|
||
- /* Lookup itb symbol. */
|
||
- if (!itb)
|
||
- {
|
||
- int i;
|
||
-
|
||
- for (i = 0; i < info->symtab_size; i++)
|
||
- if (bfd_asymbol_name (info->symtab[i])
|
||
- && (strcmp (bfd_asymbol_name (info->symtab[i]), "$_ITB_BASE_") == 0
|
||
- || strcmp (bfd_asymbol_name (info->symtab[i]),
|
||
- "_ITB_BASE_") == 0))
|
||
- {
|
||
- itb = info->symtab[i];
|
||
- break;
|
||
- }
|
||
-
|
||
- /* Lookup it only once, in case _ITB_BASE_ doesn't exist at all. */
|
||
- if (itb == NULL)
|
||
- itb = (void *) -1;
|
||
- }
|
||
-
|
||
- if (itb == (void *) -1)
|
||
- return;
|
||
-
|
||
- isec_vma = itb->section->vma;
|
||
- isec_vma = itb->section->vma - bfd_asymbol_value (itb);
|
||
- if (!itb->section || !itb->section->owner)
|
||
- return;
|
||
- bfd_get_section_contents (itb->section->owner, itb->section, buffer,
|
||
- ex9_index * 4 - isec_vma, 4);
|
||
- insn = bfd_getb32 (buffer);
|
||
- /* 16-bit instructions in ex9 table. */
|
||
- if (insn & 0x80000000)
|
||
- print_insn16 (pc, info, (insn & 0x0000FFFF),
|
||
- NDS32_PARSE_INSN16 | NDS32_PARSE_EX9IT);
|
||
- /* 32-bit instructions in ex9 table. */
|
||
- else
|
||
- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9IT);
|
||
-}
|
||
-
|
||
/* Find the value map register name. */
|
||
|
||
static keyword_t *
|
||
@@ -155,7 +134,7 @@ nds32_parse_audio_ext (const field_t *pfd,
|
||
else
|
||
int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
|
||
|
||
- if (int_value < 10)
|
||
+ if (int_value < 0)
|
||
func (stream, "#%d", int_value);
|
||
else
|
||
func (stream, "#0x%x", int_value);
|
||
@@ -186,7 +165,7 @@ nds32_parse_audio_ext (const field_t *pfd,
|
||
{
|
||
new_value |= 0x04;
|
||
}
|
||
- /* Rt CONCAT(c, t21, t0). */
|
||
+ /* Rt CONCAT(c, t21, t0). */
|
||
else if (strcmp (pfd->name, "a_rt21") == 0)
|
||
{
|
||
new_value = (insn & 0x00000020) >> 5;
|
||
@@ -221,12 +200,33 @@ nds32_parse_audio_ext (const field_t *pfd,
|
||
func (stream, "$%s", psys_reg->name);
|
||
}
|
||
|
||
-/* Dump instruction. If the opcode is unknown, return FALSE. */
|
||
+/* Match instruction opcode with keyword table. */
|
||
+
|
||
+static field_t *
|
||
+match_field (char *name)
|
||
+{
|
||
+ field_t *pfd;
|
||
+ int k;
|
||
+
|
||
+ for (k = 0; k < NDS32_CORE_COUNT; k++)
|
||
+ {
|
||
+ pfd = (field_t *) nds32_field_table[k];
|
||
+ while (1)
|
||
+ {
|
||
+ if (pfd->name == NULL)
|
||
+ break;
|
||
+ if (strcmp (name, pfd->name) == 0)
|
||
+ return pfd;
|
||
+ pfd++;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return NULL;
|
||
+}
|
||
|
||
static void
|
||
nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
- disassemble_info *info, uint32_t insn,
|
||
- uint32_t parse_mode)
|
||
+ disassemble_info *info, uint32_t insn, uint32_t parse_mode)
|
||
{
|
||
int op = 0;
|
||
fprintf_ftype func = info->fprintf_func;
|
||
@@ -245,9 +245,6 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
return;
|
||
}
|
||
|
||
- if (parse_mode & NDS32_PARSE_EX9IT)
|
||
- func (stream, " !");
|
||
-
|
||
pstr_src = opc->instruction;
|
||
if (*pstr_src == 0)
|
||
{
|
||
@@ -259,7 +256,6 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
{
|
||
func (stream, "%s ", opc->opcode);
|
||
}
|
||
-
|
||
/* NDS32_PARSE_INSN32. */
|
||
else
|
||
{
|
||
@@ -269,7 +265,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
else if (strstr (opc->instruction, "tito"))
|
||
func (stream, "%s", opc->opcode);
|
||
else
|
||
- func (stream, "%s\t", opc->opcode);
|
||
+ func (stream, "%s ", opc->opcode);
|
||
}
|
||
|
||
while (*pstr_src)
|
||
@@ -280,7 +276,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
case '=':
|
||
case '&':
|
||
pstr_src++;
|
||
- /* Compare with operand_fields[].name. */
|
||
+ /* Compare name with operand table entries. */
|
||
pstr_tmp = &tmp_string[0];
|
||
while (*pstr_src)
|
||
{
|
||
@@ -293,18 +289,9 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
*pstr_tmp++ = *pstr_src++;
|
||
}
|
||
*pstr_tmp = 0;
|
||
+ if ((pfd = match_field (&tmp_string[0])) == NULL)
|
||
+ return;
|
||
|
||
- pfd = (const field_t *) &operand_fields[0];
|
||
- while (1)
|
||
- {
|
||
- if (pfd->name == NULL)
|
||
- return;
|
||
- else if (strcmp (&tmp_string[0], pfd->name) == 0)
|
||
- break;
|
||
- pfd++;
|
||
- }
|
||
-
|
||
- /* For insn-16. */
|
||
if (parse_mode & NDS32_PARSE_INSN16)
|
||
{
|
||
if (pfd->hw_res == HW_GPR)
|
||
@@ -331,7 +318,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
if (pfd->hw_res == HW_INT)
|
||
int_value =
|
||
N32_IMMS ((insn >> pfd->bitpos),
|
||
- pfd->bitsize) << pfd->shift;
|
||
+ pfd->bitsize) << pfd->shift;
|
||
else
|
||
int_value =
|
||
__GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
|
||
@@ -348,12 +335,11 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
int_value = 0 - (128 - int_value);
|
||
func (stream, "#%d", int_value);
|
||
}
|
||
- /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8/ifcall9. */
|
||
+ /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8. */
|
||
else if ((opc->value == 0xc000) || (opc->value == 0xc800)
|
||
|| (opc->value == 0xd000) || (opc->value == 0xd800)
|
||
|| (opc->value == 0xd500) || (opc->value == 0xe800)
|
||
- || (opc->value == 0xe900)
|
||
- || (opc->value == 0xf800))
|
||
+ || (opc->value == 0xe900))
|
||
{
|
||
info->print_address_func (int_value + pc, info);
|
||
}
|
||
@@ -365,28 +351,17 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
func (stream, "~$%s", keyword_gpr[push25gpr].name);
|
||
func (stream, ", $fp, $gp, $lp}");
|
||
}
|
||
- /* ex9.it. */
|
||
- else if ((opc->value == 0xdd40) || (opc->value == 0xea00))
|
||
- {
|
||
- func (stream, "#%d", int_value);
|
||
- nds32_ex9_info (pc, info, int_value);
|
||
- }
|
||
else if (pfd->hw_res == HW_INT)
|
||
{
|
||
- if (int_value < 10)
|
||
+ if (int_value < 0)
|
||
func (stream, "#%d", int_value);
|
||
else
|
||
func (stream, "#0x%x", int_value);
|
||
}
|
||
- else /* if (pfd->hw_res == HW_UINT). */
|
||
- {
|
||
- if (int_value < 10)
|
||
- func (stream, "#%u", int_value);
|
||
- else
|
||
- func (stream, "#0x%x", int_value);
|
||
- }
|
||
+ /* if(pfd->hw_res == HW_UINT). */
|
||
+ else
|
||
+ func (stream, "#0x%x", int_value);
|
||
}
|
||
-
|
||
}
|
||
/* for audio-ext. */
|
||
else if (op == N32_OP6_AEXT)
|
||
@@ -394,12 +369,13 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
nds32_parse_audio_ext (pfd, info, insn);
|
||
}
|
||
/* for insn-32. */
|
||
- else if (pfd->hw_res < _HW_LAST)
|
||
+ else if (pfd->hw_res < HW_INT)
|
||
{
|
||
int_value =
|
||
__GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
|
||
|
||
- psys_reg = (keyword_t*) keywords[pfd->hw_res];
|
||
+ psys_reg = *(nds32_keyword_table[pfd->hw_res >> 8]
|
||
+ + (pfd->hw_res & 0xff));
|
||
|
||
psys_reg = nds32_find_reg_keyword (psys_reg, int_value);
|
||
/* For HW_SR, dump the index when it can't
|
||
@@ -444,15 +420,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
/* FIXME: Handle relocation. */
|
||
if (info->flags & INSN_HAS_RELOC)
|
||
pc = 0;
|
||
- /* Check if insn32 in ex9 table. */
|
||
- if (parse_mode & NDS32_PARSE_EX9IT)
|
||
- info->print_address_func ((pc & 0xFE000000) | int_value,
|
||
- info);
|
||
- /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */
|
||
- else if (parse_mode & NDS32_PARSE_EX9TAB)
|
||
- func (stream, "PC(31,25)|#0x%x", int_value);
|
||
- else
|
||
- info->print_address_func (int_value + pc, info);
|
||
+ info->print_address_func (int_value + pc, info);
|
||
}
|
||
else if (op == N32_OP6_LSMW)
|
||
{
|
||
@@ -496,17 +464,14 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
}
|
||
else if (pfd->hw_res == HW_INT)
|
||
{
|
||
- if (int_value < 10)
|
||
+ if (int_value < 0)
|
||
func (stream, "#%d", int_value);
|
||
else
|
||
func (stream, "#0x%x", int_value);
|
||
}
|
||
- else /* if (pfd->hw_res == HW_UINT). */
|
||
+ else /* if(pfd->hw_res == HW_UINT). */
|
||
{
|
||
- if (int_value < 10)
|
||
- func (stream, "#%u", int_value);
|
||
- else
|
||
- func (stream, "#0x%x", int_value);
|
||
+ func (stream, "#0x%x", int_value);
|
||
}
|
||
}
|
||
break;
|
||
@@ -516,34 +481,13 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
|
||
pstr_src++;
|
||
break;
|
||
|
||
- case ',':
|
||
- func (stream, ", ");
|
||
- pstr_src++;
|
||
- break;
|
||
-
|
||
- case '+':
|
||
- func (stream, " + ");
|
||
- pstr_src++;
|
||
- break;
|
||
-
|
||
- case '<':
|
||
- if (pstr_src[1] == '<')
|
||
- {
|
||
- func (stream, " << ");
|
||
- pstr_src += 2;
|
||
- }
|
||
- else
|
||
- {
|
||
- func (stream, " <");
|
||
- pstr_src++;
|
||
- }
|
||
- break;
|
||
-
|
||
default:
|
||
func (stream, "%c", *pstr_src++);
|
||
break;
|
||
- }
|
||
- }
|
||
+ } /* switch (*pstr_src). */
|
||
+
|
||
+ } /* while (*pstr_src). */
|
||
+ return;
|
||
}
|
||
|
||
/* Filter instructions with some bits must be fixed. */
|
||
@@ -571,7 +515,7 @@ nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
|
||
if (__GF (insn, 5, 5) != 0)
|
||
*opc = NULL;
|
||
break;
|
||
- case BR2 (IFCALL):
|
||
+ case BR2 (SOP0):
|
||
if (__GF (insn, 20, 5) != 0)
|
||
*opc = NULL;
|
||
break;
|
||
@@ -692,6 +636,7 @@ print_insn16 (bfd_vma pc, disassemble_info *info,
|
||
}
|
||
break;
|
||
}
|
||
+
|
||
opcode = insn & mask;
|
||
opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
|
||
|
||
@@ -715,6 +660,21 @@ htab_hash_eq (const void *p, const void *q)
|
||
return (pinsn == qinsn);
|
||
}
|
||
|
||
+static uint32_t
|
||
+mask_CEXT (uint32_t insn)
|
||
+{
|
||
+ opcode_t *opc = nds32_opcode_table[NDS32_ACE], *max_opc = NULL;
|
||
+
|
||
+ for (; opc != NULL && opc->opcode != NULL; opc++)
|
||
+ {
|
||
+ if ((insn & opc->value) == opc->value
|
||
+ && (max_opc == NULL || opc->value > max_opc->value))
|
||
+ max_opc = opc;
|
||
+ }
|
||
+
|
||
+ return max_opc ? max_opc->value : insn;
|
||
+}
|
||
+
|
||
/* Get the format of instruction. */
|
||
|
||
static uint32_t
|
||
@@ -754,18 +714,26 @@ nds32_mask_opcode (uint32_t insn)
|
||
case N32_OP6_ORI:
|
||
case N32_OP6_SLTI:
|
||
case N32_OP6_SLTSI:
|
||
- case N32_OP6_CEXT:
|
||
case N32_OP6_BITCI:
|
||
return MASK_OP (insn, 0);
|
||
+ case N32_OP6_CEXT:
|
||
+ return mask_CEXT (insn);
|
||
case N32_OP6_ALU2:
|
||
/* FFBI */
|
||
if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | N32_BIT (6)))
|
||
return MASK_OP (insn, 0x7f);
|
||
- else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | N32_BIT (6))
|
||
- || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | N32_BIT (6)))
|
||
+ else if (__GF (insn, 0, 10) == (N32_ALU2_MFUSR | N32_BIT (6))
|
||
+ || __GF (insn, 0, 10) == (N32_ALU2_MTUSR | N32_BIT (6)))
|
||
/* RDOV CLROV */
|
||
return MASK_OP (insn, 0xf81ff);
|
||
- return MASK_OP (insn, 0x1ff);
|
||
+ else if (__GF (insn, 0, 10) == (N32_ALU2_ONEOP | N32_BIT (7)))
|
||
+ {
|
||
+ /* INSB */
|
||
+ if (__GF (insn, 12, 3) == 4)
|
||
+ return MASK_OP (insn, 0x73ff);
|
||
+ return MASK_OP (insn, 0x7fff);
|
||
+ }
|
||
+ return MASK_OP (insn, 0x3ff);
|
||
case N32_OP6_ALU1:
|
||
case N32_OP6_SIMD:
|
||
return MASK_OP (insn, 0x1f);
|
||
@@ -794,113 +762,116 @@ nds32_mask_opcode (uint32_t insn)
|
||
case N32_OP6_BR1:
|
||
return MASK_OP (insn, 0x1 << 14);
|
||
case N32_OP6_BR2:
|
||
- return MASK_OP (insn, 0xf << 16);
|
||
+ if (__GF (insn, 16, 4) == 0)
|
||
+ return MASK_OP (insn, 0x1ff << 16);
|
||
+ else
|
||
+ return MASK_OP (insn, 0xf << 16);
|
||
case N32_OP6_BR3:
|
||
return MASK_OP (insn, 0x1 << 19);
|
||
case N32_OP6_MISC:
|
||
- switch (__GF (insn, 0, 5))
|
||
- {
|
||
- case N32_MISC_MTSR:
|
||
- /* SETGIE and SETEND */
|
||
- if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
|
||
- return MASK_OP (insn, 0x1fffff);
|
||
- return MASK_OP (insn, 0x1f);
|
||
- case N32_MISC_TLBOP:
|
||
- if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
|
||
- /* PB FLUA */
|
||
- return MASK_OP (insn, 0x3ff);
|
||
- return MASK_OP (insn, 0x1f);
|
||
- default:
|
||
- return MASK_OP (insn, 0x1f);
|
||
- }
|
||
+ switch (__GF (insn, 0, 5))
|
||
+ {
|
||
+ case N32_MISC_MTSR:
|
||
+ /* SETGIE and SETEND */
|
||
+ if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
|
||
+ return MASK_OP (insn, 0x1fffff);
|
||
+ return MASK_OP (insn, 0x1f);
|
||
+ case N32_MISC_TLBOP:
|
||
+ if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
|
||
+ /* PB FLUA */
|
||
+ return MASK_OP (insn, 0x3ff);
|
||
+ return MASK_OP (insn, 0x1f);
|
||
+ default:
|
||
+ return MASK_OP (insn, 0x1f);
|
||
+ }
|
||
case N32_OP6_COP:
|
||
- if (__GF (insn, 4, 2) == 0)
|
||
- {
|
||
- /* FPU */
|
||
- switch (__GF (insn, 0, 4))
|
||
- {
|
||
- case 0x0:
|
||
- case 0x8:
|
||
- /* FS1/F2OP FD1/F2OP */
|
||
- if (__GF (insn, 6, 4) == 0xf)
|
||
- return MASK_OP (insn, 0x7fff);
|
||
- /* FS1 FD1 */
|
||
- return MASK_OP (insn, 0x3ff);
|
||
- case 0x4:
|
||
- case 0xc:
|
||
- /* FS2 */
|
||
- return MASK_OP (insn, 0x3ff);
|
||
- case 0x1:
|
||
- case 0x9:
|
||
- /* XR */
|
||
- if (__GF (insn, 6, 4) == 0xc)
|
||
- return MASK_OP (insn, 0x7fff);
|
||
- /* MFCP MTCP */
|
||
- return MASK_OP (insn, 0x3ff);
|
||
- default:
|
||
- return MASK_OP (insn, 0xff);
|
||
- }
|
||
- }
|
||
- else if (__GF (insn, 0, 2) == 0)
|
||
- return MASK_OP (insn, 0xf);
|
||
- return MASK_OP (insn, 0xcf);
|
||
+ if (__GF (insn, 4, 2) == 0)
|
||
+ {
|
||
+ /* FPU */
|
||
+ switch (__GF (insn, 0, 4))
|
||
+ {
|
||
+ case 0x0:
|
||
+ case 0x8:
|
||
+ /* FS1/F2OP FD1/F2OP */
|
||
+ if (__GF (insn, 6, 4) == 0xf)
|
||
+ return MASK_OP (insn, 0x7fff);
|
||
+ /* FS1 FD1 */
|
||
+ return MASK_OP (insn, 0x3ff);
|
||
+ case 0x4:
|
||
+ case 0xc:
|
||
+ /* FS2 */
|
||
+ return MASK_OP (insn, 0x3ff);
|
||
+ case 0x1:
|
||
+ case 0x9:
|
||
+ /* XR */
|
||
+ if (__GF (insn, 6, 4) == 0xc)
|
||
+ return MASK_OP (insn, 0x7fff);
|
||
+ /* MFCP MTCP */
|
||
+ return MASK_OP (insn, 0x3ff);
|
||
+ default:
|
||
+ return MASK_OP (insn, 0xff);
|
||
+ }
|
||
+ }
|
||
+ else if (__GF (insn, 0, 2) == 0)
|
||
+ return MASK_OP (insn, 0xf);
|
||
+ return MASK_OP (insn, 0xcf);
|
||
case N32_OP6_AEXT:
|
||
- /* AUDIO */
|
||
- switch (__GF (insn, 23, 2))
|
||
- {
|
||
- case 0x0:
|
||
- if (__GF (insn, 5, 4) == 0)
|
||
- /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
|
||
- return MASK_OP (insn, (0x1f << 20) | 0x1ff);
|
||
- else if (__GF (insn, 5, 4) == 1)
|
||
- /* ALR ASR ALA ASA AUPI */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
- else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
|
||
- /* ALR2 */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
- else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
|
||
- /* AWEXT ASATS48 */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
- else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
|
||
- /* AMTAR AMTAR2 AMFAR AMFAR2 */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
|
||
- else if (__GF (insn, 7, 2) == 3)
|
||
- /* AMxxxSA */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
- else if (__GF (insn, 6, 3) == 2)
|
||
- /* AMxxxL.S */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
- else
|
||
- /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
- case 0x1:
|
||
- if (__GF (insn, 20, 3) == 0)
|
||
- /* AADDL ASUBL */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
|
||
- else if (__GF (insn, 20, 3) == 1)
|
||
- /* AMTARI Ix AMTARI Mx */
|
||
- return MASK_OP (insn, (0x1f << 20));
|
||
- else if (__GF (insn, 6, 3) == 2)
|
||
- /* AMAWzSl.S AMWzSl.S */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
- else if (__GF (insn, 7, 2) == 3)
|
||
- /* AMAWzSSA AMWzSSA */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
- else
|
||
- /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
- case 0x2:
|
||
- if (__GF (insn, 6, 3) == 2)
|
||
- /* AMAyySl.S AMWyySl.S */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
- else if (__GF (insn, 7, 2) == 3)
|
||
- /* AMAWyySSA AMWyySSA */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
- else
|
||
- /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
|
||
- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
- }
|
||
- return MASK_OP (insn, 0x1f << 20);
|
||
+ /* AUDIO */
|
||
+ switch (__GF (insn, 23, 2))
|
||
+ {
|
||
+ case 0x0:
|
||
+ if (__GF (insn, 5, 4) == 0)
|
||
+ /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
|
||
+ return MASK_OP (insn, (0x1f << 20) | 0x1ff);
|
||
+ else if (__GF (insn, 5, 4) == 1)
|
||
+ /* ALR ASR ALA ASA AUPI */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
+ else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
|
||
+ /* ALR2 */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
+ else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
|
||
+ /* AWEXT ASATS48 */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
+ else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
|
||
+ /* AMTAR AMTAR2 AMFAR AMFAR2 */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
|
||
+ else if (__GF (insn, 7, 2) == 3)
|
||
+ /* AMxxxSA */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
+ else if (__GF (insn, 6, 3) == 2)
|
||
+ /* AMxxxL.S */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
+ else
|
||
+ /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
+ case 0x1:
|
||
+ if (__GF (insn, 20, 3) == 0)
|
||
+ /* AADDL ASUBL */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
|
||
+ else if (__GF (insn, 20, 3) == 1)
|
||
+ /* AMTARI Ix AMTARI Mx */
|
||
+ return MASK_OP (insn, (0x1f << 20));
|
||
+ else if (__GF (insn, 6, 3) == 2)
|
||
+ /* AMAWzSl.S AMWzSl.S */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
+ else if (__GF (insn, 7, 2) == 3)
|
||
+ /* AMAWzSSA AMWzSSA */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
+ else
|
||
+ /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
+ case 0x2:
|
||
+ if (__GF (insn, 6, 3) == 2)
|
||
+ /* AMAyySl.S AMWyySl.S */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
|
||
+ else if (__GF (insn, 7, 2) == 3)
|
||
+ /* AMAWyySSA AMWyySSA */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
|
||
+ else
|
||
+ /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
|
||
+ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
|
||
+ }
|
||
+ return MASK_OP (insn, 0x1f << 20);
|
||
default:
|
||
return (1 << 31);
|
||
}
|
||
@@ -971,11 +942,6 @@ nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
|
||
break;
|
||
case N32_OP6_COP:
|
||
break;
|
||
- case 0xea00:
|
||
- /* break16 ex9 */
|
||
- if (__GF (insn, 5, 4) != 0)
|
||
- string = "ex9";
|
||
- break;
|
||
case 0x9200:
|
||
/* nop16 */
|
||
if (__GF (insn, 0, 9) == 0)
|
||
@@ -1005,46 +971,195 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info)
|
||
{
|
||
int status;
|
||
bfd_byte buf[4];
|
||
+ bfd_byte buf_data[16];
|
||
+ long long given;
|
||
+ long long given1;
|
||
uint32_t insn;
|
||
- static int init = 1;
|
||
- int i = 0;
|
||
- struct nds32_opcode *opc;
|
||
- struct nds32_opcode **slot;
|
||
+ int n;
|
||
+ int last_symbol_index = -1;
|
||
+ bfd_vma addr;
|
||
+ int is_data = FALSE;
|
||
+ bfd_boolean found = FALSE;
|
||
+ struct nds32_private_data *private_data;
|
||
+ unsigned int size = 16;
|
||
+ enum map_type mapping_type = MAP_CODE;
|
||
+
|
||
+ if (info->private_data == NULL)
|
||
+ {
|
||
+ /* Note: remain lifecycle throughout whole execution. */
|
||
+ static struct nds32_private_data private;
|
||
+ private.has_mapping_symbols = -1; /* unknown yet. */
|
||
+ private.last_symbol_index = -1;
|
||
+ private.last_addr = 0;
|
||
+ info->private_data = &private;
|
||
+ }
|
||
+ private_data = info->private_data;
|
||
|
||
- if (init)
|
||
+ if (info->symtab_size != 0)
|
||
{
|
||
- /* Build opcode table. */
|
||
- opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
|
||
- NULL, xcalloc, free);
|
||
+ int start;
|
||
+ if (pc == 0)
|
||
+ start = 0;
|
||
+ else
|
||
+ {
|
||
+ start = info->symtab_pos;
|
||
+ if (start < private_data->last_symbol_index)
|
||
+ start = private_data->last_symbol_index;
|
||
+ }
|
||
|
||
- while (nds32_opcodes[i].opcode != NULL)
|
||
+ if (0 > start)
|
||
+ start = 0;
|
||
+
|
||
+ if (private_data->has_mapping_symbols != 0
|
||
+ && ((strncmp (".text", info->section->name, 5) == 0)))
|
||
{
|
||
- opc = &nds32_opcodes[i];
|
||
- slot =
|
||
- (struct nds32_opcode **) htab_find_slot (opcode_htab, &opc->value,
|
||
- INSERT);
|
||
- if (*slot == NULL)
|
||
+ for (n = start; n < info->symtab_size; n++)
|
||
{
|
||
- /* This is the new one. */
|
||
- *slot = opc;
|
||
+ addr = bfd_asymbol_value (info->symtab[n]);
|
||
+ if (addr > pc)
|
||
+ break;
|
||
+ if (get_mapping_symbol_type (info, n, &mapping_type))
|
||
+ {
|
||
+ last_symbol_index = n;
|
||
+ found = TRUE;
|
||
+ }
|
||
}
|
||
- else
|
||
+
|
||
+ if (found)
|
||
+ private_data->has_mapping_symbols = 1;
|
||
+ else if (!found && private_data->has_mapping_symbols == -1)
|
||
+ {
|
||
+ /* Make sure there are no any mapping symbol. */
|
||
+ for (n = 0; n < info->symtab_size; n++)
|
||
+ {
|
||
+ if (is_mapping_symbol (info, n, &mapping_type))
|
||
+ {
|
||
+ private_data->has_mapping_symbols = -1;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ if (private_data->has_mapping_symbols == -1)
|
||
+ private_data->has_mapping_symbols = 0;
|
||
+
|
||
+ }
|
||
+
|
||
+ private_data->last_symbol_index = last_symbol_index;
|
||
+ private_data->last_mapping_type = mapping_type;
|
||
+ is_data = (private_data->last_mapping_type == MAP_DATA0
|
||
+ || private_data->last_mapping_type == MAP_DATA1
|
||
+ || private_data->last_mapping_type == MAP_DATA2
|
||
+ || private_data->last_mapping_type == MAP_DATA3
|
||
+ || private_data->last_mapping_type == MAP_DATA4);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /* Wonder data or instruction. */
|
||
+ if (is_data)
|
||
+ {
|
||
+ unsigned int i1;
|
||
+
|
||
+ /* fix corner case: there is no next mapping symbol,
|
||
+ * let mapping type decides size */
|
||
+ if (last_symbol_index + 1 >= info->symtab_size)
|
||
+ {
|
||
+ if (mapping_type == MAP_DATA0)
|
||
+ size = 1;
|
||
+ if (mapping_type == MAP_DATA1)
|
||
+ size = 2;
|
||
+ if (mapping_type == MAP_DATA2)
|
||
+ size = 4;
|
||
+ if (mapping_type == MAP_DATA3)
|
||
+ size = 8;
|
||
+ if (mapping_type == MAP_DATA4)
|
||
+ size = 16;
|
||
+ }
|
||
+ for (n = last_symbol_index + 1; n < info->symtab_size; n++)
|
||
+ {
|
||
+ addr = bfd_asymbol_value (info->symtab[n]);
|
||
+
|
||
+ enum map_type fake_mapping_type;
|
||
+ if (get_mapping_symbol_type (info, n, &fake_mapping_type))
|
||
+ {
|
||
+ if (addr > pc
|
||
+ && ((info->section == NULL)
|
||
+ || (info->section == info->symtab[n]->section)))
|
||
+ {
|
||
+ if (addr - pc < size)
|
||
+ {
|
||
+ size = addr - pc;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+
|
||
+ if (size == 3)
|
||
+ size = (pc & 1) ? 1 : 2;
|
||
+
|
||
+
|
||
+ /* Read bytes from BFD. */
|
||
+ info->read_memory_func (pc, (bfd_byte *) buf_data, size, info);
|
||
+ given = 0;
|
||
+ given1 = 0;
|
||
+ /* Start assembling data. */
|
||
+ /* Little endian of data. */
|
||
+ if (info->endian == BFD_ENDIAN_LITTLE)
|
||
+ {
|
||
+ for (i1 = size - 1;; i1--)
|
||
{
|
||
- /* Already exists. Append to the list. */
|
||
- opc = *slot;
|
||
- while (opc->next)
|
||
- opc = opc->next;
|
||
- opc->next = &nds32_opcodes[i];
|
||
+ if (i1 >= 8)
|
||
+ given1 = buf_data[i1] | (given1 << 8);
|
||
+ else
|
||
+ given = buf_data[i1] | (given << 8);
|
||
+ if (i1 == 0)
|
||
+ break;
|
||
}
|
||
- i++;
|
||
}
|
||
- init = 0;
|
||
+ else
|
||
+ {
|
||
+ /* Big endian of data. */
|
||
+ for (i1 = 0; i1 < size; i1++) {
|
||
+ if (i1 <= 7)
|
||
+ given = buf_data[i1] | (given << 8);
|
||
+ else
|
||
+ given1 = buf_data[i1] | (given1 << 8);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ info->bytes_per_line = 4;
|
||
+
|
||
+ if (size == 16)
|
||
+ {
|
||
+ info->fprintf_func (info->stream, ".qword\t0x%016llx%016llx",
|
||
+ given, given1);
|
||
+ }
|
||
+ else if (size == 8)
|
||
+ {
|
||
+ info->fprintf_func (info->stream, ".dword\t0x%016llx", given);
|
||
+ }
|
||
+ else if (size == 4)
|
||
+ {
|
||
+ info->fprintf_func (info->stream, ".word\t0x%08llx", given);
|
||
+ }
|
||
+ else if (size == 2) /* short */
|
||
+ {
|
||
+ if (mapping_type == MAP_DATA0)
|
||
+ info->fprintf_func (info->stream, ".byte\t0x%02llx", given & 0xFF);
|
||
+ else
|
||
+ info->fprintf_func (info->stream, ".short\t0x%04llx", given);
|
||
+ }
|
||
+ else
|
||
+ { /* byte */
|
||
+ info->fprintf_func (info->stream, ".byte\t0x%02llx", given);
|
||
+ }
|
||
+ return size;
|
||
}
|
||
|
||
status = info->read_memory_func (pc, (bfd_byte *) buf, 4, info);
|
||
if (status)
|
||
{
|
||
- /* for the last 16-bit instruction. */
|
||
+ /* For the last 16-bit instruction. */
|
||
status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info);
|
||
if (status)
|
||
{
|
||
@@ -1052,17 +1167,10 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info)
|
||
return -1;
|
||
}
|
||
}
|
||
-
|
||
insn = bfd_getb32 (buf);
|
||
/* 16-bit instruction. */
|
||
if (insn & 0x80000000)
|
||
{
|
||
- if (info->section && strstr (info->section->name, ".ex9.itable") != NULL)
|
||
- {
|
||
- print_insn16 (pc, info, (insn & 0x0000FFFF),
|
||
- NDS32_PARSE_INSN16 | NDS32_PARSE_EX9TAB);
|
||
- return 4;
|
||
- }
|
||
print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
|
||
return 2;
|
||
}
|
||
@@ -1070,11 +1178,206 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info)
|
||
/* 32-bit instructions. */
|
||
else
|
||
{
|
||
- if (info->section
|
||
- && strstr (info->section->name, ".ex9.itable") != NULL)
|
||
- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9TAB);
|
||
- else
|
||
- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
|
||
+ print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
|
||
return 4;
|
||
}
|
||
}
|
||
+
|
||
+/* Ignore disassembling unnecessary name. */
|
||
+
|
||
+static bfd_boolean
|
||
+nds32_symbol_is_valid (asymbol *sym,
|
||
+ struct disassemble_info *info ATTRIBUTE_UNUSED)
|
||
+{
|
||
+ const char *name;
|
||
+
|
||
+ if (sym == NULL)
|
||
+ return FALSE;
|
||
+
|
||
+ name = bfd_asymbol_name (sym);
|
||
+
|
||
+ /* Mapping symbol is invalid. */
|
||
+ if (name[0] == '$')
|
||
+ return FALSE;
|
||
+ return TRUE;
|
||
+}
|
||
+
|
||
+static void
|
||
+nds32_add_opcode_hash_table (unsigned indx)
|
||
+{
|
||
+ opcode_t *opc;
|
||
+
|
||
+ opc = nds32_opcode_table[indx];
|
||
+ if (opc == NULL)
|
||
+ return;
|
||
+
|
||
+ while (opc->opcode != NULL)
|
||
+ {
|
||
+ opcode_t **slot;
|
||
+
|
||
+ slot = (opcode_t **) htab_find_slot (opcode_htab, &opc->value, INSERT);
|
||
+ if (*slot == NULL)
|
||
+ {
|
||
+ /* This is the new one. */
|
||
+ *slot = opc;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ opcode_t *tmp;
|
||
+
|
||
+ /* Already exists. Append to the list. */
|
||
+ tmp = *slot;
|
||
+ while (tmp->next)
|
||
+ tmp = tmp->next;
|
||
+ tmp->next = opc;
|
||
+ opc->next = NULL;
|
||
+ }
|
||
+ opc++;
|
||
+ }
|
||
+}
|
||
+
|
||
+void
|
||
+disassemble_init_nds32 (struct disassemble_info *info)
|
||
+{
|
||
+ static unsigned init_done = 0;
|
||
+ const char *ptr;
|
||
+ unsigned k;
|
||
+
|
||
+ /* Set up symbol checking function. */
|
||
+ info->symbol_is_valid = nds32_symbol_is_valid;
|
||
+
|
||
+ /* Only need to initialize once: */
|
||
+ /* High level will call this function for every object file. */
|
||
+ /* For example, when disassemble all members of a library. */
|
||
+ if (init_done)
|
||
+ return;
|
||
+
|
||
+ /* Setup main core. */
|
||
+ nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0];
|
||
+ nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
|
||
+ nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0];
|
||
+
|
||
+ /* Process command line options. */
|
||
+ ptr = info->disassembler_options;
|
||
+ if (ptr != NULL)
|
||
+ {
|
||
+ const char *start, *end;
|
||
+ do
|
||
+ {
|
||
+ char name[256];
|
||
+
|
||
+ /* Get one option. */
|
||
+ start = strchr(ptr, '=');
|
||
+ end = strchr(ptr, ',');
|
||
+ if (start == NULL)
|
||
+ fprintf (stderr, "Unknown nds32 disassembler option: %s\n", ptr);
|
||
+ else
|
||
+ {
|
||
+ start++;
|
||
+ if (end == NULL)
|
||
+ strcpy (name, start);
|
||
+ else
|
||
+ strncpy (name, start, end - start);
|
||
+
|
||
+ /* Parse and process the option. */
|
||
+ if (strncmp (ptr, "ace=", 4) == 0)
|
||
+ nds32_parse_udi (name);
|
||
+ else if (strncmp (ptr, "cop0=", 5) == 0)
|
||
+ nds32_parse_cop0 (name);
|
||
+ else if (strncmp (ptr, "cop1=", 5) == 0)
|
||
+ nds32_parse_cop1 (name);
|
||
+ else if (strncmp (ptr, "cop2=", 5) == 0)
|
||
+ nds32_parse_cop2 (name);
|
||
+ else if (strncmp (ptr, "cop3=", 5) == 0)
|
||
+ nds32_parse_cop3 (name);
|
||
+ else
|
||
+ fprintf (stderr, "Unknown nds32 disassembler option: %s\n",
|
||
+ ptr);
|
||
+
|
||
+ if (end == NULL)
|
||
+ break;
|
||
+ ptr = end + 1;
|
||
+ }
|
||
+ } while (1);
|
||
+ }
|
||
+
|
||
+ /* Build opcode table. */
|
||
+ opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq, NULL,
|
||
+ xcalloc, free);
|
||
+
|
||
+ for (k = 0; k < NDS32_CORE_COUNT; k++)
|
||
+ {
|
||
+ /* Add op-codes. */
|
||
+ nds32_add_opcode_hash_table (k);
|
||
+ }
|
||
+
|
||
+ init_done = 1;
|
||
+}
|
||
+
|
||
+static int
|
||
+is_mapping_symbol (struct disassemble_info *info, int n,
|
||
+ enum map_type *map_type)
|
||
+{
|
||
+ const char *name = NULL;
|
||
+
|
||
+ /* Get symbol name. */
|
||
+ name = bfd_asymbol_name (info->symtab[n]);
|
||
+
|
||
+ if (name[1] == 'c')
|
||
+ {
|
||
+ *map_type = MAP_CODE;
|
||
+ return TRUE;
|
||
+ }
|
||
+ else if (name[1] == 'd' && name[2] == '0')
|
||
+ {
|
||
+ *map_type = MAP_DATA0;
|
||
+ return TRUE;
|
||
+ }
|
||
+ else if (name[1] == 'd' && name[2] == '1')
|
||
+ {
|
||
+ *map_type = MAP_DATA1;
|
||
+ return TRUE;
|
||
+ }
|
||
+ else if (name[1] == 'd' && name[2] == '2')
|
||
+ {
|
||
+ *map_type = MAP_DATA2;
|
||
+ return TRUE;
|
||
+ }
|
||
+ else if (name[1] == 'd' && name[2] == '3')
|
||
+ {
|
||
+ *map_type = MAP_DATA3;
|
||
+ return TRUE;
|
||
+ }
|
||
+ else if (name[1] == 'd' && name[2] == '4')
|
||
+ {
|
||
+ *map_type = MAP_DATA4;
|
||
+ return TRUE;
|
||
+ }
|
||
+
|
||
+ return FALSE;
|
||
+}
|
||
+
|
||
+static int
|
||
+get_mapping_symbol_type (struct disassemble_info *info, int n,
|
||
+ enum map_type *map_type)
|
||
+{
|
||
+ /* If the symbol is in a different section, ignore it. */
|
||
+ if (info->section != NULL && info->section != info->symtab[n]->section)
|
||
+ return FALSE;
|
||
+
|
||
+ return is_mapping_symbol (info, n, map_type);
|
||
+}
|
||
+
|
||
+void
|
||
+print_nds32_disassembler_options (FILE *stream)
|
||
+{
|
||
+ fprintf (stream, _("\n\
|
||
+The following Andes specific disassembler options are supported for use with\n\
|
||
+the -M switch:\n"));
|
||
+
|
||
+ fprintf (stream, " ace=<shrlibfile> Support user defined instruction extension\n");
|
||
+ fprintf (stream, " cop0=<shrlibfile> Support coprocessor 0 extension\n");
|
||
+ fprintf (stream, " cop1=<shrlibfile> Support coprocessor 1 extension\n");
|
||
+ fprintf (stream, " cop2=<shrlibfile> Support coprocessor 2 extension\n");
|
||
+ fprintf (stream, " cop3=<shrlibfile> Support coprocessor 3 extension\n\n");
|
||
+}
|