aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog17
-rw-r--r--gas/config/tc-nds32.c3224
-rw-r--r--gas/config/tc-nds32.h51
3 files changed, 2003 insertions, 1289 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0cbfb40..14a4e52 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,20 @@
+2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
+
+ * config/tc-nds32.c (nds32_fsrs, nds32_fdrs, nds32_gprs): Remove.
+ (relax_table): Add new relaxation pattern.
+ (do_pseudo_la_internal, do_pseudo_ls_bhw): Expand for PIC suffix.
+ (do_pseudo_move, do_pseudo_neg, do_pseudo_pushpopm): Fix.
+ (get_range_type, nds32_elf_record_fixup_exp, nds32_get_align,
+ nds32_elf_build_relax_relation, md_assemble, invalid_prev_frag,
+ nds32_relax_frag, md_estimate_size_before_relax): Adjust relaxation.
+ (relocation_table): Remove.
+ (relax_ls_table): Load-store relaxation pattern.
+ (hint_map): Define-use chain pattern.
+ (nds32_find_reloc_table, nds32_match_hint_insn): Analysis
+ relaxation pattern.
+ (nds32_parse_name): Parse PIC suffix.
+ * config/tc-nds32.h: Declare.
+
2014-09-15 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (OPTION_omit_lock_prefix): Renamed to ...
diff --git a/gas/config/tc-nds32.c b/gas/config/tc-nds32.c
index 94479ba..353a165 100644
--- a/gas/config/tc-nds32.c
+++ b/gas/config/tc-nds32.c
@@ -55,23 +55,26 @@ static int enable_16bit = 1;
expanded from the pseudo instruction. */
static bfd_boolean pseudo_opcode = FALSE;
static struct nds32_relocs_pattern *relocs_list = NULL;
+/* Save instruction relation to inserting relaxation relocation. */
struct nds32_relocs_pattern
{
segT seg;
fragS *frag;
frchainS *frchain;
symbolS *sym;
- int reloc;
- unsigned int insn;
- unsigned int size;
+ fixS* fixP;
+ struct nds32_opcode *opcode;
char *where;
struct nds32_relocs_pattern *next;
};
-/*
-static int relax_jal_bound = 3;
-static int multi_call_relax;
-static int pltgot_call_relax;
-*/
+
+/* Suffix name and relocation. */
+struct suffix_name
+{
+ 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
".flag verbatim" at beginning of the content. We have
@@ -79,6 +82,8 @@ static int vec_size = 0;
static int verbatim = 0;
static struct hash_control *nds32_gprs_hash;
static struct hash_control *nds32_hint_hash;
+#define TLS_REG "$r27"
+#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
/* Generate relocation for relax or not, and the default is true. */
static int enable_relax_relocs = 1;
@@ -90,70 +95,13 @@ static int enable_relax_ifc = 0;
static int optimize = 0;
/* Save option -Os for code size. */
static int optimize_for_space = 0;
-
-struct nds32_keyword nds32_fsrs[] =
-{
- /* Standard names. */
- {"$fs0", 0, 0}, {"$fs1", 1, 0}, {"$fs2", 2, 0}, {"$fs3", 3, 0},
- {"$fs4", 4, 0}, {"$fs5", 5, 0}, {"$fs6", 6, 0}, {"$fs7", 7, 0},
- {"$fs8", 8, 0}, {"$fs9", 9, 0}, {"$fs10", 10, 0}, {"$fs11", 11, 0},
- {"$fs12", 12, 0}, {"$fs13", 13, 0}, {"$fs14", 14, 0}, {"$fs15", 15, 0},
- {"$fs16", 16, 0}, {"$fs17", 17, 0}, {"$fs18", 18, 0}, {"$fs19", 19, 0},
- {"$fs20", 20, 0}, {"$fs21", 21, 0}, {"$fs22", 22, 0}, {"$fs23", 23, 0},
- {"$fs24", 24, 0}, {"$fs25", 25, 0}, {"$fs26", 26, 0}, {"$fs27", 27, 0},
- {"$fs28", 28, 0}, {"$fs29", 29, 0}, {"$fs30", 30, 0}, {"$fs31", 31, 0},
- {NULL, 0, 0}
-};
-
-struct nds32_keyword nds32_fdrs[] =
-{
- /* Standard names. */
- {"$fd0", 0, 0}, {"$fd1", 1, 0}, {"$fd2", 2, 0}, {"$fd3", 3, 0},
- {"$fd4", 4, 0}, {"$fd5", 5, 0}, {"$fd6", 6, 0}, {"$fd7", 7, 0},
- {"$fd8", 8, 0}, {"$fd9", 9, 0}, {"$fd10", 10, 0}, {"$fd11", 11, 0},
- {"$fd12", 12, 0}, {"$fd13", 13, 0}, {"$fd14", 14, 0}, {"$fd15", 15, 0},
- {"$fd16", 16, 0}, {"$fd17", 17, 0}, {"$fd18", 18, 0}, {"$fd19", 19, 0},
- {"$fd20", 20, 0}, {"$fd21", 21, 0}, {"$fd22", 22, 0}, {"$fd23", 23, 0},
- {"$fd24", 24, 0}, {"$fd25", 25, 0}, {"$fd26", 26, 0}, {"$fd27", 27, 0},
- {"$fd28", 28, 0}, {"$fd29", 29, 0}, {"$fd30", 30, 0}, {"$fd31", 31, 0},
- {NULL, 0, 0}
-};
-
-struct nds32_keyword nds32_gprs[] =
-{
- /* Standard names. */
- {"$r0", 0, 0}, {"$r1", 1, 0}, {"$r2", 2, 0}, {"$r3", 3, 0},
- {"$r4", 4, 0}, {"$r5", 5, 0}, {"$r6", 6, 0}, {"$r7", 7, 0},
- {"$r8", 8, 0}, {"$r9", 9, 0}, {"$r10", 10, 0}, {"$r11", 11, 0},
- {"$r12", 12, 0}, {"$r13", 13, 0}, {"$r14", 14, 0}, {"$r15", 15, 0},
- {"$r16", 16, 0}, {"$r17", 17, 0}, {"$r18", 18, 0}, {"$r19", 19, 0},
- {"$r20", 20, 0}, {"$r21", 21, 0}, {"$r22", 22, 0}, {"$r23", 23, 0},
- {"$r24", 24, 0}, {"$r25", 25, 0}, {"$r26", 26, 0}, {"$r27", 27, 0},
- {"$r28", 28, 0}, {"$r29", 29, 0}, {"$r30", 30, 0}, {"$r31", 31, 0},
- /* Names for parameter passing. */
- {"$a0", 0, 0}, {"$a1", 1, 0}, {"$a2", 2, 0}, {"$a3", 3, 0},
- {"$a4", 4, 0}, {"$a5", 5, 0},
- /* Names reserved for 5-bit addressing only. */
- {"$s0", 6, 0}, {"$s1", 7, 0}, {"$s2", 8, 0}, {"$s3", 9, 0},
- {"$s4", 10, 0}, {"$s5", 11, 0}, {"$s6", 12, 0}, {"$s7", 13, 0},
- {"$s8", 14, 0}, {"$s9", 28, 0},
- {"$ta", 15, 0},
- {"$t0", 16, 0}, {"$t1", 17, 0}, {"$t2", 18, 0}, {"$t3", 19, 0},
- {"$t4", 20, 0}, {"$t5", 21, 0}, {"$t6", 22, 0}, {"$t7", 23, 0},
- {"$t8", 24, 0}, {"$t9", 25, 0},
- {"$p0", 26, 0}, {"$p1", 27, 0},
- {"$fp", 28, 0}, {"$gp", 29, 0}, {"$lp", 30, 0}, {"$sp", 31, 0},
- /* Names reserved for 4-bit addressing only. */
- {"$h0", 0, 0}, {"$h1", 1, 0}, {"$h2", 2, 0}, {"$h3", 3, 0},
- {"$h4", 4, 0}, {"$h5", 5, 0}, {"$h6", 6, 0}, {"$h7", 7, 0},
- {"$h8", 8, 0}, {"$h9", 9, 0}, {"$h10", 10, 0}, {"$h11", 11, 0},
- {"$h12", 16, 0}, {"$h13", 17, 0}, {"$h14", 18, 0}, {"$h15", 19, 0},
- /* Names reserved for 3-bit addressing only. */
- {"$o0", 0, 0}, {"$o1", 1, 0}, {"$o2", 2, 0}, {"$o3", 3, 0},
- {"$o4", 4, 0}, {"$o5", 5, 0}, {"$o6", 6, 0}, {"$o7", 7, 0},
- {NULL, 0, 0}
-};
-
+/* Flag to save label exist. */
+static int label_exist = 0;
+/* Flag to save state in omit_fp region. */
+static int in_omit_fp = 0;
+extern struct nds32_keyword keyword_gpr[];
+/* Tag there is relax relocation having to link. */
+static bfd_boolean relaxing = FALSE;
static struct hash_control *nds32_relax_info_hash;
static relax_info_t relax_table[] =
@@ -161,7 +109,7 @@ static relax_info_t relax_table[] =
{
"jal", /* opcode */
BR_RANGE_S16M, /* br_range */
- {{0, 0, 0}}, /* cond_field */
+ {{0, 0, 0, FALSE}}, /* cond_field */
{
{
INSN_JAL /* jal label */
@@ -180,14 +128,14 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JRAL_TA
}, /* BR_RANGE_U4G */
- }, /* relax_code_seq */
- {
- {{0, 0, 0}}, /* BR_RANGE_S256 */
- {{0, 0, 0}}, /* BR_RANGE_S16K */
- {{0, 0, 0}}, /* BR_RANGE_S64K */
- {{0, 0, 0}}, /* BR_RANGE_S16M */
- {{0, 0, 0}} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* 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 */
{
@@ -209,11 +157,13 @@ static relax_info_t relax_table[] =
}, /* BR_RANGE_S16M */
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
- {0, 12, NDS32_RELAX, BFD_RELOC_NDS32_LONGCALL1},
- {4, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {8, 4, NDS32_ORIGIN, 0},
- {8, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -221,9 +171,9 @@ static relax_info_t relax_table[] =
"bltzal", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BLTZAL /* bltzal $rt, label */
@@ -235,38 +185,38 @@ static relax_info_t relax_table[] =
INSN_BLTZAL /* bltzal $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_BGEZ, /* bgez $rt, $1 */
INSN_JAL /* jal label */
}, /* BR_RANGE_S16M */
{
- INSN_BGEZ, /* bgez $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -283,18 +233,21 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_17_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGCALL2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_17_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGCALL3},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
+ {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 */
@@ -303,9 +256,9 @@ static relax_info_t relax_table[] =
"bgezal", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BGEZAL /* bgezal $rt, label */
@@ -317,38 +270,38 @@ static relax_info_t relax_table[] =
INSN_BGEZAL /* bgezal $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_BLTZ, /* bltz $rt, $1 */
INSN_JAL /* jal label */
}, /* BR_RANGE_S16M */
{
- INSN_BLTZ, /* bltz $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -365,26 +318,29 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_17_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGCALL2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_17_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGCALL3},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
{
"j", /* opcode */
BR_RANGE_S16M, /* br_range */
- {{0, 0, 0}}, /* cond_field */
+ {{0, 0, 0, FALSE}}, /* cond_field */
{
{
(INSN_J8 << 16) /* j8 label */
@@ -403,14 +359,14 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
}, /* BR_RANGE_U4G */
- }, /* relax_code_seq */
- {
- {{0, 0, 0}}, /* BR_RANGE_S256 */
- {{0, 0, 0}}, /* BR_RANGE_S16K */
- {{0, 0, 0}}, /* BR_RANGE_S64K */
- {{0, 0, 0}}, /* BR_RANGE_S16M */
- {{0, 0, 0}} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* 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 */
{
@@ -432,18 +388,20 @@ static relax_info_t relax_table[] =
}, /* BR_RANGE_S16M */
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
- {0, 12, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP1},
- {4, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {8, 4, NDS32_ORIGIN, 0},
- {8, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
{
"j8", /* opcode */
BR_RANGE_S256, /* br_range */
- {{0, 0, 0}}, /* cond_field */
+ {{0, 0, 0, FALSE}}, /* cond_field */
{
{
(INSN_J8 << 16) /* j8 label */
@@ -462,14 +420,14 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
}, /* BR_RANGE_U4G */
- }, /* relax_code_seq */
- {
- {{0, 0, 0}}, /* BR_RANGE_S256 */
- {{0, 0, 0}}, /* BR_RANGE_S16K */
- {{0, 0, 0}}, /* BR_RANGE_S64K */
- {{0, 0, 0}}, /* BR_RANGE_S16M */
- {{0, 0, 0}} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* 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 */
{
@@ -491,11 +449,13 @@ static relax_info_t relax_table[] =
}, /* BR_RANGE_S16M */
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
- {0, 12, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP1},
- {4, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {8, 4, NDS32_ORIGIN, 0},
- {8, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -503,9 +463,9 @@ static relax_info_t relax_table[] =
"beqz", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BEQZ /* beqz $rt, label */
@@ -517,44 +477,44 @@ static relax_info_t relax_table[] =
INSN_BEQZ /* beqz $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_BNEZ, /* bnez $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BNEZ, /* bnez $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -566,20 +526,24 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
@@ -588,9 +552,9 @@ static relax_info_t relax_table[] =
"bgez", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BGEZ /* bgez $rt, label */
@@ -602,38 +566,38 @@ static relax_info_t relax_table[] =
INSN_BGEZ /* bgez $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_BLTZ, /* bltz $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BLTZ, /* bltz $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -650,19 +614,22 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -670,9 +637,9 @@ static relax_info_t relax_table[] =
"bnez", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BNEZ /* bnez $rt, label */
@@ -684,44 +651,44 @@ static relax_info_t relax_table[] =
INSN_BNEZ /* bnez $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_BEQZ, /* beqz $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BEQZ, /* beqz $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -733,21 +700,25 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -755,9 +726,9 @@ static relax_info_t relax_table[] =
"bgtz", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BGTZ /* bgtz $rt, label */
@@ -769,38 +740,38 @@ static relax_info_t relax_table[] =
INSN_BGTZ /* bgtz $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BLEZ, /* blez $rt, $1 */
+ INSN_BLEZ, /* blez $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BLEZ, /* blez $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -817,19 +788,22 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -837,9 +811,9 @@ static relax_info_t relax_table[] =
"blez", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BLEZ /* blez $rt, label */
@@ -851,38 +825,38 @@ static relax_info_t relax_table[] =
INSN_BLEZ /* blez $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BGTZ, /* bgtz $rt, $1 */
+ INSN_BGTZ, /* bgtz $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BGTZ, /* bgtz $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -899,19 +873,22 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -919,9 +896,9 @@ static relax_info_t relax_table[] =
"bltz", /* opcode */
BR_RANGE_S64K, /* br_range */
{
- {0, 20, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BLTZ /* bltz $rt, label */
@@ -933,38 +910,38 @@ static relax_info_t relax_table[] =
INSN_BLTZ /* bltz $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_BGEZ, /* bgez $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BGEZ, /* bgez $rt, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 4, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -981,19 +958,22 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1001,10 +981,10 @@ static relax_info_t relax_table[] =
"beq", /* opcode */
BR_RANGE_S16K, /* br_range */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BEQ /* beq $rt, $ra, label */
@@ -1026,40 +1006,40 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
} /* BR_RANGE_U4G */
- }, /* relax_code_seq */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 8, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1067,28 +1047,34 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1096,10 +1082,10 @@ static relax_info_t relax_table[] =
"bne", /* opcode */
BR_RANGE_S16K, /* br_range */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
INSN_BNE /* bne $rt, $ra, label */
@@ -1121,40 +1107,40 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
} /* BR_RANGE_U4G */
- }, /* relax_code_seq */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 15, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 4, 8, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1162,28 +1148,33 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1191,12 +1182,12 @@ static relax_info_t relax_table[] =
"beqz38", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
- INSN_BEQZ /* beqz $rt, label */
+ INSN_BEQZ38 << 16 /* beqz $rt, label */
}, /* BR_RANGE_S256 */
{
INSN_BEQZ /* beqz $rt, label */
@@ -1205,7 +1196,7 @@ static relax_info_t relax_table[] =
INSN_BEQZ /* beqz $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_BNEZ, /* bnez $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
@@ -1214,35 +1205,34 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
} /* BR_RANGE_U4G */
- }, /* relax_code_seq */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {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 */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1254,21 +1244,25 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1276,12 +1270,12 @@ static relax_info_t relax_table[] =
"bnez38", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
- INSN_BNEZ /* bnez $rt, label */
+ INSN_BNEZ38 << 16 /* bnez $rt, label */
}, /* BR_RANGE_S256 */
{
INSN_BNEZ /* bnez $rt, label */
@@ -1290,7 +1284,7 @@ static relax_info_t relax_table[] =
INSN_BNEZ /* bnez $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_BEQZ, /* beqz $rt, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
@@ -1299,35 +1293,34 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
} /* BR_RANGE_U4G */
- }, /* relax_code_seq */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {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 */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1339,40 +1332,44 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
{
"beqzs8", /* opcode */
BR_RANGE_S256, /* br_range */
- {{0, 0, 0}}, /* cond_field */
+ {{0, 0, 0, FALSE}}, /* cond_field */
{
{
- INSN_BEQZ_TA /* beqz $r15, label */
+ INSN_BEQZS8 << 16 /* beqz $r15, label */
}, /* BR_RANGE_S256 */
{
- INSN_BNEZ /* bnez $rt, label */
+ INSN_BEQZ_TA /* bnez $rt, label */
}, /* BR_RANGE_S16K */
{
- INSN_BNEZ /* bnez $rt, label */
+ INSN_BEQZ_TA /* bnez $rt, label */
}, /* BR_RANGE_S64K */
{
- INSN_BNEZ_TA, /* bnez $r15, $1 */
+ INSN_BNEZ_TA, /* bnez $r15, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
@@ -1381,20 +1378,19 @@ static relax_info_t relax_table[] =
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
} /* BR_RANGE_U4G */
- }, /* relax_code_seq */
- {
- {{0, 0, 0}}, /* BR_RANGE_S256 */
- {{0, 0, 0}}, /* BR_RANGE_S16K */
- {{0, 0, 0}}, /* BR_RANGE_S64K */
- {{0, 0, 0}}, /* BR_RANGE_S16M */
- {{0, 0, 0}} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
- {4, 4, 4, 8, 16}, /* relax_code_size */
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ }, /* 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_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1406,20 +1402,24 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
@@ -1427,10 +1427,10 @@ static relax_info_t relax_table[] =
{
"bnezs8", /* opcode */
BR_RANGE_S256, /* br_range */
- {{0, 0, 0}}, /* cond_field */
+ {{0, 0, 0, FALSE}}, /* cond_field */
{
{
- INSN_BNEZ_TA /* bnez $r15, label */
+ INSN_BNEZS8 << 16 /* bnez $r15, label */
}, /* BR_RANGE_S256 */
{
INSN_BNEZ_TA /* bnez $r15, label */
@@ -1439,29 +1439,28 @@ static relax_info_t relax_table[] =
INSN_BNEZ_TA /* bnez $r15, label */
}, /* BR_RANGE_S64K */
{
- INSN_BEQZ_TA, /* beqz $r15, $1 */
+ INSN_BEQZ_TA, /* beqz $r15, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BEQZ_TA, /* beqz $r15, $1 */
+ 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}}, /* BR_RANGE_S256 */
- {{0, 0, 0}}, /* BR_RANGE_S16K */
- {{0, 0, 0}}, /* BR_RANGE_S64K */
- {{0, 0, 0}}, /* BR_RANGE_S16M */
- {{0, 0, 0}} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
- {4, 4, 4, 8, 16}, /* relax_code_size */
- {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ }, /* 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_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1473,21 +1472,25 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1495,59 +1498,58 @@ static relax_info_t relax_table[] =
"bnes38", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
- INSN_BNE_R5 /* bne $rt, $r5, label */
+ INSN_BNES38 << 16 /* bne $rt, $R5, label */
}, /* BR_RANGE_S256 */
{
- INSN_BNE_R5 /* bne $rt, $r5, label */
+ INSN_BNE_R5 /* bne $rt, $R5, label */
}, /* BR_RANGE_S16K */
{
- INSN_BEQ_R5, /* beq $rt, $r5, $1 */
+ INSN_BEQ_R5, /* beq $rt, $R5, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S64K */
{
- INSN_BEQ_R5, /* beq $rt, $r5, $1 */
+ INSN_BEQ_R5, /* beq $rt, $R5, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BEQ_R5, /* beq $rt, $r5, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 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 */
+ }, /* relax_code_condition */
+ {2, 4, 8, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1555,28 +1557,33 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1584,59 +1591,58 @@ static relax_info_t relax_table[] =
"beqs38", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7},
- { 0, 0, 0 }
- }, /* cond_field */
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
{
{
- INSN_BEQ_R5 /* beq $rt, $r5, label */
+ INSN_BEQS38 << 16 /* beq $rt, $R5, label */
}, /* BR_RANGE_S256 */
{
- INSN_BEQ_R5 /* beq $rt, $r5, label */
+ INSN_BEQ_R5 /* beq $rt, $R5, label */
}, /* BR_RANGE_S16K */
{
- INSN_BNE_R5, /* bne $rt, $r5, $1 */
+ INSN_BNE_R5, /* bne $rt, $R5, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S64K */
{
- INSN_BNE_R5, /* bne $rt, $r5, $1 */
+ INSN_BNE_R5, /* bne $rt, $R5, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BNE_R5, /* bne $rt, $r5, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 20, 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 */
+ }, /* relax_code_condition */
+ {2, 4, 8, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
{
{
- {0, 4, NDS32_ORIGIN, BFD_RELOC_NDS32_17_PCREL},
- {0, 2, NDS32_CONVERT, BFD_RELOC_NDS32_9_PCREL},
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
@@ -1644,28 +1650,33 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 8, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP2},
- {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, 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, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_ORIGIN| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_15_PCREL},
- {0, 2, NDS32_CONVERT| NDS32_CREATE_LABLE, BFD_RELOC_NDS32_9_PCREL},
- {0, 16, NDS32_RELAX, BFD_RELOC_NDS32_LONGJUMP3},
- {4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
- {0, 0, 0, 0}
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
@@ -1673,60 +1684,60 @@ static relax_info_t relax_table[] =
"beqc", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
- }, /* cond_field */
+ {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_MOVI_TA, /* movi $ta, imm11s */
INSN_BEQ_TA /* beq $rt, $ta, label */
}, /* BR_RANGE_S16K */
{
- INSN_MOVI_TA, /* movi $ta, imm11s */
- INSN_BEQ_TA /* beq $rt, $ta, label */
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ INSN_J /* j label */
}, /* BR_RANGE_S64K */
{
- INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 0, 0xFFFFF},
- {4, 20, 0x1F},
- {0, 0, 0}
+ {0, 0, 0xFFFFF, FALSE},
+ {4, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 0, 0xFFFFF},
- {4, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 8, 8, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -1735,24 +1746,26 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
{4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
- {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
+ {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 */
@@ -1761,60 +1774,60 @@ static relax_info_t relax_table[] =
"bnec", /* opcode */
BR_RANGE_S256, /* br_range */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
- }, /* cond_field */
+ {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_MOVI_TA, /* movi $ta, imm11s */
INSN_BNE_TA /* bne $rt, $ta, label */
}, /* BR_RANGE_S16K */
{
- INSN_MOVI_TA, /* movi $ta, imm11s */
- INSN_BNE_TA /* bne $rt, $ta, label */
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ INSN_J /* j label */
}, /* BR_RANGE_S64K */
{
- INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
INSN_J /* j label */
}, /* BR_RANGE_S16M */
{
- INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ 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 */
+ }, /* relax_code_seq */
{
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S256 */
{
- {0, 0, 0xFFFFF},
- {4, 20, 0x1F},
- {0, 0, 0}
+ {0, 0, 0xFFFFF, FALSE},
+ {4, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16K */
{
- {0, 0, 0xFFFFF},
- {4, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S64K */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
}, /* BR_RANGE_S16M */
{
- {0, 8, 0x7FF},
- {0, 20, 0x1F},
- {0, 0, 0}
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
} /* BR_RANGE_U4G */
- }, /* relax_code_condition */
+ }, /* relax_code_condition */
{4, 8, 8, 8, 16}, /* relax_code_size */
{4, 4, 4, 4, 4}, /* relax_branch_isize */
{
@@ -1823,40 +1836,41 @@ static relax_info_t relax_table[] =
{0, 0, 0, 0}
}, /* BR_RANGE_S256 */
{
- {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+ {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16K */
{
- {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S64K */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
}, /* BR_RANGE_S16M */
{
- {0, 4, NDS32_CREATE_LABLE, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
- {12, 4, NDS32_ORIGIN, 0},
- {12, 2, NDS32_CONVERT, 0},
+ {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
} /* BR_RANGE_U4G */
} /* relax_fixup */
},
{
- NULL, /* opcode */
- 0, /* br_range */
- {{0, 0, 0}}, /* cond_field */
- {{0}}, /* relax_code_seq */
- {{{0, 0, 0}}}, /* relax_code_condition */
- {0}, /* relax_code_size */
- {0}, /* relax_branch_isize */
- {{{0, 0, 0, 0}}}, /* relax_fixup */
+ NULL, /* opcode */
+ 0, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {{0}}, /* relax_code_seq */
+ {{{0, 0, 0, FALSE}}}, /* relax_code_condition */
+ {0}, /* relax_code_size */
+ {0}, /* relax_branch_isize */
+ {{{0, 0, 0, 0}}}, /* relax_fixup */
},
};
-
/* GAS definitions for command-line options. */
enum options
@@ -1872,7 +1886,7 @@ enum options
OPTION_OPTIMIZE_SPACE
};
-const char *md_shortopts = "m:G:O";
+const char *md_shortopts = "m:O:";
struct option md_longopts[] =
{
{"O1", no_argument, NULL, OPTION_OPTIMIZE},
@@ -1884,6 +1898,7 @@ struct option md_longopts[] =
{"meb", no_argument, NULL, OPTION_BIG},
{"mel", no_argument, NULL, OPTION_LITTLE},
{"mall-ext", no_argument, NULL, OPTION_TURBO},
+ {"mext-all", no_argument, NULL, OPTION_TURBO},
{"mpic", no_argument, NULL, OPTION_PIC},
/* Relaxation related options. */
{"mno-fp-as-gp-relax", no_argument, NULL, OPTION_RELAX_FP_AS_GP_OFF},
@@ -2131,7 +2146,9 @@ static int
builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
{
struct nds32_keyword *k;
-
+ if (*s != '$')
+ return -1;
+ s++;
k = hash_find (nds32_gprs_hash, s);
if (k == NULL)
@@ -2177,9 +2194,9 @@ static void
do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
char *arg_label = argv[0];
+ relaxing = TRUE;
/* b label */
- if (nds32_pic
- && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
+ if (nds32_pic && strstr (arg_label, "@PLT"))
{
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
@@ -2190,12 +2207,14 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
md_assemblef ("j %s", arg_label);
}
+ relaxing = FALSE;
}
static void
do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
char *arg_label = argv[0];
+ relaxing = TRUE;
/* bal|call label */
if (nds32_pic
&& (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
@@ -2209,6 +2228,7 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
md_assemblef ("jal %s", arg_label);
}
+ relaxing = FALSE;
}
static void
@@ -2291,21 +2311,38 @@ do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
}
static void
-do_pseudo_la_internal (const char *arg_reg, const char *arg_label, const char *line)
+do_pseudo_la_internal (const char *arg_reg, const char *arg_label,
+ const char *line)
{
+ relaxing = TRUE;
/* rt, label */
- if (!nds32_pic)
+ if (!nds32_pic && !strstr(arg_label, "@"))
{
md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
}
- else if ((strstr (arg_label, "@PLT") || strstr (arg_label, "@GOTOFF")))
+ else if (strstr (arg_label, "@TPOFF"))
+ {
+ /* la $rt, sym@TPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
+ }
+ else if (strstr(arg_label, "@GOTTPOFF"))
+ {
+ /* la $rt, sym@GOTTPOFF*/
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
+ md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
+ }
+ else if (nds32_pic && ((strstr (arg_label, "@PLT")
+ || strstr (arg_label, "@GOTOFF"))))
{
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
md_assemblef ("add %s,$ta,$gp", arg_reg);
}
- else if (strstr (arg_label, "@GOT"))
+ else if (nds32_pic && strstr (arg_label, "@GOT"))
{
long addend = builtin_addend (arg_label, NULL);
@@ -2327,6 +2364,7 @@ do_pseudo_la_internal (const char *arg_reg, const char *arg_label, const char *l
}
else
as_bad (_("need PIC qualifier with symbol. '%s'"), line);
+ relaxing = FALSE;
}
static void
@@ -2390,16 +2428,36 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
if (builtin_isreg (argv[1], NULL))
{
/* lwi */
- md_assemblef ("%c%c%si %s,[%s]", ls, size, argv[0], argv[1]);
+ md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
}
else if (!nds32_pic)
{
- /* lwi */
- md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
- md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
+ relaxing = TRUE;
+ if (strstr (argv[1], "@TPOFF"))
+ {
+ /* ls.w $rt, sym@TPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
+ md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
+ }
+ else if (strstr (argv[1], "@GOTTPOFF"))
+ {
+ /* ls.w $rt, sym@GOTTPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
+ md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
+ }
+ else
+ {
+ /* lwi */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
+ }
+ relaxing = FALSE;
}
else
{
+ relaxing = TRUE;
/* PIC code. */
if (strstr (argv[1], "@GOTOFF"))
{
@@ -2430,6 +2488,7 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
{
as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
}
+ relaxing = FALSE;
}
}
@@ -2464,7 +2523,7 @@ static void
do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
{
char *arg_rt = argv[0];
- char *arg_inc = argv[2];
+ char *arg_inc = argv[1];
char ls = 'r';
char size = 'x';
const char *sign = "";
@@ -2521,18 +2580,25 @@ do_pseudo_move_reg_internal (char *dst, char *src)
static void
do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
+ expressionS exp;
+
+ parse_expression (argv[1], &exp);
+
if (builtin_isreg (argv[1], NULL))
do_pseudo_move_reg_internal (argv[0], argv[1]);
+ else if (exp.X_op == O_constant)
+ /* move $rt, imm -> li $rt, imm */
+ do_pseudo_li_internal (argv[0], exp.X_add_number);
else
- /* move $rt, imm -> li $rt, imm */
- do_pseudo_li (argc, argv, PV_DONT_CARE);
+ /* l.w $rt, var -> l.w $rt, var */
+ do_pseudo_ls_bhw (argc, argv, 2);
}
static void
do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
{
- md_assemble ("movi $ta,0");
- md_assemblef ("sub %s,$ta,%s", argv[0], argv[1]);
+ /* Instead of "subri". */
+ md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
}
static void
@@ -2586,10 +2652,21 @@ do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
/* Adjust $re, $rb. */
if (rb >= 28)
rb = re = 31;
- else if (re >= 28)
+ else if (nds32_gpr16 != 1 && re >= 28)
re = 27;
- md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
+ /* Reduce register. */
+ if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
+ {
+ 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)
+ md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
+ }
+ else
+ md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
}
static void
@@ -2842,7 +2919,7 @@ struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
{"swi.p", 3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
{"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
{"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
- {"lwsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
+ {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
{"move", 2, do_pseudo_move, 0, 0},
{"neg", 2, do_pseudo_neg, 0, 0},
@@ -3138,7 +3215,11 @@ nds32_parse_option (int c, char *arg)
break;
default:
/* Determination of which option table to search for to save time. */
+ if (!arg)
+ return 0;
+
ptr_arg = strchr (arg, '=');
+
if (ptr_arg)
{
/* Find the value after '='. */
@@ -3155,17 +3236,17 @@ nds32_parse_option (int c, char *arg)
}
else
{
- for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
- {
- int disable = 0;
+ int disable = 0;
- /* Filter out the Disable option first. */
- if (strncmp (arg, "no-", 3) == 0)
- {
- disable = 1;
- arg += 3;
- }
+ /* Filter out the Disable option first. */
+ if (strncmp (arg, "no-", 3) == 0)
+ {
+ disable = 1;
+ arg += 3;
+ }
+ for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
+ {
if (strcmp (arg, fine_tune->name) == 0)
{
if (fine_tune->var != NULL)
@@ -3409,12 +3490,8 @@ nds32_aligned_cons (int idx)
exp.X_add_number = 0;
exp.X_op = O_constant;
- fix_new_exp (frag_now,
- frag_now_fix () - (1 << idx),
- 1 << idx,
- &exp,
- 0,
- BFD_RELOC_NDS32_DATA);
+ fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
+ &exp, 0, BFD_RELOC_NDS32_DATA);
}
}
@@ -3528,12 +3605,14 @@ nds32_omit_fp_begin (int mode)
exp.X_add_symbol = abs_section_sym;
if (mode == 1)
{
+ in_omit_fp = 1;
exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
}
else
{
+ in_omit_fp = 0;
exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
BFD_RELOC_NDS32_RELAX_REGION_END);
@@ -3649,6 +3728,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
group = group->next;
group->next = new;
}
+ relaxing = TRUE;
}
/* Decide the size of vector entries, only accepts 4 or 16 now. */
@@ -3795,12 +3875,23 @@ void
nds32_pre_do_align (int n, char *fill, int len, int max)
{
/* Only make a frag if we HAVE to... */
+ fragS *fragP;
if (n != 0 && !need_pass_2)
{
if (fill == NULL)
{
if (subseg_text_p (now_seg))
- frag_align_code (n, max);
+ {
+ fragP = frag_now;
+ frag_align_code (n, max);
+
+ /* Tag this alignment when there is a lable before it. */
+ if (label_exist)
+ {
+ fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
+ label_exist = 0;
+ }
+ }
else
frag_align (n, 0, max);
}
@@ -3888,7 +3979,7 @@ md_begin (void)
/* Initial general pupose registers hash table. */
nds32_gprs_hash = hash_new ();
- for (k = nds32_gprs; k->name; k++)
+ for (k = keyword_gpr; k->name; k++)
hash_insert (nds32_gprs_hash, k->name, k);
/* Initial branch hash table. */
@@ -3898,6 +3989,7 @@ md_begin (void)
/* Initial relax hint hash table. */
nds32_hint_hash = hash_new ();
+ enable_16bit = nds32_16bit_ext;
}
/* HANDLE_ALIGN in write.c. */
@@ -3965,6 +4057,8 @@ nds32_frob_label (symbolS *label)
int
nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
{
+ if (optimize && subseg_text_p (now_seg))
+ label_exist = 1;
return 1;
}
@@ -4009,19 +4103,19 @@ get_range_type (const struct nds32_field *field)
/* Save pseudo instruction relocation list. */
static struct nds32_relocs_pattern*
-nds32_elf_save_pseudo_pattern (int reloc, struct nds32_asm_insn *insn,
+nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
char *out, symbolS *sym,
- struct nds32_relocs_pattern *reloc_ptr)
+ struct nds32_relocs_pattern *reloc_ptr,
+ fragS *fragP)
{
if (!reloc_ptr)
reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern));
reloc_ptr->seg = now_seg;
reloc_ptr->sym = sym;
- reloc_ptr->frag = frag_now;
+ reloc_ptr->frag = fragP;
reloc_ptr->frchain = frchain_now;
- reloc_ptr->reloc = reloc;
- reloc_ptr->insn = insn->opcode->value;
- reloc_ptr->size = insn->opcode->isize;
+ reloc_ptr->fixP = fixP;
+ reloc_ptr->opcode = opcode;
reloc_ptr->where = out;
reloc_ptr->next = NULL;
return reloc_ptr;
@@ -4029,88 +4123,103 @@ nds32_elf_save_pseudo_pattern (int reloc, struct nds32_asm_insn *insn,
/* Check X_md to transform relocation. */
-static void
-nds32_elf_record_fixup_exp (char *str, const struct nds32_field *fld,
+static fixS*
+nds32_elf_record_fixup_exp (fragS *fragP, char *str,
+ const struct nds32_field *fld,
expressionS *pexp, char* out,
struct nds32_asm_insn *insn)
{
int reloc = -1;
- symbolS *sym = NULL;
- struct nds32_relocs_group *group;
- struct nds32_relocs_pattern *reloc_ptr;
+ expressionS exp;
+ fixS *fixP = NULL;
/* Handle instruction relocation. */
if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
{
/* Relocation for hi20 modifier. */
- sym = pexp->X_add_symbol;
switch (pexp->X_md)
{
- case BFD_RELOC_NDS32_GOTOFF:
- /* @GOTOFF */
+ case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
break;
- case BFD_RELOC_NDS32_GOT20:
- /* @GOT */
+ case BFD_RELOC_NDS32_GOT20: /* @GOT */
reloc = BFD_RELOC_NDS32_GOT_HI20;
break;
- case BFD_RELOC_NDS32_25_PLTREL:
- /* @PLT */
+ case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
if (!nds32_pic)
as_bad (_("Invalid PIC expression."));
else
reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
break;
- default:
- /* No suffix. */
+ case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
+ reloc = BFD_RELOC_NDS32_GOTPC_HI20;
+ break;
+ case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
+ break;
+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
+ break;
+ default: /* No suffix. */
reloc = BFD_RELOC_NDS32_HI20;
break;
}
-
- fix_new_exp (frag_now, out - frag_now->fr_literal,
- insn->opcode->isize, insn->info, 0 /* pcrel */,
- reloc);
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
}
else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
{
/* Relocation for lo12 modifier. */
if (fld->bitsize == 15 && fld->shift == 0)
{
+ /* [ls]bi || ori */
switch (pexp->X_md)
{
- case BFD_RELOC_NDS32_GOTOFF:
- /* @GOTOFF */
+ case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
break;
- case BFD_RELOC_NDS32_GOT20:
- /* @GOT */
+ case BFD_RELOC_NDS32_GOT20: /* @GOT */
reloc = BFD_RELOC_NDS32_GOT_LO12;
break;
- case BFD_RELOC_NDS32_25_PLTREL:
- /* @PLT */
+ case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
if (!nds32_pic)
as_bad (_("Invalid PIC expression."));
else
reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
break;
- default:
- /* No suffix. */
- reloc = BFD_RELOC_NDS32_LO12S0; /* [ls]bi || ori */
+ case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
+ reloc = BFD_RELOC_NDS32_GOTPC_LO12;
+ break;
+ case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
+ break;
+ default: /* No suffix. */
+ reloc = BFD_RELOC_NDS32_LO12S0;
break;
}
}
else if (fld->bitsize == 15 && fld->shift == 1)
reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */
else if (fld->bitsize == 15 && fld->shift == 2)
- reloc = BFD_RELOC_NDS32_LO12S2; /* [ls]wi */
+ {
+ /* [ls]wi */
+ switch (pexp->X_md)
+ {
+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
+ break;
+ default: /* No suffix. */
+ reloc = BFD_RELOC_NDS32_LO12S2;
+ break;
+ }
+ }
else if (fld->bitsize == 15 && fld->shift == 3)
reloc = BFD_RELOC_NDS32_LO12S3; /* [ls]di */
else if (fld->bitsize == 12 && fld->shift == 2)
- reloc = BFD_RELOC_NDS32_LO12S2; /* f[ls][sd]i */
+ reloc = R_NDS32_LO12S2_SP_RELA; /* f[ls][sd]i */
- fix_new_exp (frag_now, out - frag_now->fr_literal,
- insn->opcode->isize, insn->info, 0 /* pcrel */,
- reloc);
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
}
else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
&& (insn->attr & NASM_ATTR_PCREL))
@@ -4127,9 +4236,8 @@ nds32_elf_record_fixup_exp (char *str, const struct nds32_field *fld,
else
abort ();
- fix_new_exp (frag_now, out - frag_now->fr_literal,
- insn->opcode->isize, insn->info, 1 /* pcrel */,
- reloc);
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 1 /* pcrel */, reloc);
}
else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
&& (insn->attr & NASM_ATTR_GPREL))
@@ -4144,9 +4252,16 @@ nds32_elf_record_fixup_exp (char *str, const struct nds32_field *fld,
else
abort ();
- fix_new_exp (frag_now, out - frag_now->fr_literal,
- insn->opcode->isize, insn->info, 0 /* pcrel */,
- reloc);
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
+ /* Insert INSN16 for converting fp_as_gp. */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
+ fix_new_exp (fragP, out - fragP->fr_literal,
+ insn->opcode->isize, &exp, 0 /* pcrel */,
+ BFD_RELOC_NDS32_INSN16);
}
else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
&& (insn->attr & NASM_ATTR_PCREL))
@@ -4157,20 +4272,50 @@ nds32_elf_record_fixup_exp (char *str, const struct nds32_field *fld,
else
abort ();
- fix_new_exp (frag_now, out - frag_now->fr_literal,
- insn->opcode->isize, insn->info, 1 /* pcrel */,
- reloc);
+ 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);
+ 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);
+
+ return fixP;
+}
+
+/* Build instruction pattern to relax. There are two type group pattern
+ including pseudo instruction and relax hint. */
+
+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_relocs_pattern *reloc_ptr;
+ struct nds32_relocs_group *group;
+ symbolS *sym = NULL;
+
+ /* The expression may be used uninitialized. */
+ if (fld)
+ sym = pexp->X_add_symbol;
if (pseudo_opcode)
{
/* Save instruction relation for pseudo instruction expanding pattern. */
- reloc_ptr = nds32_elf_save_pseudo_pattern (reloc, insn, out, sym, NULL);
+ reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+ NULL, fragP);
if (!relocs_list)
relocs_list = reloc_ptr;
else
@@ -4187,267 +4332,120 @@ nds32_elf_record_fixup_exp (char *str, const struct nds32_field *fld,
group = nds32_relax_hint_current;
while (group)
{
- nds32_elf_save_pseudo_pattern (reloc, insn, out, sym, group->pattern);
+ nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+ group->pattern, fragP);
group = group->next;
free (nds32_relax_hint_current);
nds32_relax_hint_current = group;
}
}
+
+ /* Set relaxing false only for relax_hint trigger it. */
+ if (!pseudo_opcode)
+ relaxing = FALSE;
}
-#define N32_MEM_EXT(insn) (N32_OP6_MEM<< 25| insn)
+#define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
/* Relax pattern for link time relaxation. */
-static struct nds32_relocation_map relocation_table[] =
+static struct nds32_relax_hint_table relax_ls_table[] =
{
+ {
+ /* Set address: la -> sethi ori. */
+ NDS32_RELAX_HINT_LA, /* main_type */
+ 8, /* relax_code_size */
{
- /* Load-Store: sethi lwi+
- Load address: sethi ori */
- BFD_RELOC_NDS32_HI20, /* main_type */
- {
- {
- {BFD_RELOC_NDS32_LOADSTORE, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_INSN16, 0},
- {0, 0}
- },
- {
- {0, 0}
- }
- },
- },
- {
- /* Load-Store: sethi ori lwi+
- Load address: sethi ori add */
- BFD_RELOC_NDS32_GOTOFF_HI20, /* main_type */
- {
- {
- {BFD_RELOC_NDS32_LOADSTORE, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_INSN16, 0},
- {BFD_RELOC_NDS32_PTR, 0},
- {BFD_RELOC_NDS32_PTR_COUNT, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_GOTOFF_SUFF, 0},
- {BFD_RELOC_NDS32_PTR_RESOLVED, 0},
- {0, 0}
- },
- {
- {0, 0}
- }
- },
- },
+ OP6 (SETHI),
+ OP6 (ORI),
+ }, /* relax_code_seq */
{
- /* Load-Store: sethi ori lw lwi+
- Load address: sethi ori lw [addi|add] */
- BFD_RELOC_NDS32_GOT_HI20, /* main_type */
- {
- {
- {BFD_RELOC_NDS32_LOADSTORE, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_INSN16, 0},
- /* For pseudo la and l.w.
- Lw is the next one instruction. */
- {BFD_RELOC_NDS32_PTR, N32_MEM_EXT (N32_MEM_LW)},
- {BFD_RELOC_NDS32_PTR_COUNT, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_GOT_SUFF, N32_MEM_EXT (N32_MEM_LW)},
- {BFD_RELOC_NDS32_PTR_RESOLVED, N32_MEM_EXT (N32_MEM_LW)},
- {0, 0}
- },
- {
- {0, 0},
- },
- },
- },
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+ {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
+ } /* relax_fixup */
+ },
+ {
+ /* Set address: l.w -> sethi ori. */
+ NDS32_RELAX_HINT_LS, /* main_type */
+ 8, /* relax_code_size */
{
- BFD_RELOC_NDS32_PLT_GOTREL_HI20, /* main_type */
- {
- {
- {BFD_RELOC_NDS32_LOADSTORE, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_INSN16, 0},
- /* For pseudo bal.
- jral is the target instruction. */
- {BFD_RELOC_NDS32_PTR, INSN_JRAL},
- {BFD_RELOC_NDS32_PTR, (INSN_JRAL | (REG_LP << 20))},
- {BFD_RELOC_NDS32_PTR_COUNT, 0},
- {0, 0}
- },
- {
- /* For pseudo bal.
- jral is the target instruction. */
- {BFD_RELOC_NDS32_PTR, INSN_JRAL},
- {BFD_RELOC_NDS32_PTR, (INSN_JRAL | (REG_LP << 20))},
- {BFD_RELOC_NDS32_PTR_COUNT, 0},
- {0, 0}
- },
- {
- {BFD_RELOC_NDS32_PLT_GOT_SUFF, 0},
- {BFD_RELOC_NDS32_PTR_RESOLVED, 0},
- {0, 0}
- },
- {
- {0, 0},
- },
- },
- },
+ OP6 (SETHI),
+ OP6 (LBI),
+ }, /* relax_code_seq */
{
- 0,
- {
- {
- {0, 0},
- },
- },
- }
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+ {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
+ } /* relax_fixup */
+ },
+ {
+ 0,
+ 0,
+ {0},
+ {{0, 0 , 0, 0}}
+ }
};
/* Since sethi loadstore relocation has to using next instruction to determine
elimination itself or not, we have to return the next instruction range. */
static int
-nds32_elf_sethi_range (struct nds32_relocs_pattern *relocs_ptr)
-{
- unsigned int insn = relocs_ptr->insn;
- int range;
- switch (insn)
- {
- case INSN_LBI:
- case INSN_SBI:
- case INSN_LBSI:
- case N32_MEM_EXT (N32_MEM_LB):
- case N32_MEM_EXT (N32_MEM_LBS):
- case N32_MEM_EXT (N32_MEM_SB):
- range = 0x01;
- break;
- case INSN_LHI:
- case INSN_SHI:
- case INSN_LHSI:
- case N32_MEM_EXT (N32_MEM_LH):
- case N32_MEM_EXT (N32_MEM_LHS):
- case N32_MEM_EXT (N32_MEM_SH):
- range = 0x02;
- break;
- case INSN_LWI:
- case INSN_SWI:
- case N32_MEM_EXT (N32_MEM_LW):
- case N32_MEM_EXT (N32_MEM_SW):
- range = 0x04;
- break;
- case INSN_FLSI:
- case INSN_FSSI:
- range = 0x08;
- break;
- case INSN_FLDI:
- case INSN_FSDI:
- range = 0x10;
- break;
- case INSN_ORI:
- range = 0x20;
- break;
- default:
- range = 0x0;
- break;
+nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
+{
+ int range = 0;
+ while (pattern)
+ {
+ switch (pattern->opcode->value)
+ {
+ case INSN_LBI:
+ case INSN_SBI:
+ case INSN_LBSI:
+ case N32_MEM_EXT (N32_MEM_LB):
+ case N32_MEM_EXT (N32_MEM_LBS):
+ case N32_MEM_EXT (N32_MEM_SB):
+ range = NDS32_LOADSTORE_BYTE;
+ break;
+ case INSN_LHI:
+ case INSN_SHI:
+ case INSN_LHSI:
+ case N32_MEM_EXT (N32_MEM_LH):
+ case N32_MEM_EXT (N32_MEM_LHS):
+ case N32_MEM_EXT (N32_MEM_SH):
+ range = NDS32_LOADSTORE_HALF;
+ break;
+ case INSN_LWI:
+ case INSN_SWI:
+ case N32_MEM_EXT (N32_MEM_LW):
+ case N32_MEM_EXT (N32_MEM_SW):
+ range = NDS32_LOADSTORE_WORD;
+ break;
+ case INSN_FLSI:
+ case INSN_FSSI:
+ range = NDS32_LOADSTORE_FLOAT_S;
+ break;
+ case INSN_FLDI:
+ case INSN_FSDI:
+ range = NDS32_LOADSTORE_FLOAT_D;
+ break;
+ case INSN_ORI:
+ range = NDS32_LOADSTORE_IMM;
+ break;
+ default:
+ range = NDS32_LOADSTORE_NONE;
+ break;
+ }
+ if (range != NDS32_LOADSTORE_NONE)
+ break;
+ pattern = pattern->next;
}
return range;
}
/* 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 ) \
+#define SET_ADDEND(size, convertible, optimize, insn16_on) \
(((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
| ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
-/* Insert new fix. */
-
-static void
-nds32_elf_insert_relocation (struct nds32_relocs_pattern *pattern, unsigned int reloc,
- unsigned int insn_mask, symbolS *sym)
-{
- expressionS exp;
- symbolS *sym_t;
- struct nds32_relocs_pattern *pattern_t;
- int range;
- fragS *frag = pattern->frag;
- char *out = pattern->where;
- unsigned int size = pattern->size;
- static int ptr_count = 0;
-
- exp.X_op = O_symbol;
- exp.X_add_symbol = abs_section_sym;
- exp.X_add_number = 0;
-
- switch (reloc)
- {
- case BFD_RELOC_NDS32_LOADSTORE:
- /* To get the sethi match pattern. */
- range = nds32_elf_sethi_range (pattern->next);
- exp.X_add_number = SET_ADDEND (4 /* size */, 0, optimize, enable_16bit);
- exp.X_add_number |= ((range & 0x3f) << 8);
- fix_new_exp (frag, out - frag->fr_literal, size, &exp, 0 /* pcrel */, reloc);
- break;
-
- case BFD_RELOC_NDS32_PTR:
- pattern_t = pattern->next;
- while (pattern_t)
- {
- if (insn_mask == 0 || pattern_t->insn == insn_mask)
- {
- sym_t = symbol_temp_new (pattern_t->seg,
- pattern_t->where - pattern_t->frag->fr_literal,
- pattern_t->frag);
- exp.X_add_symbol = sym_t;
- fix_new_exp (frag, out - frag->fr_literal, 0, &exp, 0 /* pcrel */, reloc);
- ptr_count++;
- break;
- }
- pattern_t = pattern_t->next;
- }
- break;
-
- case BFD_RELOC_NDS32_PTR_COUNT:
- /* In current design, it only be referanced once. */
- if (ptr_count != 0)
- {
- exp.X_add_number = ptr_count;
- fix_new_exp (frag, out - frag->fr_literal, size, &exp, 0, reloc);
- }
- ptr_count = 0;
- break;
-
- case BFD_RELOC_NDS32_GOTOFF_SUFF:
- case BFD_RELOC_NDS32_GOT_SUFF:
- case BFD_RELOC_NDS32_PLT_GOT_SUFF:
- /* It has to record symbol. */
- if (insn_mask == 0 || pattern->insn == insn_mask)
- {
- exp.X_add_symbol = sym;
- fix_new_exp (frag, out - frag->fr_literal, size, &exp, 0, reloc);
- }
- break;
-
- case BFD_RELOC_NDS32_PTR_RESOLVED:
- default:
- if (insn_mask == 0 || pattern->insn == insn_mask)
- {
- fix_new_exp (frag, out - frag->fr_literal, size, &exp, 0, reloc);
- }
- }
-}
-
static void
nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
{
@@ -4562,58 +4560,525 @@ nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
/* TODO: E_NDS32_HAS_SATURATION_INST */
}
+/* Flag for analysis relaxation type. */
+
+enum nds32_insn_type
+{
+ N32_RELAX_SETHI = 1,
+ N32_RELAX_BR = (1 << 1),
+ N32_RELAX_LSI = (1 << 2),
+ N32_RELAX_JUMP = (1 << 3),
+ N32_RELAX_CALL = (1 << 4),
+ N32_RELAX_ORI = (1 << 5),
+ N32_RELAX_MEM = (1 << 6),
+ N32_RELAX_MOVI = (1 << 7),
+};
+
+struct nds32_hint_map
+{
+ bfd_reloc_code_real_type hi_type;
+ char *opc;
+ enum nds32_relax_hint_type hint_type;
+ enum nds32_br_range range;
+ enum nds32_insn_type insn_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 veriation 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}
+};
+
+/* Find the relaxation pattern according to instructions. */
+
+static bfd_boolean
+nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
+ struct nds32_relax_hint_table *hint_info)
+{
+ unsigned int opcode, seq_size;
+ enum nds32_br_range range;
+ struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
+ char *opc = NULL;
+ relax_info_t *relax_info = NULL;
+ nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
+ enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
+ struct nds32_relax_hint_table *table_ptr;
+ uint32_t *code_seq, *hint_code;
+ enum nds32_insn_type relax_type = 0;
+ struct nds32_hint_map *map_ptr = hint_map;
+ unsigned int i;
+ char *check_insn[] =
+ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+
+ /* TODO: PLT GOT. */
+ /* Traverse all pattern instruction and set flag. */
+ pattern = relocs_pattern;
+ while (pattern)
+ {
+ if (pattern->opcode->isize == 4)
+ {
+ /* 4 byte instruction. */
+ opcode = N32_OP6 (pattern->opcode->value);
+ switch (opcode)
+ {
+ case N32_OP6_SETHI:
+ hi_pattern = pattern;
+ relax_type |= N32_RELAX_SETHI;
+ break;
+ case N32_OP6_MEM:
+ relax_type |= N32_RELAX_MEM;
+ break;
+ case N32_OP6_ORI:
+ relax_type |= N32_RELAX_ORI;
+ break;
+ case N32_OP6_BR1:
+ case N32_OP6_BR2:
+ case N32_OP6_BR3:
+ relax_type |= N32_RELAX_BR;
+ break;
+ case N32_OP6_MOVI:
+ relax_type |= N32_RELAX_MOVI;
+ break;
+ case N32_OP6_LBI:
+ case N32_OP6_SBI:
+ case N32_OP6_LBSI:
+ case N32_OP6_LHI:
+ case N32_OP6_SHI:
+ case N32_OP6_LHSI:
+ case N32_OP6_LWI:
+ case N32_OP6_SWI:
+ case N32_OP6_LWC:
+ case N32_OP6_SWC:
+ relax_type |= N32_RELAX_LSI;
+ break;
+ case N32_OP6_JREG:
+ if (__GF (pattern->opcode->value, 0, 1) == 1)
+ relax_type |= N32_RELAX_CALL;
+ else
+ relax_type |= N32_RELAX_JUMP;
+ break;
+ case N32_OP6_JI:
+ if (__GF (pattern->opcode->value, 24, 1) == 1)
+ relax_type |= N32_RELAX_CALL;
+ else
+ relax_type |= N32_RELAX_JUMP;
+ break;
+ default:
+ as_warn (_("relax hint unrecognized instruction: line %d."),
+ pattern->frag->fr_line);
+ return FALSE;
+ }
+ }
+ 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++)
+ {
+ if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
+ {
+ relax_type |= N32_RELAX_BR;
+ break;
+ }
+ }
+ if (strcmp (pattern->opcode->opcode, "movi55") == 0)
+ relax_type |= N32_RELAX_MOVI;
+ }
+ pattern = pattern->next;
+ }
+
+ /* 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)))
+ {
+ opc = map_ptr->opc;
+ hint_type = map_ptr->hint_type;
+ range = map_ptr->range;
+ break;
+ }
+ map_ptr++;
+ }
+
+ if (map_ptr->insn_list == 0)
+ {
+ as_warn (_("Can not find match relax hint. line : %d"),
+ relocs_pattern->frag->fr_line);
+ return FALSE;
+ }
+
+ /* Get the match table. */
+ if (opc)
+ {
+ /* Branch relax pattern. */
+ relax_info = hash_find (nds32_relax_info_hash, opc);
+ if (!relax_info)
+ return FALSE;
+ fixup_info = relax_info->relax_fixup[range];
+ code_seq = relax_info->relax_code_seq[range];
+ seq_size = relax_info->relax_code_size[range];
+ }
+ else if (hint_type)
+ {
+ /* Load-store relax pattern. */
+ table_ptr = relax_ls_table;
+ while (table_ptr->main_type != 0)
+ {
+ if (table_ptr->main_type == hint_type)
+ {
+ fixup_info = table_ptr->relax_fixup;
+ code_seq = table_ptr->relax_code_seq;
+ seq_size = table_ptr->relax_code_size;
+ break;
+ }
+ table_ptr++;
+ }
+ if (table_ptr->main_type == 0)
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ hint_fixup = hint_info->relax_fixup;
+ hint_code = hint_info->relax_code_seq;
+ hint_info->relax_code_size = seq_size;
+
+ while (fixup_info->size != 0)
+ {
+ if (fixup_info->ramp & NDS32_HINT)
+ {
+ memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
+ hint_fixup++;
+ }
+ fixup_info++;
+ }
+ /* Clear final relocation. */
+ memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
+ /* Copy code sequance. */
+ memcpy (hint_code, code_seq, seq_size);
+ return TRUE;
+}
+
+/* Because there are a lot of variant of load-store, check
+ all these type here. */
+
+#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
+static bfd_boolean
+nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
+{
+ char *check_insn[] =
+ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+ uint32_t insn = opcode->value;
+ unsigned int i;
+
+ insn = CLEAN_REG (opcode->value);
+ if (insn == seq)
+ return TRUE;
+
+ switch (seq)
+ {
+ case OP6 (LBI):
+ /* In relocation_table, it regards instruction LBI as representation
+ of all the NDS32_RELAX_HINT_LS pattern. */
+ 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;
+ break;
+ case OP6 (BR2):
+ /* This is for LONGCALL5 and LONGCALL6. */
+ if (insn == OP6 (BR2))
+ 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;
+ else if (opcode->isize == 2)
+ {
+ for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+ if (strcmp (opcode->opcode, check_insn[i]) == 0)
+ return TRUE;
+ }
+ break;
+ case OP6 (MOVI):
+ /* This is for LONGJUMP7. */
+ if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
/* Append relax relocation for link time relaxing. */
static void
nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
{
- struct nds32_relocs_pattern *relocs_temp =
+ struct nds32_relocs_pattern *relocs_pattern =
(struct nds32_relocs_pattern *) value;
- unsigned int reloc, group_type, insn;
- symbolS *sym;
- unsigned int i = 0, x = 0, y;
+ struct nds32_relocs_pattern *pattern_temp, *pattern_now;
+ symbolS *sym, *hi_sym = NULL;
+ expressionS exp;
+ fragS *fragP;
segT seg_bak = now_seg;
frchainS *frchain_bak = frchain_now;
+ struct nds32_relax_hint_table hint_info;
+ nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
+ size_t fixup_size;
+ offsetT branch_offset;
+ fixS *fixP;
+ int range, offset;
+ unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
+ uint32_t *code_seq, code_insn;
+ char *where;
+
+ if (!relocs_pattern)
+ return;
- if (!relocs_temp)
+ if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
return;
- group_type = relocs_temp->reloc;
- sym = relocs_temp->sym;
+ /* Save symbol for some EMPTY relocation using. */
+ pattern_now = relocs_pattern;
+ while (pattern_now)
+ {
+ if (pattern_now->opcode->value == OP6 (SETHI))
+ {
+ hi_sym = pattern_now->sym;
+ break;
+ }
+ pattern_now = pattern_now->next;
+ }
+
/* Inserting fix up must specify now_seg or frchain_now. */
- now_seg = relocs_temp->seg;
- frchain_now = relocs_temp->frchain;
+ now_seg = relocs_pattern->seg;
+ frchain_now = relocs_pattern->frchain;
+ fragP = relocs_pattern->frag;
+ branch_offset = fragP->fr_offset;
- /* Find pattern in relocation table. */
- while (i < (sizeof (relocation_table)/sizeof (relocation_table[0]))
- &&relocation_table[i].main_type != group_type)
- i++;
+ hint_fixup = hint_info.relax_fixup;
+ code_seq = hint_info.relax_code_seq;
+ relax_code_size = hint_info.relax_code_size;
+ pattern_now = relocs_pattern;
- /* Can not find relocation pattern. */
- if (relocation_table[i].main_type == 0)
- return;
+ /* Insert relaxation. */
+ exp.X_op = O_symbol;
- while (relocs_temp)
+ while (pattern_now)
{
- y = 0;
+ /* Choose the match fixup by instruction. */
+ code_insn = CLEAN_REG (*(code_seq + count));
+ if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
+ {
+ count = 0;
+ code_insn = CLEAN_REG (*(code_seq + count));
- while (relocation_table[i].reloc_insn[x][y][0] != 0)
+ while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
+ {
+ count++;
+ if (count >= relax_code_size / 4)
+ {
+ as_bad (_("Internal error: Relax hint error. %s: %x"),
+ now_seg->name, pattern_now->opcode->value);
+ goto restore;
+ }
+ code_insn = CLEAN_REG (*(code_seq + count));
+ }
+ }
+ fragP = pattern_now->frag;
+ sym = pattern_now->sym;
+ branch_offset = fragP->fr_offset;
+ offset = count * 4;
+ where = pattern_now->where;
+ /* Find the instruction map fix. */
+ fixup_now = hint_fixup;
+ while (fixup_now->offset != offset)
{
- reloc = relocation_table[i].reloc_insn[x][y][0];
- insn = relocation_table[i].reloc_insn[x][y][1];
- nds32_elf_insert_relocation (relocs_temp, reloc, insn, sym);
- y++;
+ fixup_now++;
+ if (fixup_now->size == 0)
+ break;
}
+ /* This element is without relaxation relocation. */
+ if (fixup_now->size == 0)
+ {
+ pattern_now = pattern_now->next;
+ continue;
+ }
+ fixup_size = fixup_now->size;
- /* Next instruction. */
- relocs_temp = relocs_temp->next;
+ /* Insert all fixup. */
+ while (fixup_size != 0 && fixup_now->offset == offset)
+ {
+ /* Set the real instruction size in element. */
+ fixup_size = pattern_now->opcode->isize;
+ if (fixup_now->ramp & NDS32_FIX)
+ {
+ /* Convert original relocation. */
+ pattern_now->fixP->fx_r_type = fixup_now->r_type ;
+ fixup_size = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_PTR) != 0)
+ {
+ /* This relocation has to point to another instruction. Make
+ sure each resolved relocation has to be pointed. */
+ pattern_temp = relocs_pattern;
+ /* All instruction in relax_table should be 32-bit. */
+ hint_count = hint_info.relax_code_size / 4;
+ code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
+ while (pattern_temp)
+ {
+ /* Point to every resolved relocation. */
+ if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
+ {
+ ptr_offset =
+ pattern_temp->where - pattern_temp->frag->fr_literal;
+ exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
+ pattern_temp->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;
+ }
+ pattern_temp = pattern_temp->next;
+ }
+ fixup_size = 0;
+ }
+ else if (fixup_now->ramp & NDS32_ADDEND)
+ {
+ range = nds32_elf_sethi_range (relocs_pattern);
+ if (range == NDS32_LOADSTORE_NONE)
+ {
+ as_bad (_("Internal error: Range error. %s"), now_seg->name);
+ return;
+ }
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
+ exp.X_add_number |= ((range & 0x3f) << 8);
+ }
+ else if ((fixup_now->ramp & NDS32_ABS) != 0)
+ {
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_INSN16) != 0)
+ {
+ if (!enable_16bit)
+ fixup_size = 0;
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_SYM) != 0)
+ {
+ /* For EMPTY relocation save the true symbol. */
+ exp.X_add_symbol = hi_sym;
+ exp.X_add_number = branch_offset;
+ }
+ else
+ {
+ exp.X_add_symbol = sym;
+ exp.X_add_number = branch_offset;
+ }
- /* There are load store instruction shared setting symbol part, so
- re-using the final relocation. */
- if (relocation_table[i].reloc_insn[x+1][0][0] != 0)
- x++;
+ if (fixup_size != 0)
+ {
+ fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+ fixup_size, &exp, 0, fixup_now->r_type);
+ fixP->fx_addnumber = fixP->fx_offset;
+ }
+ fixup_now++;
+ fixup_size = fixup_now->size;
+ }
+ if (count < relax_code_size / 4)
+ count++;
+ pattern_now = pattern_now->next;
}
+restore:
now_seg = seg_bak;
frchain_now = frchain_bak;
}
@@ -4663,12 +5128,12 @@ md_assemble (char *str)
char *out;
struct nds32_pseudo_opcode *popcode;
const struct nds32_field *fld = NULL;
- fixS *fixP ATTRIBUTE_UNUSED;
- int insn_type;
+ fixS *fixP;
uint16_t insn_16;
- uint32_t insn_32;
struct nds32_relocs_pattern *relocs_temp;
expressionS *pexp;
+ fragS *fragP;
+ int label = label_exist;
popcode = nds32_lookup_pseudo_opcode (str);
/* Note that we need to check 'verbatim' and
@@ -4694,6 +5159,7 @@ md_assemble (char *str)
return;
}
+ label_exist = 0;
insn.info = (expressionS *) alloca (sizeof (expressionS));
nds32_assemble (&asm_desc, &insn, str);
@@ -4728,76 +5194,115 @@ md_assemble (char *str)
if (!nds32_check_insn_available (insn, str))
return;
- /* Create new frag if the instruction can be relaxed. */
+ /* Make sure the begining of text being 2-byte align. */
+ nds32_adjust_label (1);
fld = insn.field;
- if (!verbatim && fld && (insn.attr & NASM_ATTR_BRANCH))
+ /* 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))
+ && (!verbatim || pseudo_opcode))
{
/* User assembly code branch relax for it. */
- fragS *fragp = frag_now;
-
/* If fld is not NULL, it is a symbol. */
+ /* Branch msut relax to proper pattern in user assembly code exclude
+ J and JAL. Keep these two in original type for users which wants
+ to keep their size be fixed. In general, assembler does not convert
+ instruction generated by compiler. But jump instruction may be
+ truncated in text virtual model. For workaround, compiler generate
+ pseudo jump to fix this issue currently. */
+
/* Get branch range type. */
+ dwarf2_emit_insn (0);
enum nds32_br_range range_type;
- range_type = get_range_type (fld);
pexp = insn.info;
+ range_type = get_range_type (fld);
- out = frag_var (rs_machine_dependent,
- NDS32_MAXCHAR,
+ out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
0, /* VAR is un-used. */
range_type, /* SUBTYPE is used as range type. */
- pexp->X_add_symbol,
- pexp->X_add_number,
- 0);
- /* If the original frag is full, the instruction must save in next
- one. */
- while (fragp->fr_next != frag_now)
- fragp = fragp->fr_next;
- fragp->fr_fix += insn.opcode->isize;
- fragp->tc_frag_data.opcode = insn.opcode;
- fragp->tc_frag_data.insn = insn.insn;
- dwarf2_emit_insn (insn.opcode->isize);
+ pexp->X_add_symbol, pexp->X_add_number, 0);
+
+ fragP->fr_fix += insn.opcode->isize;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
if (insn.opcode->isize == 4)
bfd_putb32 (insn.insn, out);
else if (insn.opcode->isize == 2)
bfd_putb16 (insn.insn, out);
+ fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
return;
/* md_convert_frag will insert relocations. */
}
- else if (!verbatim && !fld && (optimize || optimize_for_space))
- {
- /* User assembly code without relocating convert it to 16bits if needed. */
- insn_32 = insn.insn;
+ else if (!fld && !relaxing && enable_16bit && (optimize || optimize_for_space)
+ && ((!verbatim && insn.opcode->isize == 4
+ && nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
+ || (insn.opcode->isize == 2
+ && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
+ {
+ /* Record this one is relaxable. */
+ dwarf2_emit_insn (0);
+ out = frag_var (rs_machine_dependent,
+ 4, /* Max size is 32-bit instruction. */
+ 0, /* VAR is un-used. */
+ 0, NULL, 0, NULL);
+ fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
+ fragP->fr_fix += 2;
+
+ /* In original, we don't relax the instrucion with label on it,
+ but this may cause some redundant nop16. Therefore, tag this
+ relaxable instruction and relax it carefully. */
+ if (label)
+ fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
- /* Convert instruction to 16-bits. */
- if (insn.opcode->isize == 4
- && nds32_convert_32_to_16 (stdoutput, insn_32,
- &insn_16, &insn_type))
+ if (insn.opcode->isize == 4)
+ bfd_putb16 (insn_16, out);
+ else if (insn.opcode->isize == 2)
+ bfd_putb16 (insn.insn, out);
+ return;
+ }
+ else if ((verbatim || !relaxing) && optimize && label)
+ {
+ /* This instruction is with label. */
+ expressionS exp;
+ out = frag_var (rs_machine_dependent, insn.opcode->isize,
+ 0, 0, NULL, 0, NULL);
+ /* If this insturction is branch target, it is not relaxable. */
+ fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
+ fragP->fr_fix += insn.opcode->isize;
+ if (insn.opcode->isize == 4)
{
- out = frag_more (2);
- frag_var (rs_fill, 0, 0, 0, NULL, 0, NULL);
- bfd_putb16 (insn_16, out);
- dwarf2_emit_insn (2);
- return;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
}
}
-
- out = frag_more (insn.opcode->isize);
+ else
+ out = frag_more (insn.opcode->isize);
if (insn.opcode->isize == 4)
bfd_putb32 (insn.insn, out);
- else if (insn.opcode->isize == 2)
+ if (insn.opcode->isize == 2)
bfd_putb16 (insn.insn, out);
dwarf2_emit_insn (insn.opcode->isize);
- if (fld)
- {
- /* Compiler generating code and user assembly pseudo load-store, insert
- fixup here. */
- pexp = insn.info;
- nds32_elf_record_fixup_exp (str, fld, pexp, out, &insn);
- }
+ /* Compiler generating code and user assembly pseudo load-store, insert
+ fixup here. */
+ 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);
}
/* md_macro_start */
@@ -4933,10 +5438,17 @@ nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
int i = 0;
/* The instruction has conditions. Collect condition values. */
- while (offset == code_seq_cond[i].offset)
+ while (code_seq_cond[i].bitmask != 0)
{
- mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
- *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
+ if (offset == code_seq_cond[i].offset)
+ {
+ mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
+ /* Sign extend. */
+ if (cond_fields[i].signed_extend)
+ mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
+ ((cond_fields[i].bitmask + 1) >> 1);
+ *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
+ }
i++;
}
}
@@ -4959,8 +5471,6 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
uint32_t *code_seq;
uint32_t insn;
int insn_size;
- uint16_t insn_16;
- int insn_type;
int code_seq_offset;
/* Replace with gas_assert (fragP->fr_symbol != NULL); */
@@ -5023,18 +5533,6 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
while (relax_info->relax_fixup[i][k].size !=0
&& relax_info->relax_fixup[i][k].offset < code_seq_offset)
k++;
- if (relax_info->relax_fixup[i][k].size !=0
- && relax_info->relax_fixup[i][k].ramp & NDS32_ORIGIN)
- {
- /* Set register num to insntruction. */
- nds32_elf_get_set_cond (relax_info, code_seq_offset, &insn,
- fragP->tc_frag_data.insn, i);
-
- /* Try to convert to 16-bits instruction. */
- if (nds32_convert_32_to_16 (stdoutput,
- insn, &insn_16, &insn_type))
- diff -= 2;
- }
}
code_seq_offset += insn_size;
@@ -5050,6 +5548,89 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
return diff + adjust;
}
+/* Adjust relaxable frag till current frag. */
+
+static int
+nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
+{
+ int adj;
+ if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
+ adj = -2;
+ else
+ adj = 2;
+
+ startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
+
+ while (startP)
+ {
+ startP = startP->fr_next;
+ if (startP)
+ {
+ startP->fr_address += adj;
+ if (startP == fragP)
+ break;
+ }
+ }
+ return adj;
+}
+
+static addressT
+nds32_get_align (addressT address, int align)
+{
+ addressT mask, new_address;
+
+ mask = ~((~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)
+{
+ addressT address;
+ fragS *frag_start = *prev_frag;
+
+ if (!frag_start)
+ return;
+
+ if (frag_start->last_fr_address >= fragP->last_fr_address)
+ {
+ *prev_frag = NULL;
+ return;
+ }
+
+ fragS *frag_t = *prev_frag;
+ while (frag_t != fragP)
+ {
+ if (frag_t->fr_type == rs_align
+ || frag_t->fr_type == rs_align_code
+ || frag_t->fr_type == rs_align_test)
+ {
+ /* Relax instruction can not walk across lable. */
+ if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ {
+ prev_frag = NULL;
+ return;
+ }
+ /* Relax previos relaxable to align rs_align frag. */
+ address = frag_t->fr_address + frag_t->fr_fix;
+ addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
+ if (offset & 0x2)
+ {
+ /* If there is label on the prev_frag, check if it is aligned. */
+ if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
+ & 0x2) == 0)
+ nds32_adjust_relaxable_frag (*prev_frag, frag_t);
+ }
+ *prev_frag = NULL;
+ return;
+ }
+ frag_t = frag_t->fr_next;
+ }
+}
+
/* md_relax_frag */
int
@@ -5059,9 +5640,21 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
1. relax for branch
2. relax for 32-bits to 16-bits */
- int adjust;
+ static fragS *prev_frag = NULL;
+ int adjust = 0;
+
+ invalid_prev_frag (fragP, &prev_frag);
- adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
+ adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ prev_frag = NULL;
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
+ && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
+ /* Here is considered relaxed case originally. But it may cause
+ unendless loop when relaxing. Once the instruction is relaxed,
+ it can not be undo. */
+ prev_frag = fragP;
return adjust;
}
@@ -5083,9 +5676,20 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
1. relax for branch
2. relax for 32-bits to 16-bits */
- int adjust;
+ /* Save previos relaxable frag. */
+ static fragS *prev_frag = NULL;
+ int adjust = 0;
+
+ invalid_prev_frag (fragP, &prev_frag);
- adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
+ adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ prev_frag = NULL;
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
+ adjust = 2;
+ else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
+ prev_frag = fragP;
return adjust;
}
@@ -5115,26 +5719,21 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
char *fr_buffer;
int fr_where;
int addend ATTRIBUTE_UNUSED;
- offsetT branch_target_address;
- offsetT branch_insn_address;
+ offsetT branch_target_address, branch_insn_address;
expressionS exp;
fixS *fixP;
uint32_t *code_seq;
- int code_size;
uint32_t insn;
- int insn_size;
- int offset;
- int i, j, k;
- uint16_t insn_16;
- int insn_type;
+ int code_size, insn_size, offset, fixup_size;
int buf_offset;
- nds32_relax_fixup_info_t fixup_info[MAX_RELAX_NUM];
+ int i, k;
+ uint16_t insn_16;
+ nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
/* Save the 1st instruction is converted to 16 bit or not. */
- bfd_boolean insn_convert = FALSE;
- int fixup_size;
+ unsigned int branch_size;
/* Replace with gas_assert (branch_symbol != NULL); */
- if (branch_symbol == NULL)
+ if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
return;
/* If frag_var is not enough room, the previos frag is fr_full and with
@@ -5142,142 +5741,150 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
if (opcode == NULL)
return;
- relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
-
- if (relax_info == NULL)
- return;
-
- backup_endian = target_big_endian;
- target_big_endian = 1;
-
- fr_where = fragP->fr_fix - opcode->isize;
- fr_buffer = fragP->fr_literal + fr_where;
-
- if ((S_GET_SEGMENT (branch_symbol) != sec)
- || S_IS_WEAK (branch_symbol))
+ /* Relax the insntruction. */
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
{
- if (fragP->fr_offset & 3)
- as_warn (_("Addend to unresolved symbol is not on word boundary."));
- addend = 0;
+ expressionS exp_t;
+ if (fragP->tc_frag_data.opcode->isize == 2)
+ {
+ insn_16 = fragP->tc_frag_data.insn;
+ nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
+ }
+ else
+ insn = fragP->tc_frag_data.insn;
+ fragP->fr_fix += 2;
+ fr_where = fragP->fr_fix - 4;
+ fr_buffer = fragP->fr_literal + fr_where;
+ exp_t.X_op = O_symbol;
+ exp_t.X_add_symbol = abs_section_sym;
+ exp_t.X_add_number = 0;
+ fix_new_exp (fragP, fr_where, 4, &exp_t, 0,
+ BFD_RELOC_NDS32_INSN16);
+ number_to_chars_bigendian (fr_buffer, insn, 4);
}
else
{
- /* Calculate symbol-to-instruction offset. */
- branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
- branch_insn_address = fragP->fr_address + fr_where;
- addend = (branch_target_address - branch_insn_address) >> 1;
- }
+ /* Branch instruction adjust and append relocations. */
+ relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
- code_size = relax_info->relax_code_size[branch_range_type];
- code_seq = relax_info->relax_code_seq[branch_range_type];
+ if (relax_info == NULL)
+ return;
- memcpy (fixup_info,
- relax_info->relax_fixup[branch_range_type],
- sizeof (fixup_info));
+ backup_endian = target_big_endian;
+ target_big_endian = 1;
- /* Fill in frag. */
- i = 0;
- k = 0;
- offset = 0; /* code_seq offset */
- buf_offset = 0; /* fr_buffer offset */
- while (offset < code_size)
- {
- insn = code_seq[i];
- if (insn & 0x80000000) /* 16-bits instruction. */
+ fr_where = fragP->fr_fix - opcode->isize;
+ fr_buffer = fragP->fr_literal + fr_where;
+
+ if ((S_GET_SEGMENT (branch_symbol) != sec)
+ || S_IS_WEAK (branch_symbol))
{
- insn = (insn >> 16) & 0xFFFF;
- insn_size = 2;
+ if (fragP->fr_offset & 3)
+ as_warn (_("Addend to unresolved symbol is not on word boundary."));
+ addend = 0;
}
- else /* 32-bits instruction. */
+ else
{
- insn_size = 4;
+ /* Calculate symbol-to-instruction offset. */
+ branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
+ branch_insn_address = fragP->fr_address + fr_where;
+ addend = (branch_target_address - branch_insn_address) >> 1;
}
- nds32_elf_get_set_cond (relax_info, offset, &insn,
- origin_insn, branch_range_type);
+ code_size = relax_info->relax_code_size[branch_range_type];
+ code_seq = relax_info->relax_code_seq[branch_range_type];
- /* Try to convert to 16-bits instruction. Currently, only the first
- insntruction in pattern can be converted. EX: bnez sethi ori jr,
- only bnez can be converted to 16 bit and ori can't. */
+ memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
+ sizeof (fixup_info));
- while (fixup_info[k].size != 0
- && relax_info->relax_fixup[branch_range_type][k].offset < offset)
- k++;
- if ((fixup_info[k].size != 0
- && fixup_info[k].ramp & NDS32_ORIGIN)
- && nds32_convert_32_to_16 (stdoutput, insn, &insn_16, &insn_type))
+ /* Fill in frag. */
+ i = 0;
+ k = 0;
+ offset = 0; /* code_seq offset */
+ buf_offset = 0; /* fr_buffer offset */
+ while (offset < code_size)
{
- /* Reduce to 16-bits instructions, adjust fixup_info[j]->offset. */
- for (j = 0; fixup_info[j].size != 0; j++)
+ insn = code_seq[i];
+ if (insn & 0x80000000) /* 16-bits instruction. */
{
- if (fixup_info[j].ramp & NDS32_RELAX)
- fixup_info[j].size -= 2;
-
- if (fixup_info[j].offset > buf_offset)
- fixup_info[j].offset -= 2;
+ insn = (insn >> 16) & 0xFFFF;
+ insn_size = 2;
+ }
+ else /* 32-bits instruction. */
+ {
+ insn_size = 4;
}
- md_number_to_chars (fr_buffer + buf_offset, insn_16, 2);
- buf_offset += 2;
- if (offset == 0)
- insn_convert = TRUE;
- }
- else
- {
- md_number_to_chars (fr_buffer + buf_offset, insn, insn_size);
- buf_offset += insn_size;
- }
-
- offset += insn_size;
- i++;
- }
+ nds32_elf_get_set_cond (relax_info, offset, &insn,
+ origin_insn, branch_range_type);
- /* Set up fixup. */
- exp.X_op = O_symbol;
+ /* Try to convert to 16-bits instruction. Currently, only the first
+ insntruction in pattern can be converted. EX: bnez sethi ori jr,
+ only bnez can be converted to 16 bit and ori can't. */
- for (i = 0; fixup_info[i].size != 0; i++)
- {
- fixup_size = fixup_info[i].size;
+ while (fixup_info[k].size != 0
+ && relax_info->relax_fixup[branch_range_type][k].offset < offset)
+ k++;
- if (((fixup_info[i].ramp & NDS32_ORIGIN) && insn_convert == TRUE)
- ||((fixup_info[i].ramp & NDS32_CONVERT) && insn_convert == FALSE))
- continue;
+ md_number_to_chars (fr_buffer + buf_offset, insn, insn_size);
+ buf_offset += insn_size;
- if ((fixup_info[i].ramp & NDS32_CREATE_LABLE) != 0)
- {
- /* This is a reverse branch. */
- exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
- exp.X_add_number = 0;
- }
- else if ((fixup_info[i].ramp & NDS32_RELAX) != 0)
- {
- /* This is a relax relocation. */
- exp.X_add_symbol = abs_section_sym;
- exp.X_add_number =
- SET_ADDEND (fixup_size /* size */ ,
- insn_convert , optimize, enable_16bit);
- }
- else
- {
- exp.X_add_symbol = branch_symbol;
- exp.X_add_number = branch_offset;
+ offset += insn_size;
+ i++;
}
- if (fixup_info[i].r_type != 0)
+ /* Set up fixup. */
+ exp.X_op = O_symbol;
+
+ for (i = 0; fixup_info[i].size != 0; i++)
{
- fixP = fix_new_exp (fragP,
- fr_where + fixup_info[i].offset,
- fixup_size,
- &exp,
- 0,
- fixup_info[i].r_type);
- fixP->fx_addnumber = fixP->fx_offset;
+ fixup_size = fixup_info[i].size;
+
+ if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
+ {
+ /* This is a reverse branch. */
+ exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
+ {
+ /* This relocation has to point to another instruction. */
+ branch_size = fr_where + code_size - 4;
+ exp.X_add_symbol = symbol_temp_new (sec, branch_size, fragP);
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
+ {
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
+ {
+ if (!enable_16bit)
+ continue;
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else
+ {
+ exp.X_add_symbol = branch_symbol;
+ exp.X_add_number = branch_offset;
+ }
+
+ if (fixup_info[i].r_type != 0)
+ {
+ fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
+ fixup_size, &exp, 0, fixup_info[i].r_type);
+ fixP->fx_addnumber = fixP->fx_offset;
+ }
}
- }
- fragP->fr_fix = fr_where + buf_offset;
+ fragP->fr_fix = fr_where + buf_offset;
- target_big_endian = backup_endian;
+ target_big_endian = backup_endian;
+ }
}
/* tc_frob_file_before_fix */
@@ -5287,15 +5894,62 @@ nds32_frob_file_before_fix (void)
{
}
-/* TC_FORCE_RELOCATION */
-
-int
-nds32_force_relocation (fixS *fix ATTRIBUTE_UNUSED)
+static bfd_boolean
+nds32_relaxable_section (asection *sec)
{
- /* Always force relocation, because linker may adjust the code. */
- return 1;
+ return ((sec->flags & SEC_DEBUGGING) == 0
+ && strcmp (sec->name, ".eh_frame") != 0);
}
+/* TC_FORCE_RELOCATION */
+int
+nds32_force_relocation (fixS * fix)
+{
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_NDS32_INSN16:
+ case BFD_RELOC_NDS32_LABEL:
+ case BFD_RELOC_NDS32_LONGCALL1:
+ case BFD_RELOC_NDS32_LONGCALL2:
+ case BFD_RELOC_NDS32_LONGCALL3:
+ case BFD_RELOC_NDS32_LONGJUMP1:
+ case BFD_RELOC_NDS32_LONGJUMP2:
+ case BFD_RELOC_NDS32_LONGJUMP3:
+ case BFD_RELOC_NDS32_LOADSTORE:
+ case BFD_RELOC_NDS32_9_FIXED:
+ case BFD_RELOC_NDS32_15_FIXED:
+ case BFD_RELOC_NDS32_17_FIXED:
+ case BFD_RELOC_NDS32_25_FIXED:
+ case BFD_RELOC_NDS32_9_PCREL:
+ case BFD_RELOC_NDS32_15_PCREL:
+ case BFD_RELOC_NDS32_17_PCREL:
+ case BFD_RELOC_NDS32_WORD_9_PCREL:
+ case BFD_RELOC_NDS32_10_UPCREL:
+ case BFD_RELOC_NDS32_25_PCREL:
+ case BFD_RELOC_NDS32_MINUEND:
+ case BFD_RELOC_NDS32_SUBTRAHEND:
+ return 1;
+
+ case BFD_RELOC_8:
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_NDS32_DIFF_ULEB128:
+ /* Linker should handle difference between two symbol. */
+ return fix->fx_subsy != NULL
+ && nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
+ case BFD_RELOC_64:
+ if (fix->fx_subsy)
+ as_bad ("Double word for difference between two symbols "
+ "is not supported across relaxation.");
+ default:
+ ;
+ }
+
+ if (generic_force_reloc (fix))
+ return 1;
+
+ return fix->fx_pcrel;
+}
/* TC_VALIDATE_FIX_SUB */
@@ -5446,7 +6100,7 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
fixS *fixp;
seginfo = seg_info (sec);
- if (!seginfo || !symbol_rootP || !subseg_text_p (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. */
@@ -5547,8 +6201,8 @@ nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
{
bfd *abfd ATTRIBUTE_UNUSED = sec->owner;
if (bfd_get_section_flags (abfd, sec) & (flagword) SEC_RELOC)
- nds32_insertion_sort (sec->orelocation, sec->reloc_count, sizeof (arelent**),
- compar_relent);
+ nds32_insertion_sort (sec->orelocation, sec->reloc_count,
+ sizeof (arelent**), compar_relent);
}
long
@@ -5573,8 +6227,6 @@ nds32_post_relax_hook (void)
bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
}
-
-
/* tc_fix_adjustable ()
Return whether this symbol (fixup) can be replaced with
@@ -5596,6 +6248,13 @@ nds32_fix_adjustable (fixS *fixP)
case BFD_RELOC_16:
case BFD_RELOC_32:
case BFD_RELOC_NDS32_PTR:
+ case BFD_RELOC_NDS32_LONGCALL4:
+ case BFD_RELOC_NDS32_LONGCALL5:
+ case BFD_RELOC_NDS32_LONGCALL6:
+ case BFD_RELOC_NDS32_LONGJUMP4:
+ case BFD_RELOC_NDS32_LONGJUMP5:
+ case BFD_RELOC_NDS32_LONGJUMP6:
+ case BFD_RELOC_NDS32_LONGJUMP7:
return 1;
default:
return 0;
@@ -5607,13 +6266,14 @@ nds32_fix_adjustable (fixS *fixP)
void
elf_nds32_final_processing (void)
{
- /* An FPU_COM instruction is found without previous non-FPU_COM instruction. */
+ /* An FPU_COM instruction is found without previous non-FPU_COM
+ instruction. */
if (nds32_fpu_com
&& !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
{
/* Since only FPU_COM instructions are used and no other FPU instructions
- are used. The nds32_elf_flags will be decided by the enabled options by
- command line or default configuration. */
+ are used. The nds32_elf_flags will be decided by the enabled options
+ by command line or default configuration. */
if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
{
nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
@@ -5658,21 +6318,37 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
&& fixP->fx_r_type > BFD_RELOC_NONE
&& fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
{
- /* FIXME: This implementation is partially borrowed from our old
- nds32 binutils. Its purpose is to leave original bfd
- relocation untouched, while other relocation created by CGEN
- will be converted into general bfd relocations.
- However, since we no longer use CGEN, we can simply use
- a little piece of code to deal with general bfd relocation,
- especially for the BFD_RELOC_NDS32_DATA, which is just used
- as a marker for different purpose.
- It is believed that we can construct a better mechanism to
- deal with the whole relocation issue in nds32 target
- without using CGEN. */
+ /* In our old nds32 binutils, it must convert relocations which is
+ generated by CGEN. However, it does not have to consider this anymore.
+ In current, it only deal with data relocations which enum
+ is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
+ It is believed that we can construct a better mechanism to
+ deal with the whole relocation issue in nds32 target
+ without using CGEN. */
fixP->fx_addnumber = value;
fixP->tc_fix_data = NULL;
- if (fixP->fx_r_type == BFD_RELOC_NDS32_DATA)
- fixP->fx_done = 1;
+
+ /* Tranform specific relocations here for later relocation generation.
+ Tag data here for ex9 relaxtion and tag tls data for linker. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_NDS32_DATA:
+ if (!enable_relax_ex9)
+ fixP->fx_done = 1;
+ break;
+ case BFD_RELOC_NDS32_TPOFF:
+ case BFD_RELOC_NDS32_TLS_LE_HI20:
+ case BFD_RELOC_NDS32_TLS_LE_LO12:
+ case BFD_RELOC_NDS32_TLS_LE_ADD:
+ case BFD_RELOC_NDS32_TLS_LE_LS:
+ case BFD_RELOC_NDS32_GOTTPOFF:
+ case BFD_RELOC_NDS32_TLS_IE_HI20:
+ case BFD_RELOC_NDS32_TLS_IE_LO12S2:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ default:
+ break;
+ }
return;
}
@@ -5772,7 +6448,8 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
/* cvt_frag_to_fill () has called output_leb128 () for us. */
break;
default:
- as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("expression too complex"));
return;
}
}
@@ -5796,7 +6473,8 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Internal error: Unknown fixup type %d (`%s')"),
- fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
+ fixP->fx_r_type,
+ bfd_get_reloc_code_name (fixP->fx_r_type));
break;
}
}
@@ -5847,6 +6525,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
return reloc;
}
+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}
+};
+
/* Implement md_parse_name. */
int
@@ -5854,35 +6541,32 @@ nds32_parse_name (char const *name, expressionS *exprP,
enum expr_mode mode ATTRIBUTE_UNUSED,
char *nextcharP ATTRIBUTE_UNUSED)
{
- char *suffix_table[] = { "GOTOFF", "GOT", "PLT" };
- short unsigned int reloc_table [] =
- {
- BFD_RELOC_NDS32_GOTOFF, BFD_RELOC_NDS32_GOT20,
- BFD_RELOC_NDS32_25_PLTREL
- };
- segT segment;
-
exprP->X_op_symbol = NULL;
exprP->X_md = BFD_RELOC_UNUSED;
exprP->X_add_symbol = symbol_find_or_make (name);
+ exprP->X_op = O_symbol;
+ exprP->X_add_number = 0;
- segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (segment != undefined_section)
- return 0;
-
- if (*nextcharP == '@')
+ if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
+ {
+ /* Set for _GOT_OFFSET_TABLE_. */
+ exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
+ }
+ else if (*nextcharP == '@')
{
size_t i;
char *next;
for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
{
- next = input_line_pointer + 1 + strlen (suffix_table[i]);
- if (strncasecmp (input_line_pointer + 1, suffix_table[i],
- strlen (suffix_table[i])) == 0
+ 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))
{
- exprP->X_md = reloc_table[i];
+ 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;
*nextcharP = *input_line_pointer;
@@ -5891,10 +6575,6 @@ nds32_parse_name (char const *name, expressionS *exprP,
}
}
}
-
- exprP->X_op = O_symbol;
- exprP->X_add_number = 0;
-
return 1;
}
@@ -5903,18 +6583,18 @@ nds32_parse_name (char const *name, expressionS *exprP,
int
tc_nds32_regname_to_dw2regnum (char *regname)
{
- symbolS *sym = symbol_find (regname);
+ struct nds32_keyword *sym = hash_find (nds32_gprs_hash, regname);
+
+ if (!sym)
+ return -1;
- if (S_GET_SEGMENT (sym) == reg_section
- && sym->sy_value.X_add_number < 32)
- return sym->sy_value.X_add_number;
- return -1;
+ return sym->value;
}
void
tc_nds32_frame_initial_instructions (void)
{
/* CIE */
- /* Default cfa is register-28/sp. */
+ /* Default cfa is register-31/sp. */
cfi_add_CFA_def_cfa (31, 0);
}
diff --git a/gas/config/tc-nds32.h b/gas/config/tc-nds32.h
index 731bb87..1483d51 100644
--- a/gas/config/tc-nds32.h
+++ b/gas/config/tc-nds32.h
@@ -42,10 +42,6 @@
#define TARGET_BYTES_BIG_ENDIAN 1
#endif
-/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
- symbols. The relocation type is stored in X_md. */
-#define O_PIC_reloc O_md1
-
/* as.c. */
/* Extend GAS command line option handling capability. */
extern int nds32_parse_option (int, char *);
@@ -154,6 +150,12 @@ extern void nds32_do_align (int);
#define LOCAL_LABELS_FB 1 /* Permit temporary numeric labels. */
/* frags.c. */
+
+#define NDS32_FRAG_RELAXABLE 0x1
+#define NDS32_FRAG_RELAXED 0x2
+#define NDS32_FRAG_BRANCH 0x4
+#define NDS32_FRAG_LABEL 0x8
+
struct nds32_frag_type
{
relax_substateT flag;
@@ -211,10 +213,16 @@ enum nds32_br_range
enum nds32_ramp
{
- NDS32_CREATE_LABLE = 1,
- NDS32_RELAX = 2,
- NDS32_ORIGIN = 4,
- NDS32_CONVERT = 8
+ NDS32_CREATE_LABEL = 1,
+ NDS32_RELAX = (1 << 1), /* Obsolete in the future. */
+ NDS32_ORIGIN = (1 << 2),
+ NDS32_INSN16 = (1 << 3),
+ NDS32_PTR = (1 << 4),
+ NDS32_ABS = (1 << 5),
+ NDS32_HINT = (1 << 6),
+ NDS32_FIX = (1 << 7),
+ NDS32_ADDEND = (1 << 8),
+ NDS32_SYM = (1 << 9)
};
typedef struct nds32_relax_fixup_info
@@ -231,13 +239,15 @@ typedef struct nds32_cond_field
int offset;
int bitpos; /* Register position. */
int bitmask; /* Number of register bits. */
+ bfd_boolean signed_extend;
} nds32_cond_field_t;
/* The max relaxation pattern is 20-bytes including the nop. */
#define NDS32_MAXCHAR 20
/* In current, the max entend number of instruction for one pseudo instruction
- is 4, but its number of relocation may be 5. */
-#define MAX_RELAX_NUM 8
+ is 4, but its number of relocation may be 12. */
+#define MAX_RELAX_NUM 4
+#define MAX_RELAX_FIX 12
typedef struct nds32_relax_info
{
@@ -248,17 +258,24 @@ typedef struct nds32_relax_info
/* Code sequences for different branch range. */
uint32_t relax_code_seq[BR_RANGE_NUM][MAX_RELAX_NUM];
nds32_cond_field_t relax_code_condition[BR_RANGE_NUM][MAX_RELAX_NUM];
- int relax_code_size[BR_RANGE_NUM];
+ unsigned int relax_code_size[BR_RANGE_NUM];
int relax_branch_isize[BR_RANGE_NUM];
- nds32_relax_fixup_info_t relax_fixup[BR_RANGE_NUM][MAX_RELAX_NUM];
+ nds32_relax_fixup_info_t relax_fixup[BR_RANGE_NUM][MAX_RELAX_FIX];
} relax_info_t;
-/* Relocation table. */
-struct nds32_relocation_map
+enum nds32_relax_hint_type
+{
+ NDS32_RELAX_HINT_NONE = 0,
+ NDS32_RELAX_HINT_LA,
+ NDS32_RELAX_HINT_LS
+};
+
+struct nds32_relax_hint_table
{
- unsigned int main_type;
- /* Number of instructions, {relocations type, instruction type}. */
- unsigned int reloc_insn[6][6][3];
+ enum nds32_relax_hint_type main_type;
+ unsigned int relax_code_size;
+ uint32_t relax_code_seq[MAX_RELAX_NUM];
+ nds32_relax_fixup_info_t relax_fixup[MAX_RELAX_FIX];
};
#endif /* TC_NDS32 */