diff options
author | Nick Clifton <nickc@redhat.com> | 2018-09-20 13:27:31 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-09-20 13:32:58 +0100 |
commit | fbaf61ad525eb2818598b699d44df32e46583925 (patch) | |
tree | 72886133a128d6bbd4be1af0804b10119598af3d /gas/config | |
parent | cf93e9c2cf8f8b2566f8fc86e961592b51b5980d (diff) | |
download | gdb-fbaf61ad525eb2818598b699d44df32e46583925.zip gdb-fbaf61ad525eb2818598b699d44df32e46583925.tar.gz gdb-fbaf61ad525eb2818598b699d44df32e46583925.tar.bz2 |
Andes Technology has good news for you, we plan to update the nds32 port of binutils on upstream!
We have not only removed all unsupported and obsolete code, but also supported lost of new features,
including better link-time relaxations and TLS implementations. Besides, the files generated by the
newly assembler and linker usually get higher performance and more optimized code size.
ld * emultempl/nds32elf.em (hyper_relax): New variable.
(nds32_elf_create_output_section_statements):
the parameters of bfd_elf32_nds32_set_target_option
(PARSE_AND_LIST_PROLOGUE, PARSE_AND_LIST_OPTIONS,
PARSE_AND_LIST_ARGS_CASES): Add new option --mhyper-relax.
* emultempl/nds32elf.em (nds32_elf_after_open): Updated.
* emultempl/nds32elf.em (tls_desc_trampoline): New variable.
* (nds32_elf_create_output_section_statements): Updated.
* (nds32_elf_after_parse): Disable relaxations when PIC is enable.
* (PARSE_AND_LIST_PROLOGUE, PARSE_AND_LIST_OPTIONS,
PARSE_AND_LIST_ARGS_CASES): Add new option --m[no-]tlsdesc-trampoline.
include * elf/nds32.h: Remove the unused target features.
* dis-asm.h (disassemble_init_nds32): Declared.
* elf/nds32.h (E_NDS32_NULL): Removed.
(E_NDS32_HAS_DSP_INST, E_NDS32_HAS_ZOL): New.
* opcode/nds32.h: Ident.
(N32_SUB6, INSN_LW): New macros.
(enum n32_opcodes): Updated.
* elf/nds32.h: Doc fixes.
* elf/nds32.h: Add R_NDS32_LSI.
* elf/nds32.h: Add new relocations for TLS.
gas * config/tc-nds32.c: Remove the unused target features.
(nds32_relax_relocs, md_pseudo_table, nds32_elf_record_fixup_exp,
nds32_set_elf_flags_by_insn, nds32_insert_relax_entry,
nds32_apply_fix): Likewise.
(nds32_no_ex9_begin): Removed.
* config/tc-nds32.c (add_mapping_symbol_for_align,
make_mapping_symbol, add_mapping_symbol): New functions.
* config/tc-nds32.h (enum mstate): New.
(nds32_segment_info_type): Likewise.
* configure.ac (--enable-dsp-ext, --enable-zol-ext): New options.
* config.in: Regenerated.
* configure: Regenerated.
* config/tc-nds32.c (nds32_dx_regs):
Set the value according to the configuration.
(nds32_perf_ext, nds32_perf_ext2, nds32_string_ext, nds32_audio_ext):
Likewise.
(nds32_dsp_ext): New variable. Set the value according to the
configuration.
(nds32_zol_ext): Likewise.
(asm_desc, nds32_pseudo_opcode_table): Make them static.
(nds32_set_elf_flags_by_insn): Updated.
(nds32_check_insn_available): Updated.
(nds32_str_tolower): New function.
* config/tc-nds32.c (relax_table): Updated.
(md_begin): Updated.
(md_assemble): Use XNEW macro to allocate space for `insn.info',
and then remember to free it.
(md_section_align): Cast (-1) to ValueT.
(nds32_get_align): Cast (~0U) to addressT.
(nds32_relax_branch_instructions): Updated.
(md_convert_frag): Add new local variable `final_r_type'.
(invalid_prev_frag): Add new bfd_boolean parameter `relax'.
All callers changed.
* config/tc-nds32.c (struct nds32_relocs_pattern): Add `insn' field.
(struct nds32_hint_map): Add `option_list' field.
(struct suffix_name, suffix_table): Remove the unused `pic' field.
(do_pseudo_b, do_pseudo_bal): Remove the suffix checking.
(do_pseudo_la_internal, do_pseudo_pushpopm): Indent.
(relax_hint_bias, relax_hint_id_current): New static variables.
(reset_bias, relax_hint_begin): New variables.
(nds_itoa): New function.
(CLEAN_REG, GET_OPCODE): New macros.
(struct relax_hint_id): New.
(nds32_relax_hint): For .relax_hint directive, we can use `begin'
and `end' to mark the relax pattern without giving exactly id number.
(nds32_elf_append_relax_relocs): Handle the case that the .relax_hint
directives are attached to pseudo instruction.
(nds32_elf_save_pseudo_pattern): Change the second parameter from
instruction's opcode to byte code.
(nds32_elf_build_relax_relation): Add new bfd_boolean parameter
`pseudo_hint'.
(nds32_lookup_pseudo_opcode): Fix the overflow issue.
(enum nds32_insn_type): Add N32_RELAX_ALU1 and N32_RELAX_16BIT.
(nds32_elf_record_fixup_exp, relax_ls_table, hint_map,
nds32_find_reloc_table, nds32_match_hint_insn, nds32_parse_name):
Updated.
* config/tc-nds32.h (MAX_RELAX_NUM): Extend it to 6.
(enum nds32_relax_hint_type): Merge NDS32_RELAX_HINT_LA and
NDS32_RELAX_HINT_LS into NDS32_RELAX_HINT_LALS. Add
NDS32_RELAX_HINT_LA_PLT, NDS32_RELAX_HINT_LA_GOT and
NDS32_RELAX_HINT_LA_GOTOFF.
* config/tc-nds32.h (relax_ls_table): Add floating load/store
to gp relax pattern.
(hint_map, nds32_find_reloc_table): Likewise.
* configure.ac: Define NDS32_LINUX_TOOLCHAIN.
* configure: Regenerated.
* config.in: Regenerated.
* config/tc-nds32.h (enum nds32_ramp): Updated.
(enum nds32_relax_hint_type): Likewise.
* config/tc-nds32.c: Include "errno.h" and "limits.h".
(relax_ls_table): Add TLS relax patterns.
(nds32_elf_append_relax_relocs): Attach BFD_RELOC_NDS32_GROUP on
each instructions of TLS patterns.
(nds32_elf_record_fixup_exp): Updated.
(nds32_apply_fix): Likewise.
(suffix_table): Add TLSDESC suffix.
binutils* testsuite/binutils-all/objcopy.exp: Set the unsupported reloc number
from 215 to 255 for NDS32.
bfd * elf32-nds32.c (nds32_elf_relax_loadstore):
Remove the unused target features.
(bfd_elf32_nds32_set_target_option): Remove the unused parameters.
(nds32_elf_relax_piclo12, nds32_elf_relax_letlslo12,
nds32_elf_relax_letlsadd, nds32_elf_relax_letlsls,
nds32_elf_relax_pltgot_suff, nds32_elf_relax_got_suff
nds32_elf_relax_gotoff_suff, calculate_plt_memory_address,
calculate_plt_offset, calculate_got_memory_address,
nds32_elf_check_dup_relocs): Removed.
All callers changed.
* elf32-nds32.h: Remove the unused macros and defines.
(elf_nds32_link_hash_table): Remove the unused variable.
(bfd_elf32_nds32_set_target_option): Update prototype.
(nds32_elf_ex9_init): Removed.
* elf32-nds32.c (nds32_convert_32_to_16): Updated.
* elf32-nds32.c (HOWTO2, HOWTO3): Define new HOWTO macros
to initialize array nds32_elf_howto_table in any order
without lots of EMPTY_HOWTO.
(nds32_reloc_map): Updated.
* reloc.c: Add BFD_RELOC_NDS32_LSI.
* bfd-in2.h: Regenerated.
* bfd/libbfd.h: Regenerated.
* elf32-nds32.c (nds32_elf_relax_howto_table): Add R_NDS32_LSI.
(nds32_reloc_map): Likewise.
(nds32_elf_relax_flsi): New function.
(nds32_elf_relax_section): Support floating load/store relaxation.
* elf32-nds32.c (NDS32_GUARD_SEC_P, elf32_nds32_local_gp_offset):
New macro.
(struct elf_nds32_link_hash_entry): New `offset_to_gp' field.
(struct elf_nds32_obj_tdata): New `offset_to_gp' and `hdr_size' fields.
(elf32_nds32_allocate_local_sym_info, nds32_elf_relax_guard,
nds32_elf_is_target_special_symbol, nds32_elf_maybe_function_sym):
New functions.
(nds32_info_to_howto_rel): Add BFD_ASSERT.
(bfd_elf32_bfd_reloc_type_table_lookup, nds32_elf_link_hash_newfunc,
nds32_elf_link_hash_table_create, nds32_elf_relocate_section,
nds32_elf_relax_loadstore, nds32_elf_relax_lo12, nds32_relax_adjust_label,
bfd_elf32_nds32_set_target_option, nds32_fag_mark_relax): Updated.
(nds32_elf_final_sda_base): Improve it to find the better gp value.
(insert_nds32_elf_blank): Must consider `len' when inserting blanks.
* elf32-nds32.h (bfd_elf32_nds32_set_target_option): Update prototype.
(struct elf_nds32_link_hash_table): Add new variable `hyper_relax'.
* elf32-nds32.c (elf32_nds32_allocate_dynrelocs): New function.
(create_got_section): Likewise.
(allocate_dynrelocs, nds32_elf_size_dynamic_sections,
nds32_elf_relocate_section, nds32_elf_finish_dynamic_symbol): Updated.
(nds32_elf_check_relocs): Fix the issue that the shared library may
has TEXTREL entry in the dynamic section.
(nds32_elf_create_dynamic_sections): Enable to call readonly_dynrelocs
since the TEXTREL issue is fixed in the nds32_elf_check_relocs.
(nds32_elf_finish_dynamic_sections): Update and add DT_RELASZ
dynamic entry.
(calculate_offset): Remove the unused parameter `pic_ext_target' and
related codes.
All callers changed.
(elf_backend_dtrel_excludes_plt): Disable it temporarily since it
will cause some errors for our test cases.
* elf32-nds32.c (nds32_elf_merge_private_bfd_data): Allow to link the
generic object.
* reloc.c: Add TLS relocations.
* libbfd.h: Regenerated.
* bfd-in2.h: Regenerated.
* elf32-nds32.h (struct section_id_list_t): New.
(elf32_nds32_lookup_section_id, elf32_nds32_check_relax_group,
elf32_nds32_unify_relax_group, nds32_elf_unify_tls_model):
New prototypes.
(elf32_nds32_compute_jump_table_size, elf32_nds32_local_tlsdesc_gotent):
New macro.
(nds32_insertion_sort, bfd_elf32_nds32_set_target_option,
elf_nds32_link_hash_table): Updated.
* elf32-nds32.c (enum elf_nds32_tls_type): New.
(struct elf32_nds32_relax_group_t, struct relax_group_list_t): New.
(elf32_nds32_add_dynreloc, patch_tls_desc_to_ie, get_tls_type,
fls, ones32, list_insert, list_insert_sibling, dump_chain,
elf32_nds32_check_relax_group, elf32_nds32_lookup_section_id,
elf32_nds32_unify_relax_group, nds32_elf_unify_tls_model): New functions.
(elf_nds32_obj_tdata): Add new fields.
(elf32_nds32_relax_group_ptr, nds32_elf_local_tlsdesc_gotent): New macros.
(nds32_elf_howto_table): Add TLS relocations.
(nds32_reloc_map): Likewise.
(nds32_elf_copy_indirect_symbol, nds32_elf_size_dynamic_sections,
nds32_elf_finish_dynamic_symbol, elf32_nds32_allocate_local_sym_info,
nds32_elf_relocate_section, bfd_elf32_nds32_set_target_option,
nds32_elf_check_relocs, allocate_dynrelocs): Updated.
(nds32_elf_relax_section): Call nds32_elf_unify_tls_model.
(dtpoff_base): Rename it to `gottpof' and then update it.
opcodes * nds32-asm.c (operand_fields): Remove the unused fields.
(nds32_opcodes): Remove the unused instructions.
* nds32-dis.c (nds32_ex9_info): Removed.
(nds32_parse_opcode): Updated.
(print_insn_nds32): Likewise.
* nds32-asm.c (config.h, stdlib.h, string.h): New includes.
(LEX_SET_FIELD, LEX_GET_FIELD): Update defines.
(nds32_asm_init, build_operand_hash_table, build_keyword_hash_table,
build_opcode_hash_table): New functions.
(nds32_keyword_table, nds32_keyword_count_table, nds32_field_table,
nds32_opcode_table): New.
(hw_ktabs): Declare it to a pointer rather than an array.
(build_hash_table): Removed.
* nds32-asm.h (enum): Add SYN_INPUT, SYN_OUTPUT, SYN_LOPT,
SYN_ROPT and upadte HW_GPR and HW_INT.
* nds32-dis.c (keywords): Remove const.
(match_field): New function.
(nds32_parse_opcode): Updated.
* disassemble.c (disassemble_init_for_target):
Add disassemble_init_nds32.
* nds32-dis.c (eum map_type): New.
(nds32_private_data): Likewise.
(get_mapping_symbol_type, is_mapping_symbol, nds32_symbol_is_valid,
nds32_add_opcode_hash_table, disassemble_init_nds32): New functions.
(print_insn_nds32): Updated.
* nds32-asm.c (parse_aext_reg): Add new parameter.
(parse_re, parse_re2, parse_aext_reg): Only reduced registers
are allowed to use.
All callers changed.
* nds32-asm.c (keyword_usr, keyword_sr): Updated.
(operand_fields): Add new fields.
(nds32_opcodes): Add new instructions.
(keyword_aridxi_mx): New keyword.
* nds32-asm.h (enum): Add NASM_ATTR_DSP_ISAEXT, HW_AEXT_ARIDXI_MX
and NASM_ATTR_ZOL.
(ALU2_1, ALU2_2, ALU2_3): New macros.
* nds32-dis.c (nds32_filter_unknown_insn): Updated.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-nds32.c | 4435 | ||||
-rw-r--r-- | gas/config/tc-nds32.h | 38 |
2 files changed, 2847 insertions, 1626 deletions
diff --git a/gas/config/tc-nds32.c b/gas/config/tc-nds32.c index 01bc17b..24dc390 100644 --- a/gas/config/tc-nds32.c +++ b/gas/config/tc-nds32.c @@ -35,6 +35,8 @@ #include "opcode/nds32.h" #include <stdio.h> +#include <errno.h> +#include <limits.h> /* GAS definitions. */ @@ -66,6 +68,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 +77,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,10 +90,6 @@ 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. */ static int optimize = 0; /* Save option -Os for code size. */ @@ -110,60 +109,78 @@ enum ict_option { }; static enum ict_option ict_flag = ICT_NONE; + static struct hash_control *nds32_relax_info_hash; + +/* Branch patterns. */ static relax_info_t relax_table[] = { { - "jal", /* opcode */ - BR_RANGE_S16M, /* br_range */ - {{0, 0, 0, FALSE}}, /* cond_field */ - { + .opcode = "jal", + .br_range = BR_RANGE_S16M, + .cond_field = { - INSN_JAL /* jal label */ - }, /* BR_RANGE_S256 */ + {0, 0, 0, FALSE} + }, + .relax_code_seq[BR_RANGE_S256] = { - INSN_JAL /* jal label */ - }, /* BR_RANGE_S16K */ + INSN_JAL /* jal label */ + }, + .relax_code_size[BR_RANGE_S256] = 4, + .relax_branch_isize[BR_RANGE_S256] = 4, + .relax_fixup[BR_RANGE_S256] = { - INSN_JAL /* jal label */ - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_JAL /* jal label */ - }, /* BR_RANGE_S16M */ + INSN_JAL /* jal label */ + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - 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} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + 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} - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + 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} - }, /* 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, 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}, @@ -171,169 +188,213 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - INSN_BLTZAL /* bltzal $rt, label */ - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BGEZ, /* bgez $rt, $1 */ - INSN_JAL /* jal label */ - }, /* BR_RANGE_S16M */ + INSN_BGEZAL /* bgezal $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - 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}, + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + INSN_BGEZAL /* bgezal $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[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 */ - { + INSN_BLTZ, /* bltz $rt, $1 */ + INSN_JAL /* jal label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + 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, 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, 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_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, 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 */ + {0, 0, 0, 0} + }, }, { - "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 */ + .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] = { - INSN_BGEZAL /* bgezal $rt, label */ - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BLTZ, /* bltz $rt, $1 */ - INSN_JAL /* jal label */ - }, /* BR_RANGE_S16M */ + INSN_BLTZAL /* bltzal $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - 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}, + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + INSN_BLTZAL /* bltzal $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[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 */ - { + INSN_BGEZ, /* bgez $rt, $1 */ + INSN_JAL /* jal label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + 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, 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, 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_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, 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}, @@ -341,60 +402,74 @@ static relax_info_t relax_table[] = {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 */ - { + .opcode = "j", + .br_range = BR_RANGE_S16M, + .cond_field = { - (INSN_J8 << 16) /* j8 label */ - }, /* BR_RANGE_S256 */ + {0, 0, 0, FALSE} + }, + .relax_code_seq[BR_RANGE_S256] = { - INSN_J /* j label */ - }, /* BR_RANGE_S16K */ + (INSN_J8 << 16) /* j8 label */ + }, + .relax_code_size[BR_RANGE_S256] = 2, + .relax_branch_isize[BR_RANGE_S256] = 2, + .relax_fixup[BR_RANGE_S256] = { - INSN_J /* j label */ - }, /* BR_RANGE_S64K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + INSN_J /* j label */ + }, + . relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + 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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + 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} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16M */ + 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, 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}, @@ -402,60 +477,74 @@ static relax_info_t relax_table[] = {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 */ - { + .opcode = "j8", + .br_range = BR_RANGE_S256, + .cond_field = { - (INSN_J8 << 16) /* j8 label */ - }, /* BR_RANGE_S256 */ + {0, 0, 0, FALSE} + }, + .relax_code_seq[BR_RANGE_S256] = { - INSN_J /* j label */ - }, /* BR_RANGE_S16K */ + (INSN_J8 << 16) /* j8 label */ + }, + .relax_code_size[BR_RANGE_S256] = 2, + .relax_branch_isize[BR_RANGE_S256] = 2, + .relax_fixup[BR_RANGE_S256] = { - INSN_J /* j label */ - }, /* BR_RANGE_S64K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + INSN_J /* j label */ + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - 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, 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, 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} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + 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} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16M */ + 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, 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}, @@ -463,85 +552,113 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - 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, 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] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + INSN_BEQZ /* beqz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {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, 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, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + INSN_BEQZ /* beqz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* 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} - }, /* BR_RANGE_S16M */ + }, + + .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, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + {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}, @@ -551,83 +668,104 @@ static relax_info_t relax_table[] = {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 */ + {0, 0, 0, 0} + }, }, { - "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 */ + .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] = { - 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BGEZ /* bgez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + INSN_BGEZ /* bgez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {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, 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} - }, /* BR_RANGE_S256 */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + INSN_BLTZ, /* bltz $rt, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {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_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}, @@ -637,85 +775,107 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - 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, 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] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BNEZ /* bnez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + INSN_BNEZ /* bnez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {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, 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, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + INSN_BEQZ, /* beqz $rt, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + 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}, @@ -726,82 +886,104 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - INSN_BGTZ /* bgtz $rt, label */ - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BGTZ /* bgtz $rt, label */ - }, /* BR_RANGE_S64K */ + INSN_BGTZ /* bgtz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - INSN_BLEZ, /* blez $rt, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + {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] = { - 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BGTZ /* bgtz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + {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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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} - } /* BR_RANGE_U4G */ - }, /* relax_code_condition */ - {4, 4, 4, 8, 16}, /* relax_code_size */ - {4, 4, 4, 4, 4}, /* relax_branch_isize */ - { + {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_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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_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}, @@ -811,82 +993,104 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - INSN_BLEZ /* blez $rt, label */ - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BLEZ /* blez $rt, label */ - }, /* BR_RANGE_S64K */ + INSN_BLEZ /* blez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - INSN_BGTZ, /* bgtz $rt, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + {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] = { - 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BLEZ /* blez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + {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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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} - } /* BR_RANGE_U4G */ - }, /* relax_code_condition */ - {4, 4, 4, 8, 16}, /* relax_code_size */ - {4, 4, 4, 4, 4}, /* relax_branch_isize */ - { + {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_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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_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}, @@ -896,82 +1100,104 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - INSN_BLTZ /* bltz $rt, label */ - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BLTZ /* bltz $rt, label */ - }, /* BR_RANGE_S64K */ + INSN_BLTZ /* bltz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - INSN_BGEZ, /* bgez $rt, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + {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] = { - 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BLTZ /* bltz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + {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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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} - } /* BR_RANGE_U4G */ - }, /* relax_code_condition */ - {4, 4, 4, 8, 16}, /* relax_code_size */ - {4, 4, 4, 4, 4}, /* relax_branch_isize */ - { + {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_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + 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, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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_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}, @@ -981,97 +1207,118 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - {0, 20, 0x1F, FALSE}, - {0, 15, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + INSN_BEQ /* beq $rt, $ra, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {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} + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - {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, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + INSN_BNE, /* bne $rt, $ra, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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} - }, /* BR_RANGE_S64K */ + {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_ABS, BFD_RELOC_NDS32_EMPTY}, {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16M */ + {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_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}, @@ -1082,96 +1329,118 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - {0, 20, 0x1F, FALSE}, - {0, 15, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + INSN_BNE /* bne $rt, $ra, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {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} + }, + .relax_code_size[BR_RANGE_S16K] = 4, + .relax_branch_isize[BR_RANGE_S16K] = 4, + .relax_fixup[BR_RANGE_S16K] = { - {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, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + INSN_BEQ, /* beq $rt, $ra, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + 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}, @@ -1182,84 +1451,106 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - 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, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - {0, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BEQZ /* beqz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + INSN_BEQZ /* beqz $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {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, 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, 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} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + INSN_BNEZ, /* bnez $rt, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {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, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + {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}, @@ -1270,84 +1561,106 @@ static relax_info_t relax_table[] = {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 */ + .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] = { - 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, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - {0, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + INSN_BNEZ /* bnez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + INSN_BNEZ /* bnez $rt, label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {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, 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, 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} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + INSN_BEQZ, /* beqz $rt, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + 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}, @@ -1358,66 +1671,80 @@ static relax_info_t relax_table[] = {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 = "beqzs8", + .br_range = BR_RANGE_S256, + .cond_field = { - INSN_BEQZS8 << 16 /* beqz $r15, label */ - }, /* BR_RANGE_S256 */ + {0, 0, 0, FALSE} + }, + .relax_code_seq[BR_RANGE_S256] = { - INSN_BEQZ_TA /* bnez $rt, label */ - }, /* BR_RANGE_S16K */ + 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] = { - INSN_BEQZ_TA /* bnez $rt, label */ - }, /* BR_RANGE_S64K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BNEZ_TA, /* bnez $r15, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + 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] = { - 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 */ - { + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + 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} - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + 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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + INSN_BNEZ_TA, /* bnez $r15, $1 */ + INSN_SETHI_TA, /* sethi $ta, label */ + INSN_ORI_TA, /* ori $ta, $ta, label */ + INSN_JR_TA /* jr $ta */ + }, + .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}, @@ -1427,67 +1754,81 @@ static relax_info_t relax_table[] = {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 */ + {0, 0, 0, 0} + }, }, { - "bnezs8", /* opcode */ - BR_RANGE_S256, /* br_range */ - {{0, 0, 0, FALSE}}, /* cond_field */ - { + .opcode = "bnezs8", + .br_range = BR_RANGE_S256, + .cond_field = { - INSN_BNEZS8 << 16 /* bnez $r15, label */ - }, /* BR_RANGE_S256 */ + {0, 0, 0, FALSE} + }, + .relax_code_seq[BR_RANGE_S256] = { - INSN_BNEZ_TA /* bnez $r15, label */ - }, /* BR_RANGE_S16K */ + 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] = { - INSN_BNEZ_TA /* bnez $r15, label */ - }, /* BR_RANGE_S64K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - INSN_BEQZ_TA, /* beqz $r15, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + 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] = { - 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 */ - { + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + 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} - }, /* BR_RANGE_S16K */ + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S64K */ + 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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + INSN_BEQZ_TA, /* beqz $r15, $1 */ + INSN_SETHI_TA, /* sethi $ta, label */ + INSN_ORI_TA, /* ori $ta, $ta, label */ + INSN_JR_TA /* jr $ta */ + }, + .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}, @@ -1498,89 +1839,111 @@ static relax_info_t relax_table[] = {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 */ - { - {0, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* cond_field */ - { - { - 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 = "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, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ - { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + INSN_BNE_R5 /* bne $rt, $r5, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + {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, 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 */ - { + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + INSN_BEQ_R5, /* beq $rt, $r5, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {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 $ta */ + }, + .relax_code_condition[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + {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}, @@ -1591,89 +1954,111 @@ static relax_info_t relax_table[] = {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 */ - { - {0, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* cond_field */ - { - { - 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 */ - { - { - {0, 8, 0x7, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S256 */ + .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, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S64K */ + INSN_BEQ_R5 /* beq $rt, $r5, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16M */ + {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, 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 */ - { + {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + INSN_BNE_R5, /* bne $rt, $r5, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S64K] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S16K */ + {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} - }, /* BR_RANGE_S64K */ + {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} - }, /* BR_RANGE_S16M */ + {0, 0, 0, 0} + }, + + .relax_code_seq[BR_RANGE_U4G] = { - {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, + 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 */ + }, + .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}, @@ -1684,191 +2069,238 @@ static relax_info_t relax_table[] = {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 */ - { - {0, 8, 0x7FF, TRUE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* cond_field */ - { - { - 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 */ + .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_BNEC, /* bnec $rt, imm11s, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S64K */ + INSN_MOVI_TA, /* movi $ta, imm11s */ + INSN_BEQ_TA /* beq $rt, $ta, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - INSN_BNEC, /* bnec $rt, imm11s, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + {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] = { - 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 */ - { - { - {0, 8, 0x7FF, TRUE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 0, 0xFFFFF, FALSE}, - {4, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + 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} - }, /* 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, 8, 0x7FF, FALSE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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_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 */ - { + INSN_BNEC, /* bnec $rt, imm11s, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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_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}, + {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 $ta */ + }, + .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} - } /* BR_RANGE_U4G */ - } /* relax_fixup */ + {0, 0, 0, 0} + }, }, { - "bnec", /* opcode */ - BR_RANGE_S256, /* br_range */ - { - {0, 8, 0x7FF, TRUE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* cond_field */ - { - { - 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 */ + .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_BEQC, /* beqc $rt, imm11s, $1 */ - INSN_J /* j label */ - }, /* BR_RANGE_S16M */ + INSN_MOVI_TA, /* movi $ta, imm11s */ + INSN_BNE_TA /* bne $rt, $ta, label */ + }, + .relax_code_condition[BR_RANGE_S16K] = { - 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 */ - { + {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, 8, 0x7FF, TRUE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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} + }, + + .relax_code_seq[BR_RANGE_S64K] = { - {0, 0, 0xFFFFF, FALSE}, - {4, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* BR_RANGE_S16K */ + 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} - }, /* 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, 8, 0x7FF, FALSE}, - {0, 20, 0x1F, FALSE}, - {0, 0, 0, FALSE} - }, /* 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_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 */ - { + INSN_BEQC, /* beqc $rt, imm11s, $1 */ + INSN_J /* j label */ + }, + .relax_code_condition[BR_RANGE_S16M] = { - {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, - {0, 0, 0, 0} - }, /* BR_RANGE_S256 */ + {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_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}, + {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 $ta */ + }, + .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} - } /* BR_RANGE_U4G */ - } /* relax_fixup */ - } + {0, 0, 0, 0} + }, + }, + { + .opcode = NULL, + }, }; + /* GAS definitions for command-line options. */ enum options { @@ -1935,6 +2367,9 @@ static int nds32_parse_arch (const char *str); 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 [] = { @@ -1959,11 +2394,13 @@ static struct nds32_parse_option_table parse_opts [] = 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; @@ -1994,6 +2431,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} }; @@ -2007,7 +2446,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 () @@ -2196,7 +2635,7 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], 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); @@ -2217,12 +2656,11 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], 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 @@ -2336,7 +2774,7 @@ 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); @@ -2690,11 +3128,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 @@ -2898,7 +3336,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}, @@ -2974,8 +3412,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 }, @@ -3015,22 +3453,23 @@ nds32_init_nds32_pseudo_opcodes (void) static struct nds32_pseudo_opcode * nds32_lookup_pseudo_opcode (const char *str) { + struct nds32_pseudo_opcode *result; int i = 0; - /* Assume pseudo-opcode are less than 16-char in length. */ - char op[16] = {0}; - for (i = 0; i < (int)ARRAY_SIZE (op); i++) + /* (*op) is the first word of current source line (*str) */ + int maxlen = strlen (str); + char *op = xmalloc (maxlen + 1); + + 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); + result = hash_find (nds32_pseudo_opcode_hash, op); + free (op); + return result; } static void @@ -3205,6 +3644,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; } @@ -3418,6 +3861,21 @@ 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 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, LBYTE: .byte 0x12 @@ -3451,7 +3909,10 @@ nds32_adjust_label (int n) 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); @@ -3517,15 +3978,69 @@ 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; @@ -3585,7 +4100,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)) @@ -3602,14 +4117,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; @@ -3659,31 +4166,6 @@ 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) -{ - 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; - 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; - fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0, - BFD_RELOC_NDS32_RELAX_REGION_END); - } -} - static void nds32_loop_begin (int mode) { @@ -3713,16 +4195,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)) @@ -3731,12 +4246,57 @@ 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); + memset (relocs, 0, sizeof (struct nds32_relocs_pattern)); hash_insert (nds32_hint_hash, name, relocs); } else @@ -3745,6 +4305,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) relocs=relocs->next; relocs->next = XNEW (struct nds32_relocs_pattern); relocs = relocs->next; + memset (relocs, 0, sizeof (struct nds32_relocs_pattern)); } relocs->next = NULL; @@ -3757,6 +4318,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) instructions relative to the same instruction. It to connect to next instruction after md_assemble. */ new = XNEW (struct nds32_relocs_group); + memset (new, 0, sizeof (struct nds32_relocs_group)); new->pattern = relocs; new->next = NULL; group = nds32_relax_hint_current; @@ -3840,6 +4402,7 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED) *input_line_pointer = saved_char; ignore_rest_of_line (); } + static void ict_model (int ignore ATTRIBUTE_UNUSED) { @@ -3940,8 +4503,6 @@ 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}, @@ -3964,6 +4525,7 @@ 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. */ @@ -4050,13 +4612,16 @@ 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. */ nds32_gprs_hash = hash_new (); @@ -4065,9 +4630,8 @@ md_begin (void) /* 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 (); @@ -4185,11 +4749,12 @@ 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->seg = now_seg; @@ -4199,6 +4764,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; } @@ -4240,10 +4806,18 @@ 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; - default: /* No suffix. */ - reloc = BFD_RELOC_NDS32_HI20; + default: /* No suffix */ + 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, @@ -4275,8 +4849,19 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */ reloc = BFD_RELOC_NDS32_TLS_LE_LO12; break; - default: /* No suffix. */ - reloc = BFD_RELOC_NDS32_LO12S0; + 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; + default: /* No suffix */ + 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; } } @@ -4288,9 +4873,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, 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; - default: /* No suffix. */ + default: /* No suffix */ reloc = BFD_RELOC_NDS32_LO12S2; break; } @@ -4298,7 +4883,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); @@ -4357,20 +4942,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); @@ -4382,8 +4953,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; @@ -4393,10 +4965,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; @@ -4414,7 +5008,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); @@ -4430,40 +5024,199 @@ 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 */ + /* 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} + } + }, + { + .main_type = 0, + .relax_code_seq = {0}, + .relax_fixup = {{0, 0 , 0, 0}} } }; @@ -4524,122 +5277,190 @@ nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern) /* The args means: instruction size, the 1st instruction is converted to 16 or not, optimize option, 16 bit instruction is enable. */ + #define SET_ADDEND(size, convertible, optimize, insn16_on) \ (((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_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_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. */ @@ -4654,97 +5475,199 @@ 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, + }, + /* last one */ + {0, NULL, 0, 0 ,0, 0} }; /* Find the relaxation pattern according to instructions. */ @@ -4786,6 +5709,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; @@ -4807,6 +5733,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: @@ -4829,18 +5757,20 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, } else { - /* 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++) + /* 2 byte instruction. Compare by opcode name because + the opcode of 2byte instruction is not regular. */ + 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; } @@ -4848,23 +5778,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->frag->fr_line); return FALSE; } @@ -4923,12 +5865,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; @@ -4944,22 +5888,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; } @@ -4967,8 +5912,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; } @@ -4976,7 +5941,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; @@ -4989,7 +5954,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; @@ -5010,6 +5975,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; @@ -5026,15 +5992,37 @@ 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) { + if (count >= relax_code_size / 4) + count = 0; + /* Choose the match fixup 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)); @@ -5043,8 +6031,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)); @@ -5140,7 +6131,109 @@ 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 { @@ -5157,6 +6250,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; @@ -5167,6 +6273,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 @@ -5174,6 +6293,29 @@ 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 = xmalloc (strlen (str) + 1); + nds32_str_tolower (str, s); + if (verbatim + && (((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; + } + free (s); + + 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; @@ -5209,16 +6351,16 @@ void md_assemble (char *str) { struct nds32_asm_insn insn; - expressionS insn_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 @@ -5227,11 +6369,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) @@ -5245,7 +6399,7 @@ md_assemble (char *str) } label_exist = 0; - insn.info = &insn_expr; + insn.info = XNEW (expressionS); asm_desc.result = NASM_OK; nds32_assemble (&asm_desc, &insn, str); @@ -5282,11 +6436,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)) @@ -5304,8 +6460,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, @@ -5321,6 +6477,8 @@ md_assemble (char *str) else if (insn.opcode->isize == 2) bfd_putb16 (insn.insn, out); fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH; + + free (insn.info); return; /* md_convert_frag will insert relocations. */ } @@ -5331,7 +6489,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) { @@ -5361,6 +6519,8 @@ md_assemble (char *str) bfd_putb16 (insn_16, out); else if (insn.opcode->isize == 2) bfd_putb16 (insn.insn, out); + + free (insn.info); return; } else if ((verbatim || !relaxing) && optimize && label) @@ -5390,18 +6550,21 @@ 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); + + free (insn.info); } /* md_macro_start */ @@ -5449,7 +6612,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 @@ -5552,7 +6715,6 @@ nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn, } } - static int nds32_relax_branch_instructions (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED, @@ -5581,15 +6743,36 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP, 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); @@ -5598,15 +6781,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]; @@ -5639,7 +6828,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; } } @@ -5678,19 +6867,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) @@ -5758,7 +6947,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); @@ -5795,7 +6984,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) 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); @@ -5845,6 +7034,7 @@ 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; + enum bfd_reloc_code_real final_r_type; /* Replace with gas_assert (branch_symbol != NULL); */ if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)) @@ -6025,9 +7215,10 @@ 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; 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; } } @@ -6251,12 +7442,12 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, seginfo = seg_info (sec); 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 && ict_flag == ICT_NONE) + + if (!fixp && !verbatim && ict_flag == ICT_NONE) return; subseg_change (sec, 0); @@ -6264,7 +7455,7 @@ 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; @@ -6273,10 +7464,6 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, /* These flags are only enabled when global relax is enabled. Maybe we can check DISABLE_RELAX_FLAG at link-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_flag == ICT_SMALL) @@ -6515,12 +7702,12 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 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. */ + Tag tls data for linker. */ switch (fixP->fx_r_type) { case BFD_RELOC_NDS32_DATA: - if (!enable_relax_ex9) - fixP->fx_done = 1; + /* This reloc is obselete, we do not need it so far. */ + fixP->fx_done = 1; break; case BFD_RELOC_NDS32_TPOFF: case BFD_RELOC_NDS32_TLS_LE_HI20: @@ -6530,6 +7717,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: @@ -6712,13 +7905,14 @@ 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}, }; /* Implement md_parse_name. */ @@ -6739,7 +7933,7 @@ nds32_parse_name (char const *name, expressionS *exprP, /* Check the special 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 != '@') @@ -6753,13 +7947,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; @@ -6769,6 +7961,7 @@ nds32_parse_name (char const *name, expressionS *exprP, } } } + return 1; } diff --git a/gas/config/tc-nds32.h b/gas/config/tc-nds32.h index 178ca4e..150fbda 100644 --- a/gas/config/tc-nds32.h +++ b/gas/config/tc-nds32.h @@ -24,6 +24,21 @@ #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") @@ -231,7 +246,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 @@ -254,8 +273,8 @@ typedef struct nds32_cond_field /* The max relaxation pattern is 20-bytes including the nop. */ #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 + is 6, but its number of relocation may be 12. */ +#define MAX_RELAX_NUM 6 #define MAX_RELAX_FIX 12 typedef struct nds32_relax_info @@ -275,8 +294,17 @@ 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, }; struct nds32_relax_hint_table |