NDS32: Code refactoring of relaxation.

Refactor each relaxation pattern to raise the maintainability.
In origin, all patterns is analysed in nds32_elf_relax_section,
so it is hard to debug and maintain.  Therefore, we classify all
patterns into different functions in this patch.
Moreover, we adjust all optimizations into nds32_elf_relax_section
to take these optimizations in turn.  This can promise all relaxation
being done after calling gld${EMULATION_NAME}_after_allocation.
This commit is contained in:
Kuan-Lin Chen 2014-09-11 14:25:05 +08:00
parent 40c7a7cb74
commit 1c8f6a4d1f
13 changed files with 6842 additions and 4602 deletions

View File

@ -1,3 +1,35 @@
2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
* bfd-in2.h: Regenerate.
* elf32-nds32.c (nds32_elf_mkobject): Hook bfd_elf32_mkobject.
(nds32_elf_relax_section): Code refactoring.
(nds32_elf_relax_longcall1, nds32_elf_relax_longcall2,
nds32_elf_relax_longcall3, nds32_elf_relax_longcall4,
nds32_elf_relax_longcall5, nds32_elf_relax_longcall6): Relax call
pattern. The first three is moved from nds32_elf_relax_section,
and the last three is new function.
(nds32_elf_relax_longjump1, nds32_elf_relax_longjump2,
nds32_elf_relax_longjump3, nds32_elf_relax_longjump4,
nds32_elf_relax_longjump5, nds32_elf_relax_longjump6,
nds32_elf_relax_longjump7): Relax condition branch pattern. The first
three is moved from nds32_elf_relax_section, and the last four
is new function.
(nds32_elf_relax_loadstore, nds32_elf_relax_lo12): Relax load-store
pattern and address setting pattern.
(nds32_elf_relax_piclo12, nds32_elf_relax_ptr,
nds32_elf_relax_pltgot_suff, nds32_elf_relax_got_suff,
nds32_elf_relax_gotoff_suff): Relax pic pattern.
(nds32_elf_relax_letlslo12, nds32_elf_relax_letlsadd,
nds32_elf_relax_letlsls): Relax TLS pattern.
(nds32_relax_adjust_label): Adjust alignment and nop.
(nds32_elf_pick_relax): Choose relaxation optimization.
(nds32_elf_get_relocated_section_contents): New hook.
(nds32_elf_order_insn_times, nds32_elf_ex9_build_itable): Release ex9
table 234th entry.
* elf32-nds32.h: Declare.
* libbfd.h: Regenerate.
* reloc.c: Add nds32 new relocations.
2014-09-15 Chen Gang <gang.chen.5i5j@gmail.com>
* dwarf2.c (find_abstract_instance_name): Use 'form' instead of

View File

@ -3956,6 +3956,13 @@ and shift left by 0 for use in lbi.gp, sbi.gp... */
BFD_RELOC_NDS32_15_FIXED,
BFD_RELOC_NDS32_17_FIXED,
BFD_RELOC_NDS32_25_FIXED,
BFD_RELOC_NDS32_LONGCALL4,
BFD_RELOC_NDS32_LONGCALL5,
BFD_RELOC_NDS32_LONGCALL6,
BFD_RELOC_NDS32_LONGJUMP4,
BFD_RELOC_NDS32_LONGJUMP5,
BFD_RELOC_NDS32_LONGJUMP6,
BFD_RELOC_NDS32_LONGJUMP7,
/* for PIC */
BFD_RELOC_NDS32_PLTREL_HI20,
@ -4016,12 +4023,32 @@ This is a 5 bit absolute address. */
BFD_RELOC_NDS32_DIFF16,
BFD_RELOC_NDS32_DIFF32,
BFD_RELOC_NDS32_DIFF_ULEB128,
BFD_RELOC_NDS32_EMPTY,
/* This is a 25 bit absolute address. */
BFD_RELOC_NDS32_25_ABS,
/* For ex9 and ifc using. */
BFD_RELOC_NDS32_DATA,
BFD_RELOC_NDS32_TRAN,
BFD_RELOC_NDS32_17IFC_PCREL,
BFD_RELOC_NDS32_10IFCU_PCREL,
/* For TLS. */
BFD_RELOC_NDS32_TPOFF,
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,
/* This is a 9-bit reloc */
BFD_RELOC_V850_9_PCREL,

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,7 @@
/* Relocation flags for R_NDS32_INSN16. */
/* Tag the nop16 can be removed. */
#define R_NDS32_INSN16_CONVERT_FLAG (1 << 0)
/* Convert a gp-relative access (e.g., lwi.gp)
to fp-as-gp access (lwi37.fp).
@ -67,15 +68,28 @@
in this region due to performance drop. */
#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG (1 << 4)
/* Tag range for LOADSTORE relocation. */
enum
{
NDS32_LOADSTORE_NONE = 0x0,
NDS32_LOADSTORE_BYTE = 0x1,
NDS32_LOADSTORE_HALF = 0x2,
NDS32_LOADSTORE_WORD = 0x4,
NDS32_LOADSTORE_FLOAT_S = 0x8,
NDS32_LOADSTORE_FLOAT_D = 0x10,
NDS32_LOADSTORE_IMM = 0x20
};
/* Relax tag for nds32_elf_relax_section, we have to specify which
optimization do in this round. */
enum
{
NDS32_RELAX_NONE_ROUND = 0,
NDS32_RELAX_JUMP_IFC_ROUND = 1,
NDS32_RELAX_NORMAL_ROUND,
NDS32_RELAX_JUMP_IFC_ROUND,
NDS32_RELAX_EX9_BUILD_ROUND,
NDS32_RELAX_EX9_REPLACE_ROUND
NDS32_RELAX_EX9_REPLACE_ROUND,
NDS32_RELAX_EMPTY_ROUND
};
/* Optimization status mask. */
@ -85,29 +99,23 @@ enum
/* Optimization turn on mask. */
#define NDS32_RELAX_JUMP_IFC_ON (1 << 0)
#define NDS32_RELAX_EX9_ON (1 << 1)
/* The break 0xea defined for ex9 table to keep for trace32 to use 0xeaea. */
#define INSN_BREAK_EA 0x64001d4a
extern void nds32_insertion_sort
(void *, size_t, size_t, int (*) (const void *, const void *));
extern int nds32_elf_ex9_init (void);
extern void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *);
extern void nds32_elf_ex9_finish (struct bfd_link_info *);
extern bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *);
extern void nds32_elf_ex9_import_table (struct bfd_link_info *);
extern bfd_boolean nds32_elf_ifc_reloc (void);
extern bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *);
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);
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);
#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)
/* Hash table structure for target nds32. There are some members to
save target options passed from nds32elf.em to bfd. */

View File

@ -1797,6 +1797,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_NDS32_15_FIXED",
"BFD_RELOC_NDS32_17_FIXED",
"BFD_RELOC_NDS32_25_FIXED",
"BFD_RELOC_NDS32_LONGCALL4",
"BFD_RELOC_NDS32_LONGCALL5",
"BFD_RELOC_NDS32_LONGCALL6",
"BFD_RELOC_NDS32_LONGJUMP4",
"BFD_RELOC_NDS32_LONGJUMP5",
"BFD_RELOC_NDS32_LONGJUMP6",
"BFD_RELOC_NDS32_LONGJUMP7",
"BFD_RELOC_NDS32_PLTREL_HI20",
"BFD_RELOC_NDS32_PLTREL_LO12",
"BFD_RELOC_NDS32_PLT_GOTREL_HI20",
@ -1838,11 +1845,25 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_NDS32_DIFF16",
"BFD_RELOC_NDS32_DIFF32",
"BFD_RELOC_NDS32_DIFF_ULEB128",
"BFD_RELOC_NDS32_EMPTY",
"BFD_RELOC_NDS32_25_ABS",
"BFD_RELOC_NDS32_DATA",
"BFD_RELOC_NDS32_TRAN",
"BFD_RELOC_NDS32_17IFC_PCREL",
"BFD_RELOC_NDS32_10IFCU_PCREL",
"BFD_RELOC_NDS32_TPOFF",
"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_V850_9_PCREL",
"BFD_RELOC_V850_22_PCREL",
"BFD_RELOC_V850_SDA_16_16_OFFSET",

View File

@ -4000,6 +4000,20 @@ ENUMX
BFD_RELOC_NDS32_17_FIXED
ENUMX
BFD_RELOC_NDS32_25_FIXED
ENUMX
BFD_RELOC_NDS32_LONGCALL4
ENUMX
BFD_RELOC_NDS32_LONGCALL5
ENUMX
BFD_RELOC_NDS32_LONGCALL6
ENUMX
BFD_RELOC_NDS32_LONGJUMP4
ENUMX
BFD_RELOC_NDS32_LONGJUMP5
ENUMX
BFD_RELOC_NDS32_LONGJUMP6
ENUMX
BFD_RELOC_NDS32_LONGJUMP7
ENUMDOC
for relax
ENUM
@ -4102,8 +4116,14 @@ ENUMX
ENUMX
BFD_RELOC_NDS32_DIFF_ULEB128
ENUMX
BFD_RELOC_NDS32_EMPTY
ENUMDOC
relaxation relative relocation types
ENUM
BFD_RELOC_NDS32_25_ABS
ENUMX
ENUMDOC
This is a 25 bit absolute address.
ENUM
BFD_RELOC_NDS32_DATA
ENUMX
BFD_RELOC_NDS32_TRAN
@ -4112,7 +4132,35 @@ ENUMX
ENUMX
BFD_RELOC_NDS32_10IFCU_PCREL
ENUMDOC
relaxation relative relocation types
For ex9 and ifc using.
ENUM
BFD_RELOC_NDS32_TPOFF
ENUMX
BFD_RELOC_NDS32_TLS_LE_HI20
ENUMX
BFD_RELOC_NDS32_TLS_LE_LO12
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_LO12S2
ENUMX
BFD_RELOC_NDS32_TLS_TPOFF
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
ENUMDOC
For TLS.
ENUM

View File

@ -1,3 +1,20 @@
2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
* config/tc-nds32.c (nds32_fsrs, nds32_fdrs, nds32_gprs): Remove.
(relax_table): Add new relaxation pattern.
(do_pseudo_la_internal, do_pseudo_ls_bhw): Expand for PIC suffix.
(do_pseudo_move, do_pseudo_neg, do_pseudo_pushpopm): Fix.
(get_range_type, nds32_elf_record_fixup_exp, nds32_get_align,
nds32_elf_build_relax_relation, md_assemble, invalid_prev_frag,
nds32_relax_frag, md_estimate_size_before_relax): Adjust relaxation.
(relocation_table): Remove.
(relax_ls_table): Load-store relaxation pattern.
(hint_map): Define-use chain pattern.
(nds32_find_reloc_table, nds32_match_hint_insn): Analysis
relaxation pattern.
(nds32_parse_name): Parse PIC suffix.
* config/tc-nds32.h: Declare.
2014-09-15 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (OPTION_omit_lock_prefix): Renamed to ...

File diff suppressed because it is too large Load Diff

View File

@ -42,10 +42,6 @@
#define TARGET_BYTES_BIG_ENDIAN 1
#endif
/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
symbols. The relocation type is stored in X_md. */
#define O_PIC_reloc O_md1
/* as.c. */
/* Extend GAS command line option handling capability. */
extern int nds32_parse_option (int, char *);
@ -154,6 +150,12 @@ extern void nds32_do_align (int);
#define LOCAL_LABELS_FB 1 /* Permit temporary numeric labels. */
/* frags.c. */
#define NDS32_FRAG_RELAXABLE 0x1
#define NDS32_FRAG_RELAXED 0x2
#define NDS32_FRAG_BRANCH 0x4
#define NDS32_FRAG_LABEL 0x8
struct nds32_frag_type
{
relax_substateT flag;
@ -211,10 +213,16 @@ enum nds32_br_range
enum nds32_ramp
{
NDS32_CREATE_LABLE = 1,
NDS32_RELAX = 2,
NDS32_ORIGIN = 4,
NDS32_CONVERT = 8
NDS32_CREATE_LABEL = 1,
NDS32_RELAX = (1 << 1), /* Obsolete in the future. */
NDS32_ORIGIN = (1 << 2),
NDS32_INSN16 = (1 << 3),
NDS32_PTR = (1 << 4),
NDS32_ABS = (1 << 5),
NDS32_HINT = (1 << 6),
NDS32_FIX = (1 << 7),
NDS32_ADDEND = (1 << 8),
NDS32_SYM = (1 << 9)
};
typedef struct nds32_relax_fixup_info
@ -231,13 +239,15 @@ typedef struct nds32_cond_field
int offset;
int bitpos; /* Register position. */
int bitmask; /* Number of register bits. */
bfd_boolean signed_extend;
} nds32_cond_field_t;
/* The max relaxation pattern is 20-bytes including the nop. */
#define NDS32_MAXCHAR 20
/* In current, the max entend number of instruction for one pseudo instruction
is 4, but its number of relocation may be 5. */
#define MAX_RELAX_NUM 8
is 4, but its number of relocation may be 12. */
#define MAX_RELAX_NUM 4
#define MAX_RELAX_FIX 12
typedef struct nds32_relax_info
{
@ -248,17 +258,24 @@ typedef struct nds32_relax_info
/* Code sequences for different branch range. */
uint32_t relax_code_seq[BR_RANGE_NUM][MAX_RELAX_NUM];
nds32_cond_field_t relax_code_condition[BR_RANGE_NUM][MAX_RELAX_NUM];
int relax_code_size[BR_RANGE_NUM];
unsigned int relax_code_size[BR_RANGE_NUM];
int relax_branch_isize[BR_RANGE_NUM];
nds32_relax_fixup_info_t relax_fixup[BR_RANGE_NUM][MAX_RELAX_NUM];
nds32_relax_fixup_info_t relax_fixup[BR_RANGE_NUM][MAX_RELAX_FIX];
} relax_info_t;
/* Relocation table. */
struct nds32_relocation_map
enum nds32_relax_hint_type
{
unsigned int main_type;
/* Number of instructions, {relocations type, instruction type}. */
unsigned int reloc_insn[6][6][3];
NDS32_RELAX_HINT_NONE = 0,
NDS32_RELAX_HINT_LA,
NDS32_RELAX_HINT_LS
};
struct nds32_relax_hint_table
{
enum nds32_relax_hint_type main_type;
unsigned int relax_code_size;
uint32_t relax_code_seq[MAX_RELAX_NUM];
nds32_relax_fixup_info_t relax_fixup[MAX_RELAX_FIX];
};
#endif /* TC_NDS32 */

View File

@ -1,3 +1,7 @@
2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
* nds32.h: Declare new relocations.
2014-09-15 Andrew Bennett <andrew.bennett@imgtec.com>
Matthew Fortune <matthew.fortune@imgtec.com>

View File

@ -76,7 +76,6 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
RELOC_NUMBER (R_NDS32_GOTOFF, 43)
RELOC_NUMBER (R_NDS32_GOTPC20, 44)
RELOC_NUMBER (R_NDS32_GOT_HI20, 45)
RELOC_NUMBER (R_NDS32_GOT_LO12, 46)
RELOC_NUMBER (R_NDS32_GOTPC_HI20, 47)
RELOC_NUMBER (R_NDS32_GOTPC_LO12, 48)
@ -95,8 +94,8 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
RELOC_NUMBER (R_NDS32_15_FIXED_RELA, 61)
RELOC_NUMBER (R_NDS32_17_FIXED_RELA, 62)
RELOC_NUMBER (R_NDS32_25_FIXED_RELA, 63)
RELOC_NUMBER (R_NDS32_PLTREL_HI20, 64)
RELOC_NUMBER (R_NDS32_PLTREL_LO12, 65)
RELOC_NUMBER (R_NDS32_PLTREL_HI20, 64) /* This is obsoleted. */
RELOC_NUMBER (R_NDS32_PLTREL_LO12, 65) /* This is obsoleted. */
RELOC_NUMBER (R_NDS32_PLT_GOTREL_HI20, 66)
RELOC_NUMBER (R_NDS32_PLT_GOTREL_LO12, 67)
RELOC_NUMBER (R_NDS32_SDA12S2_DP_RELA, 68)
@ -123,22 +122,38 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type)
RELOC_NUMBER (R_NDS32_GOT15S2_RELA, 89)
RELOC_NUMBER (R_NDS32_GOT17S2_RELA, 90)
RELOC_NUMBER (R_NDS32_5_RELA, 91)
RELOC_NUMBER (R_NDS32_10_UPCREL_RELA, 92)
RELOC_NUMBER (R_NDS32_10_UPCREL_RELA, 92) /* This is obsoleted. */
RELOC_NUMBER (R_NDS32_SDA_FP7U2_RELA, 93)
RELOC_NUMBER (R_NDS32_WORD_9_PCREL_RELA, 94)
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)
RELOC_NUMBER (R_NDS32_LONGJUMP4, 110)
RELOC_NUMBER (R_NDS32_LONGJUMP5, 111)
RELOC_NUMBER (R_NDS32_LONGJUMP6, 112)
RELOC_NUMBER (R_NDS32_LONGJUMP7, 113)
RELOC_NUMBER (R_NDS32_RELAX_ENTRY, 192)
RELOC_NUMBER (R_NDS32_GOT_SUFF, 193)
RELOC_NUMBER (R_NDS32_GOTOFF_SUFF, 194)
RELOC_NUMBER (R_NDS32_PLT_GOT_SUFF, 195)
RELOC_NUMBER (R_NDS32_MULCALL_SUFF, 196)
RELOC_NUMBER (R_NDS32_MULCALL_SUFF, 196) /* This is obsoleted. */
RELOC_NUMBER (R_NDS32_PTR, 197)
RELOC_NUMBER (R_NDS32_PTR_COUNT, 198)
RELOC_NUMBER (R_NDS32_PTR_RESOLVED, 199)
RELOC_NUMBER (R_NDS32_PLTBLOCK, 200)
RELOC_NUMBER (R_NDS32_PLTBLOCK, 200) /* This is obsoleted. */
RELOC_NUMBER (R_NDS32_RELAX_REGION_BEGIN, 201)
RELOC_NUMBER (R_NDS32_RELAX_REGION_END, 202)
RELOC_NUMBER (R_NDS32_MINUEND, 203)
@ -149,7 +164,9 @@ 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_FPBASE, 211)
RELOC_NUMBER (R_NDS32_TLS_LE_ADD, 211)
RELOC_NUMBER (R_NDS32_TLS_LE_LS, 212)
RELOC_NUMBER (R_NDS32_EMPTY, 213)
END_RELOC_NUMBERS (R_NDS32_max)

View File

@ -1,3 +1,10 @@
2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
* emultempl/nds32elf.em (nds32_elf_after_open): Do not keep
ex9 234th entry.
(nds32_elf_after_allocation): Move all optimizations into
nds32_elf_relax_section.
2014-09-15 Andrew Bennett <andrew.bennett@imgtec.com>
Matthew Fortune <matthew.fortune@imgtec.com>

View File

@ -52,7 +52,8 @@ nds32_elf_create_output_section_statements (void)
if (strstr (bfd_get_target (link_info.output_bfd), "nds32") == NULL)
{
/* Check the output target is nds32. */
einfo ("%F%X%P: error: Cannot change output format whilst linking NDS32 binaries.\n");
einfo ("%F%X%P: error: Cannot change output format whilst "
"linking NDS32 binaries.\n");
return;
}
@ -124,8 +125,9 @@ nds32_elf_after_open (void)
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 (!link_info.relocatable && abfd->link.next == NULL)
if (abfd->link_next == NULL && (target_optimize & NDS32_RELAX_EX9_ON))
{
asection *itable;
struct bfd_link_hash_entry *h;
@ -137,17 +139,8 @@ nds32_elf_after_open (void)
{
itable->gc_mark = 1;
itable->alignment_power = 2;
if ((target_optimize & NDS32_RELAX_EX9_ON))
{
itable->size = 0x1000;
itable->contents = bfd_zalloc (abfd, itable->size);
}
else
{
itable->size = 0x4;
itable->contents = bfd_zalloc (abfd, itable->size);
bfd_putb32 (INSN_BREAK_EA,itable->contents);
}
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_",
@ -158,6 +151,7 @@ nds32_elf_after_open (void)
get_elf_backend_data (link_info.output_bfd)->collect, &h);
}
}
#endif
}
/* Check object files if the target is dynamic linked executable
@ -173,12 +167,14 @@ nds32_elf_after_open (void)
if (link_info.shared || link_info.pie)
{
/* 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);
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;
}
@ -192,108 +188,22 @@ nds32_elf_after_open (void)
gld${EMULATION_NAME}_after_open ();
}
static void nds32_elf_relax_stub (bfd_boolean relax)
{
/* Re-caculate memory map address. */
lang_do_assignments (lang_assigning_phase_enum);
lang_reset_memory_regions ();
one_lang_size_sections_pass (&relax, FALSE);
}
static void
nds32_elf_after_allocation (void)
{
struct elf_nds32_link_hash_table *table;
table = nds32_elf_hash_table (&link_info);
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;
}
/* 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 ();
if (!table)
return;
/* Use IFC */
if ((target_optimize & NDS32_RELAX_JUMP_IFC_ON)
&& !(table->relax_status & NDS32_RELAX_JUMP_IFC_DONE))
{
table->relax_round = NDS32_RELAX_JUMP_IFC_ROUND;
/* Traverse all sections to build j and jal list. */
nds32_elf_relax_stub (TRUE);
/* Replace with ifc. */
if (!nds32_elf_ifc_finish (&link_info))
einfo (_("%F: Please report this bug. IFC error.\n"));
table->relax_round = NDS32_RELAX_NONE_ROUND;
/* Adjust address after ifcall. */
nds32_elf_relax_stub (FALSE);
if (!nds32_elf_ifc_reloc ())
einfo (_("%F: Please report this bug. IFC error.\n"));
}
/* EX9 Instruction Table Relaxation. */
if (!link_info.relocatable && !nds32_elf_ex9_itb_base (&link_info))
einfo (_("%F: Please report this bug. Ex9 relocation error.\n"));
/* Generate ex9 table. */
if ((target_optimize & NDS32_RELAX_EX9_ON)
&& !(table->relax_status & NDS32_RELAX_EX9_DONE))
{
/* Ex9 entry point. */
table->relax_round = NDS32_RELAX_EX9_BUILD_ROUND;
/* Initialize ex9 hash table. */
if (!nds32_elf_ex9_init ())
return;
/* Build ex9 instruction table. */
nds32_elf_relax_stub (TRUE);
nds32_elf_ex9_finish (&link_info);
/* Replace with ex9.it. */
nds32_elf_relax_stub (TRUE);
table->relax_round = NDS32_RELAX_NONE_ROUND;
/* Do ifc again. */
if (target_optimize & NDS32_RELAX_JUMP_IFC_ON)
if (!nds32_elf_ifc_finish (&link_info))
einfo (_("%F: Please report this bug. IFC error.\n"));
/* Re-caculate memory map address. */
lang_do_assignments (lang_assigning_phase_enum);
/* Relocation for .ex9.itable. */
nds32_elf_ex9_reloc_jmp (&link_info);
}
else if (ex9_import_file != NULL
&& !(table->relax_status = NDS32_RELAX_EX9_DONE))
{
/* Import ex9 table. */
if (update_ex9_table == 1)
{
/* Build ex9 table. */
table->relax_round = NDS32_RELAX_EX9_BUILD_ROUND;
/* Initialize ex9 hash table. */
if (!nds32_elf_ex9_init ())
return;
/* Build ex9 table. */
nds32_elf_relax_stub (TRUE);
/* Relocation for .ex9.itable. */
lang_do_assignments (lang_assigning_phase_enum);
nds32_elf_ex9_reloc_jmp (&link_info);
}
nds32_elf_ex9_import_table (&link_info);
/* Replace with ex9.it. */
table->relax_round = NDS32_RELAX_EX9_REPLACE_ROUND;
table->relax_status |= NDS32_RELAX_EX9_DONE;
nds32_elf_relax_stub (TRUE);
}
}
EOF
@ -332,7 +242,7 @@ PARSE_AND_LIST_PROLOGUE='
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},
{ "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
{ "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
/* 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},
@ -399,7 +309,7 @@ PARSE_AND_LIST_ARGS_CASES='
break;
case OPTION_EXPORT_SYMBOLS:
if (!optarg)
einfo (_("Missing file for --mgen-symbol-ld-script.\n"), optarg);
einfo (_("Missing file for --mexport-symbols.\n"), optarg);
if(strcmp (optarg, "-") == 0)
sym_ld_script = stdout;
@ -425,7 +335,7 @@ PARSE_AND_LIST_ARGS_CASES='
ex9_export_file = stdout;
else
{
ex9_export_file = fopen (optarg, FOPEN_WT);
ex9_export_file = fopen (optarg, "wb");
if(ex9_export_file == NULL)
einfo (_("ERROR %P%F: cannot open ex9 export file %s.\n"), optarg);
}
@ -434,7 +344,7 @@ PARSE_AND_LIST_ARGS_CASES='
if (!optarg)
einfo (_("Missing file for --mimport-ex9=<file>.\n"));
ex9_import_file = fopen (optarg, "r+");
ex9_import_file = fopen (optarg, "rb+");
if(ex9_import_file == NULL)
einfo (_("ERROR %P%F: cannot open ex9 import file %s.\n"), optarg);
break;