gas/riscv: Produce version 3 DWARF CIE by default
[deliverable/binutils-gdb.git] / gas / config / tc-nds32.c
index b2741b82139b8833bdc708df73c83a9b610b0dc4..a75dd9ada9c89c3bc9ab89a5356db2d125f2a56c 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-nds32.c -- Assemble for the nds32
 /* tc-nds32.c -- Assemble for the nds32
-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+   Copyright (C) 2012-2019 Free Software Foundation, Inc.
    Contributed by Andes Technology Corporation.
 
    This file is part of GAS, the GNU Assembler.
    Contributed by Andes Technology Corporation.
 
    This file is part of GAS, the GNU Assembler.
 #include "hash.h"
 #include "sb.h"
 #include "macro.h"
 #include "hash.h"
 #include "sb.h"
 #include "macro.h"
-#include "struc-symbol.h"
 #include "opcode/nds32.h"
 
 #include <stdio.h>
 #include "opcode/nds32.h"
 
 #include <stdio.h>
+#include <errno.h>
+#include <limits.h>
 
 /* GAS definitions.  */
 
 
 /* GAS definitions.  */
 
@@ -66,6 +67,8 @@ struct nds32_relocs_pattern
   struct nds32_opcode *opcode;
   char *where;
   struct nds32_relocs_pattern *next;
   struct nds32_opcode *opcode;
   char *where;
   struct nds32_relocs_pattern *next;
+  /* Assembled instruction bytes.  */
+  uint32_t insn;
 };
 
 /* Suffix name and relocation.  */
 };
 
 /* Suffix name and relocation.  */
@@ -73,7 +76,6 @@ struct suffix_name
 {
   const char *suffix;
   short unsigned int reloc;
 {
   const char *suffix;
   short unsigned int reloc;
-  int pic;
 };
 static int vec_size = 0;
 /* If the assembly code is generated by compiler, it is supposed to have
 };
 static int vec_size = 0;
 /* If the assembly code is generated by compiler, it is supposed to have
@@ -87,10 +89,6 @@ static struct hash_control *nds32_hint_hash;
 
 /* Generate relocation for relax or not, and the default is true.  */
 static int enable_relax_relocs = 1;
 
 /* Generate relocation for relax or not, and the default is true.  */
 static int enable_relax_relocs = 1;
-/* The value will be used in RELAX_ENTRY.  */
-static int enable_relax_ex9 = 0;
-/* The value will be used in RELAX_ENTRY.  */
-static int enable_relax_ifc = 0;
 /* Save option -O for performance.  */
 static int optimize = 0;
 /* Save option -Os for code size.  */
 /* Save option -O for performance.  */
 static int optimize = 0;
 /* Save option -Os for code size.  */
@@ -102,61 +100,86 @@ 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;
 extern struct nds32_keyword keyword_gpr[];
 /* Tag there is relax relocation having to link.  */
 static bfd_boolean relaxing = FALSE;
+/* ICT model.  */
+enum ict_option {
+  ICT_NONE = 0,
+  ICT_SMALL,
+  ICT_LARGE
+};
+static enum ict_option ict_flag = ICT_NONE;
 \f
 \f
+
 static struct hash_control *nds32_relax_info_hash;
 static struct hash_control *nds32_relax_info_hash;
+
+/* Branch patterns.  */
 static relax_info_t relax_table[] =
 {
   {
 static relax_info_t relax_table[] =
 {
   {
-    "jal",                                     /* opcode */
-    BR_RANGE_S16M,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "jal",
+    .br_range = BR_RANGE_S16M,
+    .cond_field =
       {
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16K */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA
-      }, /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 4, 12},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 4,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -164,169 +187,213 @@ static relax_info_t relax_table[] =
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bltzal",                                  /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BLTZAL /* bltzal $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BLTZAL /* bltzal $rt, label */
-      }, /* BR_RANGE_S16K */
+    .opcode = "bgezal",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+         INSN_BGEZAL   /* bgezal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BLTZAL /* bltzal $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-       INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZAL     /* bgezal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-       INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA /* jral $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BGEZAL     /* bgezal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
        {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
        {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
   },
   {
-    "bgezal",                                  /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BGEZAL /* bgezal $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BGEZAL /* bgezal $rt, label */
-      }, /* BR_RANGE_S16K */
+    .opcode = "bltzal",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+         INSN_BLTZAL   /* bltzal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BGEZAL /* bgezal $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_BLTZAL     /* bltzal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA /* jral $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BLTZAL     /* bltzal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
        {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -334,60 +401,74 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "j",                                       /* opcode */
-    BR_RANGE_S16M,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "j",
+    .br_range = BR_RANGE_S16M,
+    .cond_field =
       {
       {
-        (INSN_J8 << 16) /* j8 label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16K */
+       (INSN_J8 << 16) /* j8 label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_J          /* j label */
+      },
+    . relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      }, /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 4, 12},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 4,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -395,60 +476,74 @@ static relax_info_t relax_table[] =
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "j8",                                      /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "j8",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
       {
       {
-        (INSN_J8 << 16) /* j8 label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16K */
+       (INSN_J8 << 16) /* j8 label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      }, /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 4, 12},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
+      {
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 4,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -456,85 +551,113 @@ static relax_info_t relax_table[] =
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beqz",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "beqz",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    /* We do not use beqz38 and beqzs8 here directly because we
+       don't want to check register number for specail condition.  */
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+         INSN_BEQZ     /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
       {
        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
+      {
+       /* bnez range is 17 pcrel, but it use 15 pcrel here since link time
+          relaxtion.  If 17 pcrel can reach, it do not have to use S16M.
+          Therefore, 15 pcrel is just for linker to distinguish LONGJUMP5
+          and LONGJUMP6.  */
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -544,83 +667,104 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
   },
   {
-    "bgez",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BGEZ /* bgez $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "bgez",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BGEZ       /* bgez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BGEZ /* bgez $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BGEZ /* bgez $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BGEZ       /* bgez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZ       /* bgez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -630,85 +774,107 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bnez",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
+    .opcode = "bnez",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
       {
        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -719,82 +885,104 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bgtz",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
+    .opcode = "bgtz",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BGTZ       /* bgtz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BGTZ /* bgtz $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BGTZ /* bgtz $rt, label */
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BGTZ /* bgtz $rt, label */
-      }, /* BR_RANGE_S64K */
+       INSN_BGTZ       /* bgtz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BLEZ, /* blez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_BLEZ, /* blez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BGTZ       /* bgtz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BLEZ,      /* blez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BLEZ,      /* blez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -804,82 +992,104 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "blez",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
-      {
-        INSN_BLEZ /* blez $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "blez",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BLEZ       /* blez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BLEZ /* blez $rt, label */
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BLEZ /* blez $rt, label */
-      }, /* BR_RANGE_S64K */
+       INSN_BLEZ       /* blez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BGTZ, /* bgtz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_BGTZ, /* bgtz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BLEZ       /* blez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGTZ,      /* bgtz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BGTZ,      /* bgtz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -889,82 +1099,104 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bltz",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "bltz",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S64K */
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {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},
@@ -974,97 +1206,118 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beq",                                     /* opcode */
-    BR_RANGE_S16K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 15, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQ /* beq $rt, $ra, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BEQ /* beq $rt, $ra, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+    .opcode = "beq",
+    .br_range = BR_RANGE_S16K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQ        /* beq $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQ        /* beq $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-       {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1075,96 +1328,118 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bne",                                     /* opcode */
-    BR_RANGE_S16K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 15, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
-      {
-        INSN_BNE /* bne $rt, $ra, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNE /* bne $rt, $ra, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+    .opcode = "bne",
+    .br_range = BR_RANGE_S16K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNE        /* bne $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BNE        /* bne $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQ,       /* beq $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BEQ,       /* beq $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQ,       /* beq $rt, $ra, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1175,84 +1450,106 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beqz38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
-      {
-        INSN_BEQZ38 << 16 /* beqz $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+    .opcode = "beqz38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQZ38 << 16       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1263,84 +1560,106 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bnez38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
+    .opcode = "bnez38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNEZ38 << 16       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BNEZ38 << 16 /* bnez $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1351,66 +1670,80 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beqzs8",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "beqzs8",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
       {
       {
-        INSN_BEQZS8 << 16 /* beqz $r15, label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
       {
-        INSN_BEQZ_TA /* bnez $rt, label */
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZS8 << 16       /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BEQZ_TA /* bnez $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BNEZ_TA, /* bnez $r15, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ_TA    /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_BNEZ_TA, /* bnez $r15, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQZ_TA    /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BNEZ_TA,   /* bnez $r15, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BNEZ_TA,   /* bnez $r15, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1420,67 +1753,81 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
   },
   {
-    "bnezs8",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "bnezs8",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
       {
       {
-        INSN_BNEZS8 << 16 /* bnez $r15, label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
       {
-        INSN_BNEZ_TA /* bnez $r15, label */
-      }, /* BR_RANGE_S16K */
+       INSN_BNEZS8 << 16       /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        INSN_BNEZ_TA /* bnez $r15, label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BEQZ_TA, /* beqz $r15, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_BNEZ_TA    /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        INSN_BEQZ_TA, /* beqz $r15, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNEZ_TA    /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQZ_TA,   /* beqz $r15, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BEQZ_TA,   /* beqz $r15, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1491,89 +1838,111 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "bnes38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BNES38 << 16 /* bne $rt, $R5, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNE_R5 /* bne $rt, $R5, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQ_R5, /* beq $rt, $R5, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQ_R5, /* beq $rt, $R5, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQ_R5, /* beq $rt, $R5, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+    .opcode = "bnes38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNES38 << 16       /* bne $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BNE_R5     /* bne $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 8, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQ_R5,    /* beq $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BEQ_R5,    /* beq $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQ_R5,    /* beq $rt, $r5, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1584,89 +1953,111 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beqs38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQS38 << 16 /* beq $rt, $R5, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BEQ_R5 /* beq $rt, $R5, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNE_R5, /* bne $rt, $R5, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNE_R5, /* bne $rt, $R5, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNE_R5, /* bne $rt, $R5, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+    .opcode = "beqs38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQS38 << 16       /* beq $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQ_R5     /* beq $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 8, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNE_R5,    /* bne $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNE_R5,    /* bne $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BNE_R5,    /* bne $rt, $r5, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {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},
@@ -1677,191 +2068,238 @@ static relax_info_t relax_table[] =
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
   },
   {
-    "beqc",                                    /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7FF, TRUE},
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQC /* beqc $rt, imm11s, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_MOVI_TA, /* movi $ta, imm11s */
-        INSN_BEQ_TA /* beq $rt, $ta, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNEC, /* bnec $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
+    .opcode = "beqc",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7FF, TRUE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQC       /* beqc $rt, imm11s, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BNEC, /* bnec $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_MOVI_TA,   /* movi $ta, imm11s */
+       INSN_BEQ_TA     /* beq $rt, $ta, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BNEC, /* bnec $rt, imm11s, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 0, 0xFFFFF, FALSE},
+       {4, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 8,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 8, 0x7FF, TRUE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 0, 0xFFFFF, FALSE},
-        {4, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BNEC,      /* bnec $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 8, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BNEC,      /* bnec $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BNEC,      /* bnec $rt, imm11s, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
        {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
        {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
        {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
   },
   {
-    "bnec",                                    /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7FF, TRUE},
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BNEC /* bnec $rt, imm11s, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_MOVI_TA, /* movi $ta, imm11s */
-        INSN_BNE_TA /* bne $rt, $ta, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
+    .opcode = "bnec",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7FF, TRUE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+         INSN_BNEC     /* bnec $rt, imm11s, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
       {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_MOVI_TA,   /* movi $ta, imm11s */
+       INSN_BNE_TA     /* bne $rt, $ta, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
       {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 0, 0xFFFFF, FALSE},
+       {4, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 8,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
       {
-        {0, 8, 0x7FF, TRUE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
       {
-        {0, 0, 0xFFFFF, FALSE},
-        {4, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 8, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
       {
-       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
-       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
-        {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
        {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
        {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
-  }
+       {0, 0, 0, 0}
+      },
+  },
+  {
+    .opcode = NULL,
+  },
 };
 \f
 };
 \f
+
 /* GAS definitions for command-line options.  */
 enum options
 {
 /* GAS definitions for command-line options.  */
 enum options
 {
@@ -1928,6 +2366,9 @@ static int nds32_parse_arch (const char *str);
 static int nds32_parse_baseline (const char *str);
 static int nds32_parse_freg (const char *str);
 static int nds32_parse_abi (const char *str);
 static int nds32_parse_baseline (const char *str);
 static int nds32_parse_freg (const char *str);
 static int nds32_parse_abi (const char *str);
+static void add_mapping_symbol (enum mstate state,
+                               unsigned int padding_byte,
+                               unsigned int align);
 
 static struct nds32_parse_option_table parse_opts [] =
 {
 
 static struct nds32_parse_option_table parse_opts [] =
 {
@@ -1952,11 +2393,13 @@ static struct nds32_parse_option_table parse_opts [] =
 static int nds32_mac = 1;
 static int nds32_div = 1;
 static int nds32_16bit_ext = 1;
 static int nds32_mac = 1;
 static int nds32_div = 1;
 static int nds32_16bit_ext = 1;
-static int nds32_dx_regs = 1;
-static int nds32_perf_ext = 1;
-static int nds32_perf_ext2 = 1;
-static int nds32_string_ext = 1;
-static int nds32_audio_ext = 1;
+static int nds32_dx_regs = NDS32_DEFAULT_DX_REGS;
+static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT;
+static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2;
+static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT;
+static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT;
+static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT;
+static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT;
 static int nds32_fpu_fma = 0;
 static int nds32_pic = 0;
 static int nds32_relax_fp_as_gp = 1;
 static int nds32_fpu_fma = 0;
 static int nds32_pic = 0;
 static int nds32_relax_fp_as_gp = 1;
@@ -1987,6 +2430,8 @@ static struct nds32_set_option_table toggle_opts [] =
   {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
   {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
   {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
   {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
   {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
   {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
+  {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1},
+  {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1},
   {NULL, NULL, NULL, 0}
 };
 
   {NULL, NULL, NULL, 0}
 };
 
@@ -2000,7 +2445,7 @@ nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
                         char **pstr, int64_t *value);
 
 \f
                         char **pstr, int64_t *value);
 
 \f
-struct nds32_asm_desc asm_desc;
+static struct nds32_asm_desc asm_desc;
 
 /* md_after_parse_args ()
 
 
 /* md_after_parse_args ()
 
@@ -2189,7 +2634,7 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* b   label */
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* b   label */
-  if (nds32_pic && strstr (arg_label, "@PLT"))
+  if (nds32_pic)
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
@@ -2210,12 +2655,11 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* bal|call  label */
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* bal|call  label */
-  if (nds32_pic
-      && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
+  if (nds32_pic)
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
-      md_assemble  ((char *) "add $ta,$ta,$gp");
+      md_assemble ((char *) "add $ta,$ta,$gp");
       md_assemble ((char *) "jral $ta");
     }
   else
       md_assemble ((char *) "jral $ta");
     }
   else
@@ -2329,7 +2773,7 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label,
 
   relaxing = TRUE;
   /* rt, label */
 
   relaxing = TRUE;
   /* rt, label */
-  if (!nds32_pic && !strstr(arg_label, "@"))
+  if (!nds32_pic && !strstr (arg_label, "@"))
     {
       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
     {
       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
@@ -2683,11 +3127,11 @@ do_pseudo_pushpopm (int argc, char *argv[],
   /* Reduce register.  */
   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
     {
   /* Reduce register.  */
   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
     {
-      if (re >= 15 && strstr(opc, "smw") != NULL)
+      if (re >= 15 && strstr (opc, "smw") != NULL)
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
       if (rb <= 10)
        md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
       if (rb <= 10)
        md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
-      if (re >= 15 && strstr(opc, "lmw") != NULL)
+      if (re >= 15 && strstr (opc, "lmw") != NULL)
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
     }
   else
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
     }
   else
@@ -2891,7 +3335,7 @@ do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
   md_assemblef ("smw.adm $ta,[%s],$ta", location);
 }
 
   md_assemblef ("smw.adm $ta,[%s],$ta", location);
 }
 
-struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
+static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
 {
   {"b",      1, do_pseudo_b,      0, 0},
   {"bal",    1, do_pseudo_bal,    0, 0},
 {
   {"b",      1, do_pseudo_b,      0, 0},
   {"bal",    1, do_pseudo_bal,    0, 0},
@@ -2967,8 +3411,8 @@ struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
   {"v3pop",  2, do_pseudo_v3pop,  0, 0},
 
   /* Support pseudo instructions of pushing/poping registers into/from stack
   {"v3pop",  2, do_pseudo_v3pop,  0, 0},
 
   /* Support pseudo instructions of pushing/poping registers into/from stack
-       push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
-       pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
+     push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
+     pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
@@ -3008,22 +3452,23 @@ nds32_init_nds32_pseudo_opcodes (void)
 static struct nds32_pseudo_opcode *
 nds32_lookup_pseudo_opcode (const char *str)
 {
 static struct nds32_pseudo_opcode *
 nds32_lookup_pseudo_opcode (const char *str)
 {
+  struct nds32_pseudo_opcode *result;
   int i = 0;
   int i = 0;
-  /* Assume pseudo-opcode are less than 16-char in length.  */
-  char op[16] = {0};
 
 
-  for (i = 0; i < (int)ARRAY_SIZE (op); i++)
+  /* (*op) is the first word of current source line (*str)  */
+  int maxlen = strlen (str);
+  char *op = xmalloc (maxlen + 1);
+
+  for (i = 0; i < maxlen; i++)
     {
       if (ISSPACE (op[i] = str[i]))
        break;
     }
     {
       if (ISSPACE (op[i] = str[i]))
        break;
     }
-
-  if (i >= (int)ARRAY_SIZE (op))
-    return NULL;
-
   op[i] = '\0';
 
   op[i] = '\0';
 
-  return hash_find (nds32_pseudo_opcode_hash, op);
+  result = hash_find (nds32_pseudo_opcode_hash, op);
+  free (op);
+  return result;
 }
 
 static void
 }
 
 static void
@@ -3198,6 +3643,10 @@ nds32_all_ext (void)
   nds32_fpu_fma = 1;
   nds32_fpu_sp_ext = 1;
   nds32_fpu_dp_ext = 1;
   nds32_fpu_fma = 1;
   nds32_fpu_sp_ext = 1;
   nds32_fpu_dp_ext = 1;
+  nds32_dsp_ext = 1;
+  nds32_zol_ext = 1;
+  /* Turn off reduced register.  */
+  nds32_gpr16 = 0;
 
   return 1;
 }
 
   return 1;
 }
@@ -3392,7 +3841,7 @@ do_nds32_seg (int i, subsegT sub)
       seg->s = subseg_new (seg->name, sub);
       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
        {
       seg->s = subseg_new (seg->name, sub);
       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
        {
-         bfd_set_section_flags (stdoutput, seg->s, seg->flags);
+         bfd_set_section_flags (seg->s, seg->flags);
          if ((seg->flags & SEC_LOAD) == 0)
            seg_info (seg->s)->bss = 1;
        }
          if ((seg->flags & SEC_LOAD) == 0)
            seg_info (seg->s)->bss = 1;
        }
@@ -3411,6 +3860,21 @@ nds32_seg (int i)
 /* Set if label adjustment is needed.  I should not adjust .xbyte in dwarf.  */
 static symbolS *nds32_last_label;      /* Last label for alignment.  */
 
 /* Set if label adjustment is needed.  I should not adjust .xbyte in dwarf.  */
 static symbolS *nds32_last_label;      /* Last label for alignment.  */
 
+static void
+add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align)
+{
+  if ((shift > 1) && (addr & 1))
+    {
+      int n = (1 << shift) - 1;
+      if (!is_data_align)
+       add_mapping_symbol (MAP_CODE, 1, 0);
+      else if ((int) (addr & n) != n)
+       add_mapping_symbol (MAP_CODE, 1, 0);
+    }
+  else if ((shift > 1) && ((int) (addr & 1) == 0))
+    add_mapping_symbol (MAP_CODE, 0, 0);
+}
+
 /* This code is referred from D30V for adjust label to be with pending
    alignment.  For example,
      LBYTE: .byte      0x12
 /* This code is referred from D30V for adjust label to be with pending
    alignment.  For example,
      LBYTE: .byte      0x12
@@ -3444,7 +3908,10 @@ nds32_adjust_label (int n)
   if (frag_now_fix () & ((1 << n) -1 ))
     {
       if (subseg_text_p (now_seg))
   if (frag_now_fix () & ((1 << n) -1 ))
     {
       if (subseg_text_p (now_seg))
-       frag_align_code (n, 0);
+       {
+         add_mapping_symbol_for_align (n, frag_now_fix (), 1);
+         frag_align_code (n, 0);
+       }
       else
        frag_align (n, 0, 0);
 
       else
        frag_align (n, 0, 0);
 
@@ -3509,16 +3976,70 @@ nds32_cons_align (int size ATTRIBUTE_UNUSED)
      I think we should just adjust label in `nds32_aligned_X_cons' instead of here.  */
 }
 
      I think we should just adjust label in `nds32_aligned_X_cons' instead of here.  */
 }
 
+static void
+make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align)
+{
+  symbolS *symbol_p = NULL;
+  const char *symbol_name = NULL;
+  switch (state)
+    {
+    case MAP_DATA:
+      if (align == 0)
+       symbol_name = "$d0";
+      else if (align == 1)
+       symbol_name = "$d1";
+      else if (align == 2)
+       symbol_name = "$d2";
+      else if (align == 3)
+       symbol_name = "$d3";
+      else if (align == 4)
+       symbol_name = "$d4";
+      break;
+    case MAP_CODE:
+      symbol_name = "$c";
+      break;
+    default:
+      abort ();
+    }
+
+  symbol_p = symbol_new (symbol_name, now_seg, value, frag);
+  /* local scope attribute  */
+  symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL;
+}
+
+static void
+add_mapping_symbol (enum mstate state, unsigned int padding_byte,
+                   unsigned int align)
+{
+  enum mstate current_mapping_state =
+    seg_info (now_seg)->tc_segment_info_data.mapstate;
+
+  if (state == MAP_CODE
+      && current_mapping_state == state)
+    return;
+
+  if (!SEG_NORMAL (now_seg)
+      || !subseg_text_p (now_seg))
+    return;
+
+  /* start adding mapping symbol  */
+  seg_info (now_seg)->tc_segment_info_data.mapstate = state;
+  make_mapping_symbol (state, (valueT) frag_now_fix () + padding_byte,
+                      frag_now, align);
+}
+
 static void
 nds32_aligned_cons (int idx)
 {
   nds32_adjust_label (idx);
 static void
 nds32_aligned_cons (int idx)
 {
   nds32_adjust_label (idx);
+  add_mapping_symbol (MAP_DATA, 0, idx);
   /* Call default handler.  */
   cons (1 << idx);
   if (now_seg->flags & SEC_CODE
       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
     {
   /* Call default handler.  */
   cons (1 << idx);
   if (now_seg->flags & SEC_CODE
       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
     {
-      /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data.  */
+      /* Use BFD_RELOC_NDS32_DATA to avoid linker
+        optimization replacing data.  */
       expressionS exp;
 
       exp.X_add_number = 0;
       expressionS exp;
 
       exp.X_add_number = 0;
@@ -3578,7 +4099,7 @@ nds32_relax_relocs (int relax)
   char *name;
   int i;
   const char *subtype_relax[] =
   char *name;
   int i;
   const char *subtype_relax[] =
-    {"", "", "ex9", "ifc"};
+    {"", "",};
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
@@ -3595,14 +4116,6 @@ nds32_relax_relocs (int relax)
            case 0:
            case 1:
              enable_relax_relocs = relax & enable_relax_relocs;
            case 0:
            case 1:
              enable_relax_relocs = relax & enable_relax_relocs;
-             enable_relax_ex9 = relax & enable_relax_ex9;
-             enable_relax_ifc = relax & enable_relax_ifc;
-             break;
-           case 2:
-             enable_relax_ex9 = relax;
-             break;
-           case 3:
-             enable_relax_ifc = relax;
              break;
            default:
              break;
              break;
            default:
              break;
@@ -3652,31 +4165,6 @@ nds32_omit_fp_begin (int mode)
     }
 }
 
     }
 }
 
-/* Insert relocations to mark the begin and end of ex9 region,
-   for further relaxation use.
-   bit[i] for $ri */
-
-static void
-nds32_no_ex9_begin (int mode)
-{
-  expressionS exp;
-
-  exp.X_op = O_symbol;
-  exp.X_add_symbol = abs_section_sym;
-  if (mode == 1)
-    {
-      exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
-      fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
-                  BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
-    }
-  else
-    {
-      exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
-      fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
-                  BFD_RELOC_NDS32_RELAX_REGION_END);
-    }
-}
-
 static void
 nds32_loop_begin (int mode)
 {
 static void
 nds32_loop_begin (int mode)
 {
@@ -3706,16 +4194,49 @@ struct nds32_relocs_group
 };
 
 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
 };
 
 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
+/* Used to reorder the id for ".relax_hint id".  */
+static int relax_hint_bias = 0;
+/* Record current relax hint id.  */
+static int relax_hint_id_current = -1;
+int reset_bias = 0;
+/* If ".relax_hint begin" is triggered?  */
+int relax_hint_begin = 0;
+
+/* Record the reordered relax hint id.  */
+
+struct relax_hint_id
+{
+  int old_id;
+  int new_id;
+  struct relax_hint_id *next;
+};
+
+/* FIXME: Need to find somewhere to free the list.  */
+struct relax_hint_id *record_id_head = NULL;
+
+/* Is the buffer large enough?  */
+#define MAX_BUFFER 12
+
+static char *nds_itoa (int n);
+
+static char *
+nds_itoa (int n)
+{
+  char *buf = xmalloc (MAX_BUFFER * sizeof (char));
+  snprintf (buf, MAX_BUFFER, "%d", n);
+  return buf;
+}
 
 /* Insert a relax hint.  */
 
 static void
 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
 {
 
 /* Insert a relax hint.  */
 
 static void
 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
 {
-  char *name;
+  char *name = NULL;
   char saved_char;
   struct nds32_relocs_pattern *relocs = NULL;
   struct nds32_relocs_group *group, *new;
   char saved_char;
   struct nds32_relocs_pattern *relocs = NULL;
   struct nds32_relocs_group *group, *new;
+  struct relax_hint_id *record_id;
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
@@ -3724,12 +4245,57 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   *input_line_pointer = 0;
   name = strdup (name);
 
   *input_line_pointer = 0;
   name = strdup (name);
 
+  if (name && strcmp (name, "begin") == 0)
+    {
+      if (relax_hint_id_current == -1)
+       reset_bias = 1;
+      relax_hint_bias++;
+      relax_hint_id_current++;
+      relax_hint_begin = 1;
+    }
+
+  /* Original case ".relax_hint id".  It's id may need to be reordered. */
+  if (!relax_hint_begin)
+    {
+      int tmp = strtol (name, NULL, 10);
+      record_id = record_id_head;
+      while (record_id)
+       {
+         if (record_id->old_id == tmp)
+           {
+             name = nds_itoa (record_id->new_id);
+             goto reordered_id;
+           }
+         record_id = record_id->next;
+       }
+      if (reset_bias)
+       {
+         relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
+         reset_bias = 0;
+       }
+      relax_hint_id_current = tmp + relax_hint_bias;
+
+      /* Insert the element to the head of the link list.  */
+      struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
+      tmp_id->old_id = tmp;
+      tmp_id->new_id = relax_hint_id_current;
+      tmp_id->next = record_id_head;
+      record_id_head = tmp_id;
+    }
+
+  if (name && strcmp (name, "end") == 0)
+    relax_hint_begin = 0;
+  name = nds_itoa (relax_hint_id_current);
+
+reordered_id:
+
   /* Find relax hint entry for next instruction, and all member will be
      initialized at that time.  */
   relocs = hash_find (nds32_hint_hash, name);
   if (relocs == NULL)
     {
       relocs = XNEW (struct nds32_relocs_pattern);
   /* Find relax hint entry for next instruction, and all member will be
      initialized at that time.  */
   relocs = hash_find (nds32_hint_hash, name);
   if (relocs == NULL)
     {
       relocs = XNEW (struct nds32_relocs_pattern);
+      memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
       hash_insert (nds32_hint_hash, name, relocs);
     }
   else
       hash_insert (nds32_hint_hash, name, relocs);
     }
   else
@@ -3738,6 +4304,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
        relocs=relocs->next;
       relocs->next = XNEW (struct nds32_relocs_pattern);
       relocs = relocs->next;
        relocs=relocs->next;
       relocs->next = XNEW (struct nds32_relocs_pattern);
       relocs = relocs->next;
+      memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
     }
 
   relocs->next = NULL;
     }
 
   relocs->next = NULL;
@@ -3750,6 +4317,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
      instructions relative to the same instruction.  It to connect to
      next instruction after md_assemble.  */
   new = XNEW (struct nds32_relocs_group);
      instructions relative to the same instruction.  It to connect to
      next instruction after md_assemble.  */
   new = XNEW (struct nds32_relocs_group);
+  memset (new, 0, sizeof (struct nds32_relocs_group));
   new->pattern = relocs;
   new->next = NULL;
   group = nds32_relax_hint_current;
   new->pattern = relocs;
   new->next = NULL;
   group = nds32_relax_hint_current;
@@ -3834,6 +4402,46 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
   ignore_rest_of_line ();
 }
 
   ignore_rest_of_line ();
 }
 
+static void
+ict_model (int ignore ATTRIBUTE_UNUSED)
+{
+  char *name;
+  char saved_char;
+  int i;
+  const char *possible_flags[] = { "small", "large" };
+
+  /* Skip whitespaces.  */
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE (*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
+    {
+      if (strcmp (name, possible_flags[i]) == 0)
+       {
+         switch (i)
+           {
+           case 0:
+             /* flag: verbatim  */
+             ict_flag = ICT_SMALL;
+             break;
+           case 1:
+             ict_flag = ICT_LARGE;
+             break;
+           default:
+             break;
+           }
+         /* Already found the flag, no need to continue next loop.   */
+         break;
+       }
+    }
+
+  *input_line_pointer = saved_char;
+  ignore_rest_of_line ();
+}
+
 static void
 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
 {
 static void
 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
 {
@@ -3894,13 +4502,12 @@ const pseudo_typeS md_pseudo_table[] =
   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   {"omit_fp_end", nds32_omit_fp_begin, 0},
   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   {"omit_fp_end", nds32_omit_fp_begin, 0},
-  {"no_ex9_begin", nds32_no_ex9_begin, 1},
-  {"no_ex9_end", nds32_no_ex9_begin, 0},
   {"vec_size", nds32_vec_size, 0},
   {"flag", nds32_flag, 0},
   {"innermost_loop_begin", nds32_loop_begin, 1},
   {"innermost_loop_end", nds32_loop_begin, 0},
   {"relax_hint", nds32_relax_hint, 0},
   {"vec_size", nds32_vec_size, 0},
   {"flag", nds32_flag, 0},
   {"innermost_loop_begin", nds32_loop_begin, 1},
   {"innermost_loop_end", nds32_loop_begin, 0},
   {"relax_hint", nds32_relax_hint, 0},
+  {"ict_model", ict_model, 0},
   {NULL, NULL, 0}
 };
 
   {NULL, NULL, 0}
 };
 
@@ -3917,6 +4524,7 @@ nds32_pre_do_align (int n, char *fill, int len, int max)
            {
              dwarf2_emit_insn (0);
              fragP = frag_now;
            {
              dwarf2_emit_insn (0);
              fragP = frag_now;
+             add_mapping_symbol_for_align (n, frag_now_fix (), 0);
              frag_align_code (n, max);
 
              /* Tag this alignment when there is a label before it.  */
              frag_align_code (n, max);
 
              /* Tag this alignment when there is a label before it.  */
@@ -4003,13 +4611,16 @@ void
 md_begin (void)
 {
   struct nds32_keyword *k;
 md_begin (void)
 {
   struct nds32_keyword *k;
-  unsigned int i;
+  relax_info_t *relax_info;
+  int flags = 0;
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
 
   nds32_init_nds32_pseudo_opcodes ();
   asm_desc.parse_operand = nds32_asm_parse_operand;
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
 
   nds32_init_nds32_pseudo_opcodes ();
   asm_desc.parse_operand = nds32_asm_parse_operand;
-  nds32_asm_init (&asm_desc, 0);
+  if (nds32_gpr16)
+    flags |= NASM_OPEN_REDUCED_REG;
+  nds32_asm_init (&asm_desc, flags);
 
   /* Initial general purpose registers hash table.  */
   nds32_gprs_hash = hash_new ();
 
   /* Initial general purpose registers hash table.  */
   nds32_gprs_hash = hash_new ();
@@ -4018,9 +4629,8 @@ md_begin (void)
 
   /* Initial branch hash table.  */
   nds32_relax_info_hash = hash_new ();
 
   /* Initial branch hash table.  */
   nds32_relax_info_hash = hash_new ();
-  for (i = 0; i < ARRAY_SIZE (relax_table); i++)
-    hash_insert (nds32_relax_info_hash, relax_table[i].opcode,
-                &relax_table[i]);
+  for (relax_info = relax_table; relax_info->opcode; relax_info++)
+    hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
 
   /* Initial relax hint hash table.  */
   nds32_hint_hash = hash_new ();
 
   /* Initial relax hint hash table.  */
   nds32_hint_hash = hash_new ();
@@ -4138,11 +4748,12 @@ get_range_type (const struct nds32_field *field)
 /* Save pseudo instruction relocation list.  */
 
 static struct nds32_relocs_pattern*
 /* Save pseudo instruction relocation list.  */
 
 static struct nds32_relocs_pattern*
-nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
+nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
                               char *out, symbolS *sym,
                               struct nds32_relocs_pattern *reloc_ptr,
                               fragS *fragP)
 {
                               char *out, symbolS *sym,
                               struct nds32_relocs_pattern *reloc_ptr,
                               fragS *fragP)
 {
+  struct nds32_opcode *opcode = insn->opcode;
   if (!reloc_ptr)
     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   reloc_ptr->seg = now_seg;
   if (!reloc_ptr)
     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   reloc_ptr->seg = now_seg;
@@ -4152,6 +4763,7 @@ nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
   reloc_ptr->fixP = fixP;
   reloc_ptr->opcode = opcode;
   reloc_ptr->where = out;
   reloc_ptr->fixP = fixP;
   reloc_ptr->opcode = opcode;
   reloc_ptr->where = out;
+  reloc_ptr->insn = insn->insn;
   reloc_ptr->next = NULL;
   return reloc_ptr;
 }
   reloc_ptr->next = NULL;
   return reloc_ptr;
 }
@@ -4193,10 +4805,18 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
          reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
          break;
        case BFD_RELOC_NDS32_GOTTPOFF:  /* @GOTTPOFF */
          reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
          break;
        case BFD_RELOC_NDS32_GOTTPOFF:  /* @GOTTPOFF */
-         reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
+         reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
+         break;
+       case BFD_RELOC_NDS32_TLS_DESC:  /* @TLSDESC */
+         reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
          break;
          break;
-       default:        /* No suffix.  */
-         reloc = BFD_RELOC_NDS32_HI20;
+       default:        /* No suffix */
+         if (nds32_pic)
+           /* When the file is pic, the address must be offset to gp.
+              It may define another relocation or use GOTOFF.  */
+           reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
+         else
+           reloc = BFD_RELOC_NDS32_HI20;
          break;
        }
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
          break;
        }
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
@@ -4228,8 +4848,19 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
            case BFD_RELOC_NDS32_TPOFF:         /* @TPOFF */
              reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
              break;
            case BFD_RELOC_NDS32_TPOFF:         /* @TPOFF */
              reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
              break;
-           default:    /* No suffix.  */
-             reloc = BFD_RELOC_NDS32_LO12S0;
+           case BFD_RELOC_NDS32_GOTTPOFF:      /* @GOTTPOFF */
+             reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
+             break;
+           case BFD_RELOC_NDS32_TLS_DESC:      /* @TLSDESC */
+             reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
+             break;
+           default:    /* No suffix */
+             if (nds32_pic)
+               /* When the file is pic, the address must be offset to gp.
+                  It may define another relocation or use GOTOFF.  */
+               reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
+             else
+               reloc = BFD_RELOC_NDS32_LO12S0;
              break;
            }
        }
              break;
            }
        }
@@ -4241,9 +4872,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
          switch (pexp->X_md)
            {
            case BFD_RELOC_NDS32_GOTTPOFF:      /* @GOTTPOFF */
          switch (pexp->X_md)
            {
            case BFD_RELOC_NDS32_GOTTPOFF:      /* @GOTTPOFF */
-             reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
+             reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
              break;
              break;
-           default:    /* No suffix */
+           default:    /* No suffix */
              reloc = BFD_RELOC_NDS32_LO12S2;
              break;
            }
              reloc = BFD_RELOC_NDS32_LO12S2;
              break;
            }
@@ -4251,7 +4882,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
       else if (fld->bitsize == 15 && fld->shift == 3)
        reloc = BFD_RELOC_NDS32_LO12S3;         /* [ls]di */
       else if (fld->bitsize == 12 && fld->shift == 2)
       else if (fld->bitsize == 15 && fld->shift == 3)
        reloc = BFD_RELOC_NDS32_LO12S3;         /* [ls]di */
       else if (fld->bitsize == 12 && fld->shift == 2)
-       reloc = R_NDS32_LO12S2_SP_RELA;         /* f[ls][sd]i */
+       reloc = BFD_RELOC_NDS32_LO12S2_SP;      /* f[ls][sd]i */
 
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
                          insn->info, 0 /* pcrel */, reloc);
 
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
                          insn->info, 0 /* pcrel */, reloc);
@@ -4307,20 +4938,6 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
       else
        abort ();
 
       else
        abort ();
 
-      fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
-                  insn->info, 1 /* pcrel */, reloc);
-    }
-  else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
-    {
-      /* Relocation for ifcall instruction.  */
-      if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
-       reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
-      else if (insn->opcode->isize == 4 && fld->bitsize == 16
-              && fld->shift == 1)
-       reloc = BFD_RELOC_NDS32_17IFC_PCREL;
-      else
-       abort ();
-
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
                   insn->info, 1 /* pcrel */, reloc);
     }
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
                   insn->info, 1 /* pcrel */, reloc);
     }
@@ -4335,8 +4952,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
 
 static void
 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
 
 static void
 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
-                               struct nds32_opcode *opcode, fragS *fragP,
-                               const struct nds32_field *fld)
+                               struct nds32_asm_insn *insn, fragS *fragP,
+                               const struct nds32_field *fld,
+                               bfd_boolean pseudo_hint)
 {
   struct nds32_relocs_pattern *reloc_ptr;
   struct nds32_relocs_group *group;
 {
   struct nds32_relocs_pattern *reloc_ptr;
   struct nds32_relocs_group *group;
@@ -4346,10 +4964,32 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
   if (fld)
     sym = pexp->X_add_symbol;
 
   if (fld)
     sym = pexp->X_add_symbol;
 
-  if (pseudo_opcode)
+  if (pseudo_hint)
+    {
+      /* We cannot know how many instructions will be expanded for
+        the pseudo instruction here.  The first expanded instruction fills
+        the memory created by relax_hint.  The follower will created and link
+        here.  */
+      group = nds32_relax_hint_current;
+      while (group)
+       {
+         if (group->pattern->opcode == NULL)
+           nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
+                                          group->pattern, fragP);
+         else
+           {
+             group->pattern->next =
+               nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
+                                              NULL, fragP);
+             group->pattern = group->pattern->next;
+           }
+         group = group->next;
+       }
+    }
+  else if (pseudo_opcode)
     {
       /* Save instruction relation for pseudo instruction expanding pattern.  */
     {
       /* Save instruction relation for pseudo instruction expanding pattern.  */
-      reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+      reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
                                                 NULL, fragP);
       if (!relocs_list)
        relocs_list = reloc_ptr;
                                                 NULL, fragP);
       if (!relocs_list)
        relocs_list = reloc_ptr;
@@ -4367,7 +5007,7 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
       group = nds32_relax_hint_current;
       while (group)
        {
       group = nds32_relax_hint_current;
       while (group)
        {
-         nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+         nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
                                         group->pattern, fragP);
          group = group->next;
          free (nds32_relax_hint_current);
                                         group->pattern, fragP);
          group = group->next;
          free (nds32_relax_hint_current);
@@ -4383,40 +5023,199 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
 
 /* Relax pattern for link time relaxation.  */
 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
 
 /* Relax pattern for link time relaxation.  */
+/* Relaxation types only! relocation types are not necessary.  */
+/* Refer to nds32_elf_record_fixup_exp ().  */
 
 static struct nds32_relax_hint_table relax_ls_table[] =
 {
   {
 
 static struct nds32_relax_hint_table relax_ls_table[] =
 {
   {
-    /* Set address: la -> sethi ori.  */
-    NDS32_RELAX_HINT_LA,       /* main_type */
-    8,                         /* relax_code_size */
-    {
-      OP6 (SETHI),
-      OP6 (ORI),
-    },                         /* relax_code_seq */
-    {
-      {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
-      {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
-    }                          /* relax_fixup */
+    /* LA and Floating LSI.  */
+    .main_type = NDS32_RELAX_HINT_LA_FLSI,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
   },
   {
   },
   {
-    /* Set address: l.w -> sethi ori.  */
-    NDS32_RELAX_HINT_LS,       /* main_type */
-    8,                         /* relax_code_size */
-    {
-      OP6 (SETHI),
-      OP6 (LBI),
-    },                         /* relax_code_seq */
-    {
-      {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
-      {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
-    }                          /* relax_fixup */
+    /* Load Address / Load-Store (LALS).  */
+    .main_type = NDS32_RELAX_HINT_LALS,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
   },
   {
   },
   {
-    0,
-    0,
-    {0},
-    {{0, 0 , 0, 0}}
+    /* B(AL) symbol@PLT  */
+    .main_type = NDS32_RELAX_HINT_LA_PLT,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (JREG),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* LA (@GOT).  */
+    .main_type = NDS32_RELAX_HINT_LA_GOT,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* LA (@GOTOFF).  */
+    .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS LE LS|LA */
+    .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6(SETHI),
+       OP6(ORI),
+       OP6(MEM),
+       OP6(ALU1),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS IE LA */
+    .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
+    .relax_code_size = 8,
+    .relax_code_seq =
+      {
+       OP6(SETHI),
+       OP6(LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS IEGP LA */
+    .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS DESC LS:  */
+    .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
+    .relax_code_size = 24,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (LBI),      /* load argument */
+       OP6 (JREG),
+       OP6 (MEM),      /* load/store variable or load argument */
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
+       {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
+       {16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
+       {20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    .main_type = 0,
+    .relax_code_seq = {0},
+    .relax_fixup = {{0, 0 , 0, 0}}
   }
 };
 
   }
 };
 
@@ -4477,122 +5276,190 @@ nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
 
 /* The args means: instruction size, the 1st instruction is converted to 16 or
    not, optimize option, 16 bit instruction is enable.  */
 
 /* The args means: instruction size, the 1st instruction is converted to 16 or
    not, optimize option, 16 bit instruction is enable.  */
+
 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
    | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
    | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
+#define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
 
 static void
 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
 {
 
 static void
 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
 {
-  /* Set E_NDS32_HAS_EXT_INST.  */
-  if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
-    {
-      if (nds32_perf_ext)
-       nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
-      else
-       as_bad (_("instruction %s requires enabling performance extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
-    {
-      if (nds32_perf_ext2)
-       nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
-      else
-       as_bad (_("instruction %s requires enabling performance extension II"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
-    {
-      if (nds32_audio_ext)
-       nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
-      else
-       as_bad (_("instruction %s requires enabling AUDIO extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
-    {
-      if (nds32_string_ext)
-       nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
-      else
-       as_bad (_("instruction %s requires enabling STRING extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_DIV)
-          && (insn->opcode->attr & NASM_ATTR_DXREG))
-    {
-      if (nds32_div && nds32_dx_regs)
-       nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
-      else
-       as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU)
-    {
-      if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
-       {
-         if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
-           nds32_fpu_com = 1;
-       }
-      else
-       as_bad (_("instruction %s requires enabling FPU extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
-    {
-      if (nds32_fpu_sp_ext)
-       nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
-      else
-       as_bad (_("instruction %s requires enabling FPU_SP extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
-          && (insn->opcode->attr & NASM_ATTR_MAC))
-    {
-      if (nds32_fpu_sp_ext && nds32_mac)
-       {
-         nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
-         nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
-       }
-      else
-       as_bad (_("instruction %s requires enabling FPU_MAC extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
-    {
-      if (nds32_fpu_dp_ext)
-       nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
-      else
-       as_bad (_("instruction %s requires enabling FPU_DP extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
-          && (insn->opcode->attr & NASM_ATTR_MAC))
+  static int skip_flags = NASM_ATTR_FPU_FMA
+    | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT
+    | NASM_ATTR_GPREL | NASM_ATTR_DXREG
+    | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2
+    | NASM_ATTR_ISA_V3 | NASM_ATTR_ISA_V3M
+    | NASM_ATTR_PCREL;
+
+  int new_flags = insn->opcode->attr & ~skip_flags;
+  while (new_flags)
     {
     {
-      if (nds32_fpu_dp_ext && nds32_mac)
+      int next = 1 << (ffs (new_flags) - 1);
+      new_flags &= ~next;
+      switch (next)
        {
        {
-         nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
-         nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+       case NASM_ATTR_PERF_EXT:
+         {
+           if (nds32_perf_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
+               skip_flags |= NASM_ATTR_PERF_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling performance "
+                       "extension"), insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_PERF2_EXT:
+         {
+           if (nds32_perf_ext2)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
+               skip_flags |= NASM_ATTR_PERF2_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling performance "
+                       "extension II"), insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_AUDIO_ISAEXT:
+         {
+           if (nds32_audio_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
+               skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling AUDIO extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_STR_EXT:
+         {
+           if (nds32_string_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
+               skip_flags |= NASM_ATTR_STR_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling STRING extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_DIV:
+         {
+           if (insn->opcode->attr & NASM_ATTR_DXREG)
+             {
+               if (nds32_div && nds32_dx_regs)
+                 {
+                   nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
+                   skip_flags |= NASM_ATTR_DIV;
+                 }
+               else
+                 as_bad (_("instruction %s requires enabling DIV & DX_REGS "
+                           "extension"), insn->opcode->opcode);
+             }
+         }
+         break;
+       case NASM_ATTR_FPU:
+         {
+           if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
+             {
+               if (!(nds32_elf_flags
+                     & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
+                 nds32_fpu_com = 1;
+               skip_flags |= NASM_ATTR_FPU;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_FPU_SP_EXT:
+         {
+           if (nds32_fpu_sp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
+               skip_flags |= NASM_ATTR_FPU_SP_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU_SP extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_FPU_DP_EXT:
+         {
+           if (nds32_fpu_dp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+               skip_flags |= NASM_ATTR_FPU_DP_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU_DP extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_MAC:
+         {
+           if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
+             {
+               if (nds32_fpu_sp_ext && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+               else
+                 as_bad (_("instruction %s requires enabling FPU_MAC "
+                           "extension"), insn->opcode->opcode);
+             }
+           else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
+             {
+               if (nds32_fpu_dp_ext && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+               else
+                 as_bad (_("instruction %s requires enabling FPU_MAC "
+                           "extension"), insn->opcode->opcode);
+             }
+           else if (insn->opcode->attr & NASM_ATTR_DXREG)
+             {
+               if (nds32_dx_regs && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
+               else
+                 as_bad (_("instruction %s requires enabling DX_REGS "
+                           "extension"), insn->opcode->opcode);
+             }
+
+           if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
+             skip_flags |= NASM_ATTR_MAC;
+         }
+         break;
+       case NASM_ATTR_DSP_ISAEXT:
+         {
+           if (nds32_dsp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
+               skip_flags |= NASM_ATTR_DSP_ISAEXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling dsp extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_ZOL:
+         {
+           if (nds32_zol_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_ZOL;
+               skip_flags |= NASM_ATTR_ZOL;
+             }
+           else
+             as_bad (_("instruction %s requires enabling zol extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       default:
+         as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
+                 next);
        }
        }
-      else
-       as_bad (_("instruction %s requires enabling FPU_MAC extension"),
-               insn->opcode->opcode);
-    }
-  /* TODO: FPU_BOTH */
-  else if ((insn->opcode->attr & NASM_ATTR_MAC)
-          && (insn->opcode->attr & NASM_ATTR_DXREG))
-    {
-      if (nds32_mac && nds32_dx_regs)
-       nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
-      else
-       as_bad (_("instruction %s requires enabling DX_REGS extension"),
-               insn->opcode->opcode);
     }
     }
-  /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
-  else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
-    {
-      nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
-    }
-  /* TODO: E_NDS32_HAS_SATURATION_INST */
 }
 
 /* Flag for analysis relaxation type.  */
 }
 
 /* Flag for analysis relaxation type.  */
@@ -4607,97 +5474,199 @@ enum nds32_insn_type
   N32_RELAX_ORI = (1 << 5),
   N32_RELAX_MEM = (1 << 6),
   N32_RELAX_MOVI = (1 << 7),
   N32_RELAX_ORI = (1 << 5),
   N32_RELAX_MEM = (1 << 6),
   N32_RELAX_MOVI = (1 << 7),
+  N32_RELAX_ALU1 = (1 << 8),
+  N32_RELAX_16BIT = (1 << 9),
 };
 
 struct nds32_hint_map
 {
 };
 
 struct nds32_hint_map
 {
+  /* the preamble relocation */
   bfd_reloc_code_real_type hi_type;
   bfd_reloc_code_real_type hi_type;
+  /* mnemonic */
   const char *opc;
   const char *opc;
+  /* relax pattern ID */
   enum nds32_relax_hint_type hint_type;
   enum nds32_relax_hint_type hint_type;
+  /* range */
   enum nds32_br_range range;
   enum nds32_br_range range;
+  /* pattern character flags */
   enum nds32_insn_type insn_list;
   enum nds32_insn_type insn_list;
+  /* optional pattern character flags */
+  enum nds32_insn_type option_list;
 };
 
 /* Table to match instructions with hint and relax pattern.  */
 
 static struct nds32_hint_map hint_map [] =
 {
 };
 
 /* Table to match instructions with hint and relax pattern.  */
 
 static struct nds32_hint_map hint_map [] =
 {
-    {
-      /* LONGCALL4.  */
-      BFD_RELOC_NDS32_HI20,
-      "jal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
-    },
-    {
-      /* LONGCALL5.  */
-      _dummy_first_bfd_reloc_code_real,
-      "bgezal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16M,
-      N32_RELAX_BR | N32_RELAX_CALL
-    },
-    {
-      /* LONGCALL6.  */
-      BFD_RELOC_NDS32_HI20,
-      "bgezal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
-    },
-    {
-      /* LONGJUMP4.  */
-      BFD_RELOC_NDS32_HI20,
-      "j",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP5.  */
-      /* There is two kinds of variations of LONGJUMP5.  One of them
-        generate EMPTY relocation for converted INSN16 if needed.
-        But we don't distinguish them here.  */
-      _dummy_first_bfd_reloc_code_real,
-      "beq",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16M,
-      N32_RELAX_BR | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP6.  */
-      BFD_RELOC_NDS32_HI20,
-      "beq",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP7.  */
-      _dummy_first_bfd_reloc_code_real,
-      "beqc",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16K,
-      N32_RELAX_MOVI | N32_RELAX_BR
-    },
-    {
-      /* LOADSTORE ADDRESS.  */
-      BFD_RELOC_NDS32_HI20,
-      NULL,
-      NDS32_RELAX_HINT_LA,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI
-    },
-    {
-      /* LOADSTORE ADDRESS.  */
-      BFD_RELOC_NDS32_HI20,
-      NULL,
-      NDS32_RELAX_HINT_LS,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_LSI
-    },
-    {0, NULL, 0, 0 ,0}
+  {
+    /* LONGCALL4.  */
+    BFD_RELOC_NDS32_HI20,
+    "jal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGCALL5.  */
+    _dummy_first_bfd_reloc_code_real,
+    "bgezal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16M,
+    N32_RELAX_BR | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGCALL6.  */
+    BFD_RELOC_NDS32_HI20,
+    "bgezal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGJUMP4.  */
+    BFD_RELOC_NDS32_HI20,
+    "j",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP5.  */
+    /* There is two kinds of variation of LONGJUMP5.  One of them
+       generate EMPTY relocation for converted INSN16 if needed.
+       But we don't distinguish them here.  */
+    _dummy_first_bfd_reloc_code_real,
+    "beq",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16M,
+    N32_RELAX_BR | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP6.  */
+    BFD_RELOC_NDS32_HI20,
+    "beq",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP7.  */
+    _dummy_first_bfd_reloc_code_real,
+    "beqc",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16K,
+    N32_RELAX_MOVI | N32_RELAX_BR,
+    0,
+  },
+  {
+    /* LONGCALL (BAL|JR|LA symbol@PLT).  */
+    BFD_RELOC_NDS32_PLT_GOTREL_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_PLT,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
+  },
+  /* relative issue: #12566 */
+  {
+    /* LA and Floating LSI.  */
+    BFD_RELOC_NDS32_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_FLSI,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
+    0,
+  },
+  /* relative issue: #11685 #11602 */
+  {
+    /* load address / load-store (LALS).  */
+    BFD_RELOC_NDS32_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LALS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI,
+    N32_RELAX_ORI | N32_RELAX_LSI,
+  },
+  {
+    /* setup $GP (_GLOBAL_OFFSET_TABLE_)  */
+    BFD_RELOC_NDS32_GOTPC_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LALS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    0,
+  },
+  {
+    /* GOT LA/LS (symbol@GOT)  */
+    BFD_RELOC_NDS32_GOT_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_GOT,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_MEM,
+  },
+  {
+    /* GOTOFF LA/LS (symbol@GOTOFF)  */
+    BFD_RELOC_NDS32_GOTOFF_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_GOTOFF,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1  | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
+  },
+  {
+    /* TLS LE LA|LS (@TPOFF)  */
+    BFD_RELOC_NDS32_TLS_LE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_LE_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1 | N32_RELAX_MEM,
+  },
+  {
+    /* TLS IE LA */
+    BFD_RELOC_NDS32_TLS_IE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IE_LA,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_LSI,
+    0,
+  },
+{
+    /* TLS IE LS */
+    BFD_RELOC_NDS32_TLS_IE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IE_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
+    0,
+  },
+  {
+    /* TLS IEGP LA */
+    BFD_RELOC_NDS32_TLS_IEGP_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IEGP_LA,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
+    0,
+  },
+  {
+    /* TLS DESC LS */
+    BFD_RELOC_NDS32_TLS_DESC_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_DESC_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
+    N32_RELAX_LSI | N32_RELAX_MEM,
+  },
+  /* last one */
+  {0, NULL, 0, 0 ,0, 0}
 };
 
 /* Find the relaxation pattern according to instructions.  */
 };
 
 /* Find the relaxation pattern according to instructions.  */
@@ -4739,6 +5708,9 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
            case N32_OP6_MEM:
              relax_type |= N32_RELAX_MEM;
              break;
            case N32_OP6_MEM:
              relax_type |= N32_RELAX_MEM;
              break;
+           case N32_OP6_ALU1:
+             relax_type |= N32_RELAX_ALU1;
+             break;
            case N32_OP6_ORI:
              relax_type |= N32_RELAX_ORI;
              break;
            case N32_OP6_ORI:
              relax_type |= N32_RELAX_ORI;
              break;
@@ -4760,6 +5732,8 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
            case N32_OP6_SWI:
            case N32_OP6_LWC:
            case N32_OP6_SWC:
            case N32_OP6_SWI:
            case N32_OP6_LWC:
            case N32_OP6_SWC:
+           case N32_OP6_LDC:
+           case N32_OP6_SDC:
              relax_type |= N32_RELAX_LSI;
              break;
            case N32_OP6_JREG:
              relax_type |= N32_RELAX_LSI;
              break;
            case N32_OP6_JREG:
@@ -4782,18 +5756,20 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
        }
       else
        {
        }
       else
        {
-         /* 2 byte instruction.  Compare by opcode name because the opcode of
-            2byte instruction is not regular.  */
-         for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+         /* 2 byte instruction.  Compare by opcode name because
+            the opcode of 2byte instruction is not regular.  */
+         int is_matched = 0;
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
            {
              if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
                {
                  relax_type |= N32_RELAX_BR;
            {
              if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
                {
                  relax_type |= N32_RELAX_BR;
+                 is_matched += 1;
                  break;
                }
            }
                  break;
                }
            }
-         if (strcmp (pattern->opcode->opcode, "movi55") == 0)
-           relax_type |= N32_RELAX_MOVI;
+         if (!is_matched)
+           relax_type |= N32_RELAX_16BIT;
        }
       pattern = pattern->next;
     }
        }
       pattern = pattern->next;
     }
@@ -4801,23 +5777,35 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
   /* Analysis instruction flag to choose relaxation table.  */
   while (map_ptr->insn_list != 0)
     {
   /* Analysis instruction flag to choose relaxation table.  */
   while (map_ptr->insn_list != 0)
     {
-      if (map_ptr->insn_list == relax_type
-         && (!hi_pattern
-             || (hi_pattern->fixP
-                 && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
+      struct nds32_hint_map *hint = map_ptr++;
+      enum nds32_insn_type must = hint->insn_list;
+      enum nds32_insn_type optional = hint->option_list;
+      enum nds32_insn_type extra;
+
+      if (must != (must & relax_type))
+       continue;
+
+      extra = relax_type ^ must;
+      if (extra != (extra & optional))
+       continue;
+
+      if (!hi_pattern
+         || (hi_pattern->fixP
+             && hi_pattern->fixP->fx_r_type == hint->hi_type))
        {
        {
-         opc = map_ptr->opc;
-         hint_type = map_ptr->hint_type;
-         range = map_ptr->range;
+         opc = hint->opc;
+         hint_type = hint->hint_type;
+         range = hint->range;
+         map_ptr = hint;
          break;
        }
          break;
        }
-      map_ptr++;
     }
 
   if (map_ptr->insn_list == 0)
     {
     }
 
   if (map_ptr->insn_list == 0)
     {
-      as_warn (_("Can not find match relax hint.  Line: %d"),
-              relocs_pattern->frag->fr_line);
+      if (!nds32_pic)
+       as_warn (_("Can not find match relax hint.  Line: %d"),
+                relocs_pattern->frag->fr_line);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -4876,12 +5864,14 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
 /* Because there are a lot of variant of load-store, check
    all these type here.  */
 
 /* Because there are a lot of variant of load-store, check
    all these type here.  */
 
-#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
+#define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
+#define GET_OPCODE(insn) ((insn) & 0xfe000000)
+
 static bfd_boolean
 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
 {
   const char *check_insn[] =
 static bfd_boolean
 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
 {
   const char *check_insn[] =
-    { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+    { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
   uint32_t insn = opcode->value;
   unsigned int i;
 
   uint32_t insn = opcode->value;
   unsigned int i;
 
@@ -4897,22 +5887,23 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
          || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
          || insn == OP6 (LWI) || insn == OP6 (SWI)
       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
          || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
          || insn == OP6 (LWI) || insn == OP6 (SWI)
-         || insn == OP6 (LWC) || insn == OP6 (SWC))
-        return TRUE;
+         || insn == OP6 (LWC) || insn == OP6 (SWC)
+         || insn == OP6 (LDC) || insn == OP6 (SDC))
+       return TRUE;
       break;
     case OP6 (BR2):
       /* This is for LONGCALL5 and LONGCALL6.  */
       if (insn == OP6 (BR2))
       break;
     case OP6 (BR2):
       /* This is for LONGCALL5 and LONGCALL6.  */
       if (insn == OP6 (BR2))
-        return TRUE;
+       return TRUE;
       break;
     case OP6 (BR1):
       /* This is for LONGJUMP5 and LONGJUMP6.  */
       if (opcode->isize == 4
          && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
       break;
     case OP6 (BR1):
       /* This is for LONGJUMP5 and LONGJUMP6.  */
       if (opcode->isize == 4
          && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
-        return TRUE;
+       return TRUE;
       else if (opcode->isize == 2)
        {
       else if (opcode->isize == 2)
        {
-         for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
            if (strcmp (opcode->opcode, check_insn[i]) == 0)
              return TRUE;
        }
            if (strcmp (opcode->opcode, check_insn[i]) == 0)
              return TRUE;
        }
@@ -4920,8 +5911,28 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
     case OP6 (MOVI):
       /* This is for LONGJUMP7.  */
       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
     case OP6 (MOVI):
       /* This is for LONGJUMP7.  */
       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
-        return TRUE;
+       return TRUE;
+      break;
+    case OP6 (MEM):
+      if (OP6 (MEM) == GET_OPCODE (insn))
+       return TRUE;
       break;
       break;
+    case OP6 (JREG):
+      /* bit 24: N32_JI_JAL  */ /* feed me!  */
+      if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
+       return TRUE;
+      break;
+    default:
+      if (opcode->isize == 2)
+       {
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
+           if (strcmp (opcode->opcode, check_insn[i]) == 0)
+             return TRUE;
+
+         if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
+             (strcmp (opcode->opcode, "add45") == 0))
+           return TRUE;
+       }
     }
   return FALSE;
 }
     }
   return FALSE;
 }
@@ -4929,7 +5940,7 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
 /* Append relax relocation for link time relaxing.  */
 
 static void
 /* Append relax relocation for link time relaxing.  */
 
 static void
-nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
+nds32_elf_append_relax_relocs (const char *key, void *value)
 {
   struct nds32_relocs_pattern *relocs_pattern =
     (struct nds32_relocs_pattern *) value;
 {
   struct nds32_relocs_pattern *relocs_pattern =
     (struct nds32_relocs_pattern *) value;
@@ -4942,7 +5953,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
   struct nds32_relax_hint_table hint_info;
   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
   size_t fixup_size;
   struct nds32_relax_hint_table hint_info;
   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
   size_t fixup_size;
-  offsetT branch_offset;
+  offsetT branch_offset, hi_branch_offset = 0;
   fixS *fixP;
   int range, offset;
   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
   fixS *fixP;
   int range, offset;
   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
@@ -4963,6 +5974,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
       if (pattern_now->opcode->value == OP6 (SETHI))
        {
          hi_sym = pattern_now->sym;
       if (pattern_now->opcode->value == OP6 (SETHI))
        {
          hi_sym = pattern_now->sym;
+         hi_branch_offset = pattern_now->fixP->fx_offset;
          break;
        }
       pattern_now = pattern_now->next;
          break;
        }
       pattern_now = pattern_now->next;
@@ -4979,15 +5991,37 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
   relax_code_size = hint_info.relax_code_size;
   pattern_now = relocs_pattern;
 
   relax_code_size = hint_info.relax_code_size;
   pattern_now = relocs_pattern;
 
+#ifdef NDS32_LINUX_TOOLCHAIN
+  /* prepare group relocation ID (number).  */
+  long group_id = 0;
+  if (key)
+    {
+      /* convert .relax_hint key to number */
+      errno = 0;
+      group_id = strtol (key, NULL, 10);
+      if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
+         || (errno != 0 && group_id == 0))
+       {
+         as_bad (_("Internal error: .relax_hint KEY is not a number!"));
+         goto restore;
+       }
+    }
+#endif
+
   /* Insert relaxation.  */
   exp.X_op = O_symbol;
 
   /* Insert relaxation.  */
   exp.X_op = O_symbol;
 
+  /* For each instruction in the hint group.  */
   while (pattern_now)
     {
   while (pattern_now)
     {
+      if (count >= relax_code_size / 4)
+       count = 0;
+
       /* Choose the match fixup by instruction.  */
       code_insn = CLEAN_REG (*(code_seq + count));
       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
        {
       /* Choose the match fixup by instruction.  */
       code_insn = CLEAN_REG (*(code_seq + count));
       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
        {
+         /* Try search from head again */
          count = 0;
          code_insn = CLEAN_REG (*(code_seq + count));
 
          count = 0;
          code_insn = CLEAN_REG (*(code_seq + count));
 
@@ -4996,8 +6030,11 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
              count++;
              if (count >= relax_code_size / 4)
                {
              count++;
              if (count >= relax_code_size / 4)
                {
-                 as_bad (_("Internal error: Relax hint error. %s: %x"),
-                         now_seg->name, pattern_now->opcode->value);
+                 as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
+                         key,
+                         now_seg->name,
+                         pattern_now->opcode->opcode,
+                         pattern_now->opcode->value);
                  goto restore;
                }
              code_insn = CLEAN_REG (*(code_seq + count));
                  goto restore;
                }
              code_insn = CLEAN_REG (*(code_seq + count));
@@ -5093,7 +6130,109 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
            {
              /* For EMPTY relocation save the true symbol.  */
              exp.X_add_symbol = hi_sym;
            {
              /* For EMPTY relocation save the true symbol.  */
              exp.X_add_symbol = hi_sym;
-             exp.X_add_number = branch_offset;
+             exp.X_add_number = hi_branch_offset;
+           }
+         else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
+           {
+             /* Do the same as NDS32_SYM.  */
+             exp.X_add_symbol = hi_sym;
+             exp.X_add_number = hi_branch_offset;
+
+             /* Extra to NDS32_SYM.  */
+             /* Detect if DESC_FUNC relax type do apply.  */
+             if ((REG_GP == N32_RA5 (pattern_now->insn))
+                 || (REG_GP == N32_RB5 (pattern_now->insn)))
+               {
+                 fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+                                     fixup_size, &exp, pcrel,
+                                     BFD_RELOC_NDS32_TLS_DESC_FUNC);
+                 fixP->fx_addnumber = fixP->fx_offset;
+
+                 fixup_size = 0;
+               }
+             /* Else do as usual.  */
+           }
+         else if (fixup_now->ramp & NDS32_PTR_PATTERN)
+           {
+             /* Find out PTR_RESOLVED code pattern.  */
+             nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
+             uint32_t resolved_pattern = 0;
+             while (next_fixup->offset)
+               {
+                 if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
+                   {
+                     uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
+                     if (!resolved_pattern)
+                       resolved_pattern = new_pattern;
+                     else if (new_pattern != resolved_pattern)
+                       {
+                         as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
+                                    "patterns are not supported yet!"));
+                         break;
+                       }
+                   }
+                 ++next_fixup;
+               }
+
+             /* Find matched code and insert fix-ups.  */
+             struct nds32_relocs_pattern *next_pattern = pattern_now->next;
+             /* This relocation has to point to another instruction.
+                Make sure each resolved relocation has to be pointed.  */
+             /* All instruction in relax_table should be 32-bit.  */
+             while (next_pattern)
+               {
+                 uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
+                 if (cur_pattern == resolved_pattern)
+                   {
+                     ptr_offset = next_pattern->where
+                       - next_pattern->frag->fr_literal;
+                     exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
+                                                         next_pattern->frag);
+                     exp.X_add_number = 0;
+                     fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+                                         fixup_size, &exp, 0,
+                                         fixup_now->r_type);
+                     fixP->fx_addnumber = fixP->fx_offset;
+                   }
+                 next_pattern = next_pattern->next;
+               }
+
+             fixup_size = 0;
+           }
+         else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
+           {
+             /* Find each PTR_RESOLVED pattern after PTR.  */
+             nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
+             while (next_fixup->offset)
+               {
+                 if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
+                   {
+                     uint32_t pattern = code_seq[next_fixup->offset >> 2];
+                     /* Find matched code to insert fix-ups.  */
+                     struct nds32_relocs_pattern *next_insn = pattern_now->next;
+                     while (next_insn)
+                       {
+                         uint32_t insn_pattern = GET_OPCODE (next_insn->opcode->value);
+                         if (insn_pattern == pattern)
+                           {
+                             ptr_offset = next_insn->where
+                               - next_insn->frag->fr_literal;
+                             exp.X_add_symbol = symbol_temp_new (now_seg,
+                                                                 ptr_offset,
+                                                                 next_insn->frag);
+                             exp.X_add_number = 0;
+                             fixP = fix_new_exp (fragP,
+                                                 where - fragP->fr_literal,
+                                                 fixup_size, &exp, 0,
+                                                 fixup_now->r_type);
+                             fixP->fx_addnumber = fixP->fx_offset;
+                           }
+                         next_insn = next_insn->next;
+                       }
+                   }
+                 ++next_fixup;
+               }
+             fixup_size = 0;
            }
          else
            {
            }
          else
            {
@@ -5110,6 +6249,19 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
          fixup_now++;
          fixup_size = fixup_now->size;
        }
          fixup_now++;
          fixup_size = fixup_now->size;
        }
+
+#ifdef NDS32_LINUX_TOOLCHAIN
+      /* Insert group relocation for each relax hint.  */
+      if (key)
+       {
+         exp.X_add_symbol = hi_sym; /* for eyes only */
+         exp.X_add_number = group_id;
+         fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
+                             &exp, pcrel, BFD_RELOC_NDS32_GROUP);
+         fixP->fx_addnumber = fixP->fx_offset;
+       }
+#endif
+
       if (count < relax_code_size / 4)
        count++;
       pattern_now = pattern_now->next;
       if (count < relax_code_size / 4)
        count++;
       pattern_now = pattern_now->next;
@@ -5120,6 +6272,19 @@ restore:
   frchain_now = frchain_bak;
 }
 
   frchain_now = frchain_bak;
 }
 
+static void
+nds32_str_tolower (const char *src, char *dest)
+{
+  unsigned int i, len;
+
+  len = strlen (src);
+
+  for (i = 0; i < len; i++)
+    *(dest + i) = TOLOWER (*(src + i));
+
+  *(dest + i) = '\0';
+}
+
 /* Check instruction if it can be used for the baseline.  */
 
 static bfd_boolean
 /* Check instruction if it can be used for the baseline.  */
 
 static bfd_boolean
@@ -5127,6 +6292,29 @@ nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
 {
   int attr = insn.attr & ATTR_ALL;
   static int baseline_isa = 0;
 {
   int attr = insn.attr & ATTR_ALL;
   static int baseline_isa = 0;
+  char *s;
+
+  s = xmalloc (strlen (str) + 1);
+  nds32_str_tolower (str, s);
+  if (verbatim
+      && (((insn.opcode->value == ALU2 (MTUSR)
+           || insn.opcode->value == ALU2 (MFUSR))
+          && (strstr (s, "lc")
+              || strstr (s, "le")
+              || strstr (s, "lb")))
+         || (insn.attr & NASM_ATTR_ZOL)))
+    {
+      as_bad (_("Not support instruction %s in verbatim."), str);
+      return FALSE;
+    }
+  free (s);
+
+  if (!enable_16bit && insn.opcode->isize == 2)
+    {
+      as_bad (_("16-bit instruction is disabled: %s."), str);
+      return FALSE;
+    }
+
   /* No isa setting or all isa can use.  */
   if (attr == 0 || attr == ATTR_ALL)
     return TRUE;
   /* No isa setting or all isa can use.  */
   if (attr == 0 || attr == ATTR_ALL)
     return TRUE;
@@ -5162,16 +6350,16 @@ void
 md_assemble (char *str)
 {
   struct nds32_asm_insn insn;
 md_assemble (char *str)
 {
   struct nds32_asm_insn insn;
-  expressionS expr;
   char *out;
   struct nds32_pseudo_opcode *popcode;
   const struct nds32_field *fld = NULL;
   fixS *fixP;
   uint16_t insn_16;
   struct nds32_relocs_pattern *relocs_temp;
   char *out;
   struct nds32_pseudo_opcode *popcode;
   const struct nds32_field *fld = NULL;
   fixS *fixP;
   uint16_t insn_16;
   struct nds32_relocs_pattern *relocs_temp;
-  expressionS *pexp;
+  struct nds32_relocs_group *group_temp;
   fragS *fragP;
   int label = label_exist;
   fragS *fragP;
   int label = label_exist;
+  static bfd_boolean pseudo_hint = FALSE;
 
   popcode = nds32_lookup_pseudo_opcode (str);
   /* Note that we need to check 'verbatim' and
 
   popcode = nds32_lookup_pseudo_opcode (str);
   /* Note that we need to check 'verbatim' and
@@ -5180,11 +6368,23 @@ md_assemble (char *str)
      need to perform pseudo instruction expansion/transformation.  */
   if (popcode && !(verbatim && popcode->physical_op))
     {
      need to perform pseudo instruction expansion/transformation.  */
   if (popcode && !(verbatim && popcode->physical_op))
     {
+      /* Pseudo instruction is with relax_hint.  */
+      if (relaxing)
+       pseudo_hint = TRUE;
       pseudo_opcode = TRUE;
       nds32_pseudo_opcode_wrapper (str, popcode);
       pseudo_opcode = FALSE;
       pseudo_opcode = TRUE;
       nds32_pseudo_opcode_wrapper (str, popcode);
       pseudo_opcode = FALSE;
+      pseudo_hint = FALSE;
       nds32_elf_append_relax_relocs (NULL, relocs_list);
 
       nds32_elf_append_relax_relocs (NULL, relocs_list);
 
+      /* Free relax_hint group list.  */
+      while (nds32_relax_hint_current)
+       {
+         group_temp = nds32_relax_hint_current->next;
+         free (nds32_relax_hint_current);
+         nds32_relax_hint_current = group_temp;
+       }
+
       /* Free pseudo list.  */
       relocs_temp = relocs_list;
       while (relocs_temp)
       /* Free pseudo list.  */
       relocs_temp = relocs_list;
       while (relocs_temp)
@@ -5198,7 +6398,7 @@ md_assemble (char *str)
     }
 
   label_exist = 0;
     }
 
   label_exist = 0;
-  insn.info = & expr;
+  insn.info = XNEW (expressionS);
   asm_desc.result = NASM_OK;
   nds32_assemble (&asm_desc, &insn, str);
 
   asm_desc.result = NASM_OK;
   nds32_assemble (&asm_desc, &insn, str);
 
@@ -5235,11 +6435,13 @@ md_assemble (char *str)
 
   /* Make sure the beginning of text being 2-byte align.  */
   nds32_adjust_label (1);
 
   /* Make sure the beginning of text being 2-byte align.  */
   nds32_adjust_label (1);
+  add_mapping_symbol (MAP_CODE, 0, 0);
   fld = insn.field;
   /* Try to allocate the max size to guarantee relaxable same branch
      instructions in the same fragment.  */
   frag_grow (NDS32_MAXCHAR);
   fragP = frag_now;
   fld = insn.field;
   /* Try to allocate the max size to guarantee relaxable same branch
      instructions in the same fragment.  */
   frag_grow (NDS32_MAXCHAR);
   fragP = frag_now;
+
   if (fld && (insn.attr & NASM_ATTR_BRANCH)
       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
                            && insn.opcode->value != INSN_J))
   if (fld && (insn.attr & NASM_ATTR_BRANCH)
       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
                            && insn.opcode->value != INSN_J))
@@ -5257,8 +6459,8 @@ md_assemble (char *str)
       /* Get branch range type.  */
       dwarf2_emit_insn (0);
       enum nds32_br_range range_type;
       /* Get branch range type.  */
       dwarf2_emit_insn (0);
       enum nds32_br_range range_type;
+      expressionS *pexp = insn.info;
 
 
-      pexp = insn.info;
       range_type = get_range_type (fld);
 
       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
       range_type = get_range_type (fld);
 
       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
@@ -5274,6 +6476,8 @@ md_assemble (char *str)
       else if (insn.opcode->isize == 2)
        bfd_putb16 (insn.insn, out);
       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
       else if (insn.opcode->isize == 2)
        bfd_putb16 (insn.insn, out);
       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
+
+      free (insn.info);
       return;
       /* md_convert_frag will insert relocations.  */
     }
       return;
       /* md_convert_frag will insert relocations.  */
     }
@@ -5284,7 +6488,7 @@ md_assemble (char *str)
                   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
     {
       /* Record this one is relaxable.  */
                   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
     {
       /* Record this one is relaxable.  */
-      pexp = insn.info;
+      expressionS *pexp = insn.info;
       dwarf2_emit_insn (0);
       if (fld)
        {
       dwarf2_emit_insn (0);
       if (fld)
        {
@@ -5314,6 +6518,8 @@ md_assemble (char *str)
        bfd_putb16 (insn_16, out);
       else if (insn.opcode->isize == 2)
        bfd_putb16 (insn.insn, out);
        bfd_putb16 (insn_16, out);
       else if (insn.opcode->isize == 2)
        bfd_putb16 (insn.insn, out);
+
+      free (insn.info);
       return;
     }
   else if ((verbatim || !relaxing) && optimize && label)
       return;
     }
   else if ((verbatim || !relaxing) && optimize && label)
@@ -5343,18 +6549,21 @@ md_assemble (char *str)
 
   if (insn.opcode->isize == 4)
     bfd_putb32 (insn.insn, out);
 
   if (insn.opcode->isize == 4)
     bfd_putb32 (insn.insn, out);
-  if (insn.opcode->isize == 2)
+  else if (insn.opcode->isize == 2)
     bfd_putb16 (insn.insn, out);
 
   dwarf2_emit_insn (insn.opcode->isize);
 
   /* Compiler generating code and user assembly pseudo load-store, insert
      fixup here.  */
     bfd_putb16 (insn.insn, out);
 
   dwarf2_emit_insn (insn.opcode->isize);
 
   /* Compiler generating code and user assembly pseudo load-store, insert
      fixup here.  */
-  pexp = insn.info;
+  expressionS *pexp = insn.info;
   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   /* Build relaxation pattern when relaxing is enable.  */
   if (relaxing)
   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   /* Build relaxation pattern when relaxing is enable.  */
   if (relaxing)
-    nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
+    nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
+                                   pseudo_hint);
+
+  free (insn.info);
 }
 
 /* md_macro_start  */
 }
 
 /* md_macro_start  */
@@ -5400,9 +6609,9 @@ md_operand (expressionS *expressionP)
 valueT
 md_section_align (segT segment, valueT size)
 {
 valueT
 md_section_align (segT segment, valueT size)
 {
-  int align = bfd_get_section_alignment (stdoutput, segment);
+  int align = bfd_section_alignment (segment);
 
 
-  return ((size + (1 << align) - 1) & -(1 << align));
+  return ((size + (1 << align) - 1) & ((valueT) -1 << align));
 }
 
 /* GAS will call this function when a symbol table lookup fails, before it
 }
 
 /* GAS will call this function when a symbol table lookup fails, before it
@@ -5505,7 +6714,6 @@ nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
     }
 }
 
     }
 }
 
-
 static int
 nds32_relax_branch_instructions (segT segment, fragS *fragP,
                                 long stretch ATTRIBUTE_UNUSED,
 static int
 nds32_relax_branch_instructions (segT segment, fragS *fragP,
                                 long stretch ATTRIBUTE_UNUSED,
@@ -5534,15 +6742,36 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
   if (opcode == NULL)
     return adjust;
 
   if (opcode == NULL)
     return adjust;
 
+  /* Use U4G mode for b and bal in verbatim mode because lto may combine
+     functions into a file.  And order the file in the last when linking.
+     Once there is multiple definition, the same function will be kicked.
+     This may cause relocation truncated error.  */
+  if (verbatim && !nds32_pic
+      && (strcmp (opcode->opcode, "j") == 0
+         || strcmp (opcode->opcode, "jal") == 0))
+    {
+      fragP->fr_subtype = BR_RANGE_U4G;
+      if (init)
+       return 8;
+      else
+       return 0;
+    }
+
   relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
 
   if (relax_info == NULL)
     return adjust;
 
   if (init)
   relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
 
   if (relax_info == NULL)
     return adjust;
 
   if (init)
-    branch_range_type = relax_info->br_range;
+    {
+      branch_range_type = relax_info->br_range;
+      i = BR_RANGE_S256;
+    }
   else
   else
-    branch_range_type = fragP->fr_subtype;
+    {
+      branch_range_type = fragP->fr_subtype;
+      i = branch_range_type;
+    }
 
   offset = nds32_calc_branch_offset (segment, fragP, stretch,
                                     relax_info, branch_range_type);
 
   offset = nds32_calc_branch_offset (segment, fragP, stretch,
                                     relax_info, branch_range_type);
@@ -5551,15 +6780,21 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
 
   /* If actual range is equal to instruction jump range, do nothing.  */
   if (real_range_type == branch_range_type)
 
   /* If actual range is equal to instruction jump range, do nothing.  */
   if (real_range_type == branch_range_type)
-    return adjust;
+    {
+      fragP->fr_subtype = real_range_type;
+      return adjust;
+    }
 
   /* Find out proper relaxation code sequence.  */
 
   /* Find out proper relaxation code sequence.  */
-  for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
+  for (; i < BR_RANGE_NUM; i++)
     {
       if (real_range_type <= (unsigned int) i)
        {
          if (init)
            diff = relax_info->relax_code_size[i] - opcode->isize;
     {
       if (real_range_type <= (unsigned int) i)
        {
          if (init)
            diff = relax_info->relax_code_size[i] - opcode->isize;
+         else if (real_range_type < (unsigned int) i)
+           diff = relax_info->relax_code_size[real_range_type]
+             - relax_info->relax_code_size[branch_range_type];
          else
            diff = relax_info->relax_code_size[i]
              - relax_info->relax_code_size[branch_range_type];
          else
            diff = relax_info->relax_code_size[i]
              - relax_info->relax_code_size[branch_range_type];
@@ -5592,7 +6827,7 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
            }
 
          /* Update fr_subtype to new NDS32_BR_RANGE.  */
            }
 
          /* Update fr_subtype to new NDS32_BR_RANGE.  */
-         fragP->fr_subtype = i;
+         fragP->fr_subtype = real_range_type;
          break;
        }
     }
          break;
        }
     }
@@ -5631,19 +6866,19 @@ nds32_get_align (addressT address, int align)
 {
   addressT mask, new_address;
 
 {
   addressT mask, new_address;
 
-  mask = ~((~0U) << align);
+  mask = ~((addressT) (~0) << align);
   new_address = (address + mask) & (~mask);
   return (new_address - address);
 }
 
 /* Check the prev_frag is legal.  */
 static void
   new_address = (address + mask) & (~mask);
   return (new_address - address);
 }
 
 /* Check the prev_frag is legal.  */
 static void
-invalid_prev_frag (fragS * fragP, fragS **prev_frag)
+invalid_prev_frag (fragS * fragP, fragS **prev_frag, bfd_boolean relax)
 {
   addressT address;
   fragS *frag_start = *prev_frag;
 
 {
   addressT address;
   fragS *frag_start = *prev_frag;
 
-  if (!frag_start)
+  if (!frag_start || !relax)
     return;
 
   if (frag_start->last_fr_address >= fragP->last_fr_address)
     return;
 
   if (frag_start->last_fr_address >= fragP->last_fr_address)
@@ -5711,7 +6946,7 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
-  invalid_prev_frag (fragP, &prev_frag);
+  invalid_prev_frag (fragP, &prev_frag, TRUE);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
@@ -5748,7 +6983,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
-  invalid_prev_frag (fragP, &prev_frag);
+  invalid_prev_frag (fragP, &prev_frag, FALSE);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
@@ -5798,6 +7033,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
   /* Save the 1st instruction is converted to 16 bit or not.  */
   unsigned int branch_size;
   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
   /* Save the 1st instruction is converted to 16 bit or not.  */
   unsigned int branch_size;
+  enum bfd_reloc_code_real final_r_type;
 
   /* Replace with gas_assert (branch_symbol != NULL); */
   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
 
   /* Replace with gas_assert (branch_symbol != NULL); */
   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
@@ -5978,9 +7214,10 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
 
          if (fixup_info[i].r_type != 0)
            {
 
          if (fixup_info[i].r_type != 0)
            {
+             final_r_type = fixup_info[i].r_type;
              fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
                                  fixup_size, &exp, pcrel,
              fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
                                  fixup_size, &exp, pcrel,
-                                 fixup_info[i].r_type);
+                                 final_r_type);
              fixP->fx_addnumber = fixP->fx_offset;
            }
        }
              fixP->fx_addnumber = fixP->fx_offset;
            }
        }
@@ -6079,9 +7316,6 @@ md_number_to_chars (char *buf, valueT val, int n)
     number_to_chars_littleendian (buf, val, n);
 }
 
     number_to_chars_littleendian (buf, val, n);
 }
 
-/* Equal to MAX_PRECISION in atof-ieee.c.  */
-#define MAX_LITTLENUMS 6
-
 /* This function is called to convert an ASCII string into a floating point
    value in format used by the CPU.  */
 
 /* This function is called to convert an ASCII string into a floating point
    value in format used by the CPU.  */
 
@@ -6204,12 +7438,12 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   seginfo = seg_info (sec);
   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
     return;
   seginfo = seg_info (sec);
   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
     return;
-  /* If there is no relocation and relax is disabled, it is not necessary to
-     insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization.  */
+
   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
     if (!fixp->fx_done)
       break;
   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
     if (!fixp->fx_done)
       break;
-  if (!fixp && !enable_relax_ex9 && !verbatim)
+
+  if (!fixp && !verbatim && ict_flag == ICT_NONE)
     return;
 
   subseg_change (sec, 0);
     return;
 
   subseg_change (sec, 0);
@@ -6217,7 +7451,7 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   /* Set RELAX_ENTRY flags for linker.  */
   fragP = seginfo->frchainP->frch_root;
   exp.X_op = O_symbol;
   /* Set RELAX_ENTRY flags for linker.  */
   fragP = seginfo->frchainP->frch_root;
   exp.X_op = O_symbol;
-  exp.X_add_symbol = section_symbol (sec);
+  exp.X_add_symbol = abs_section_sym;
   exp.X_add_number = 0;
   if (!enable_relax_relocs)
     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
   exp.X_add_number = 0;
   if (!enable_relax_relocs)
     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
@@ -6226,12 +7460,12 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
       /* These flags are only enabled when global relax is enabled.
         Maybe we can check DISABLE_RELAX_FLAG at link-time,
         so we set them anyway.  */
       /* These flags are only enabled when global relax is enabled.
         Maybe we can check DISABLE_RELAX_FLAG at link-time,
         so we set them anyway.  */
-      if (enable_relax_ex9)
-       exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
-      if (enable_relax_ifc)
-       exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
       if (verbatim)
        exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
       if (verbatim)
        exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
+      if (ict_flag == ICT_SMALL)
+       exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL;
+      else if (ict_flag == ICT_LARGE)
+       exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE;
     }
   if (optimize)
     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
     }
   if (optimize)
     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
@@ -6331,13 +7565,13 @@ compar_relent (const void *lhs, const void *rhs)
    relocation.  */
 
 void
    relocation.  */
 
 void
-nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
-                         unsigned int n ATTRIBUTE_UNUSED)
+nds32_set_section_relocs (asection *sec ATTRIBUTE_UNUSED,
+                         arelent **relocs, unsigned int n)
 {
 {
-  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);
+  if (n <= 1)
+    return;
+
+  nds32_insertion_sort (relocs, n, sizeof (*relocs), compar_relent);
 }
 
 long
 }
 
 long
@@ -6464,12 +7698,12 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       fixP->tc_fix_data = NULL;
 
       /* Transform specific relocations here for later relocation generation.
       fixP->tc_fix_data = NULL;
 
       /* Transform specific relocations here for later relocation generation.
-        Tag data here for ex9 relaxation and tag tls data for linker.  */
+        Tag tls data for linker.  */
       switch (fixP->fx_r_type)
        {
        case BFD_RELOC_NDS32_DATA:
       switch (fixP->fx_r_type)
        {
        case BFD_RELOC_NDS32_DATA:
-         if (!enable_relax_ex9)
-           fixP->fx_done = 1;
+         /* This reloc is obselete, we do not need it so far.  */
+         fixP->fx_done = 1;
          break;
        case BFD_RELOC_NDS32_TPOFF:
        case BFD_RELOC_NDS32_TLS_LE_HI20:
          break;
        case BFD_RELOC_NDS32_TPOFF:
        case BFD_RELOC_NDS32_TLS_LE_HI20:
@@ -6479,6 +7713,12 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        case BFD_RELOC_NDS32_GOTTPOFF:
        case BFD_RELOC_NDS32_TLS_IE_HI20:
        case BFD_RELOC_NDS32_TLS_IE_LO12S2:
        case BFD_RELOC_NDS32_GOTTPOFF:
        case BFD_RELOC_NDS32_TLS_IE_HI20:
        case BFD_RELOC_NDS32_TLS_IE_LO12S2:
+       case BFD_RELOC_NDS32_TLS_DESC_HI20:
+       case BFD_RELOC_NDS32_TLS_DESC_LO12:
+       case BFD_RELOC_NDS32_TLS_IE_LO12:
+       case BFD_RELOC_NDS32_TLS_IEGP_HI20:
+       case BFD_RELOC_NDS32_TLS_IEGP_LO12:
+       case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
          break;
        default:
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
          break;
        default:
@@ -6661,13 +7901,14 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   return reloc;
 }
 
   return reloc;
 }
 
-struct suffix_name suffix_table[] =
+static struct suffix_name suffix_table[] =
 {
 {
-  {"GOTOFF",   BFD_RELOC_NDS32_GOTOFF, 1},
-  {"GOT",      BFD_RELOC_NDS32_GOT20,  1},
-  {"TPOFF",    BFD_RELOC_NDS32_TPOFF,  0},
-  {"PLT",      BFD_RELOC_NDS32_25_PLTREL,      1},
-  {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF,       0}
+  {"GOTOFF",   BFD_RELOC_NDS32_GOTOFF},
+  {"GOT",      BFD_RELOC_NDS32_GOT20},
+  {"TPOFF",    BFD_RELOC_NDS32_TPOFF},
+  {"PLT",      BFD_RELOC_NDS32_25_PLTREL},
+  {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF},
+  {"TLSDESC",  BFD_RELOC_NDS32_TLS_DESC},
 };
 
 /* Implement md_parse_name.  */
 };
 
 /* Implement md_parse_name.  */
@@ -6688,7 +7929,7 @@ nds32_parse_name (char const *name, expressionS *exprP,
 
   /* Check the special name if a symbol.  */
   segment = S_GET_SEGMENT (exprP->X_add_symbol);
 
   /* Check the special name if a symbol.  */
   segment = S_GET_SEGMENT (exprP->X_add_symbol);
-  if (segment != undefined_section)
+  if ((segment != undefined_section) && (*nextcharP != '@'))
     return 0;
 
   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
     return 0;
 
   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
@@ -6702,13 +7943,11 @@ nds32_parse_name (char const *name, expressionS *exprP,
       char *next;
       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
        {
       char *next;
       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
        {
-         next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
+         next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
          if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
                           strlen (suffix_table[i].suffix)) == 0
              && !is_part_of_name (*next))
            {
          if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
                           strlen (suffix_table[i].suffix)) == 0
              && !is_part_of_name (*next))
            {
-             if (!nds32_pic && suffix_table[i].pic)
-               as_bad (_("need PIC qualifier with symbol."));
              exprP->X_md = suffix_table[i].reloc;
              *input_line_pointer = *nextcharP;
              input_line_pointer = next;
              exprP->X_md = suffix_table[i].reloc;
              *input_line_pointer = *nextcharP;
              input_line_pointer = next;
@@ -6718,6 +7957,7 @@ nds32_parse_name (char const *name, expressionS *exprP,
            }
        }
     }
            }
        }
     }
+
   return 1;
 }
 
   return 1;
 }
 
This page took 0.086566 seconds and 4 git commands to generate.