gdb/fortran: Support for single/double type modifiers
[deliverable/binutils-gdb.git] / gas / config / tc-nds32.c
index 01bc17b6c22e8f09feccaa3b88a9ec44e07db966..a75dd9ada9c89c3bc9ab89a5356db2d125f2a56c 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 #include "hash.h"
 #include "sb.h"
 #include "macro.h"
-#include "struc-symbol.h"
 #include "opcode/nds32.h"
 
 #include <stdio.h>
+#include <errno.h>
+#include <limits.h>
 
 /* GAS definitions.  */
 
@@ -66,6 +67,8 @@ struct nds32_relocs_pattern
   struct nds32_opcode *opcode;
   char *where;
   struct nds32_relocs_pattern *next;
+  /* Assembled instruction bytes.  */
+  uint32_t insn;
 };
 
 /* Suffix name and relocation.  */
@@ -73,7 +76,6 @@ struct suffix_name
 {
   const char *suffix;
   short unsigned int reloc;
-  int pic;
 };
 static int vec_size = 0;
 /* If the assembly code is generated by compiler, it is supposed to have
@@ -87,10 +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;
-/* The value will be used in RELAX_ENTRY.  */
-static int enable_relax_ex9 = 0;
-/* The value will be used in RELAX_ENTRY.  */
-static int enable_relax_ifc = 0;
 /* Save option -O for performance.  */
 static int optimize = 0;
 /* Save option -Os for code size.  */
@@ -110,60 +108,78 @@ enum ict_option {
 };
 static enum ict_option ict_flag = ICT_NONE;
 \f
+
 static struct hash_control *nds32_relax_info_hash;
+
+/* Branch patterns.  */
 static relax_info_t relax_table[] =
 {
   {
-    "jal",                                     /* opcode */
-    BR_RANGE_S16M,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "jal",
+    .br_range = BR_RANGE_S16M,
+    .cond_field =
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16K */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA
-      }, /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 4, 12},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 4,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -171,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}
-      } /* 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 */
+    .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_S16K */
-      {
-        INSN_BLTZAL /* bltzal $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-       INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZAL     /* bgezal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-       INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA /* jral $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BGEZAL     /* bgezal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
        {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
        {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
        {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
-    "bgezal",                                  /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BGEZAL /* bgezal $rt, label */
-      }, /* BR_RANGE_S256 */
+    .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_S16K */
-      {
-        INSN_BGEZAL /* bgezal $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_JAL /* jal label */
-      }, /* BR_RANGE_S16M */
+       INSN_BLTZAL     /* bltzal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JRAL_TA /* jral $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BLTZAL     /* bltzal $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_JAL        /* jal label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JRAL_TA    /* jral $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
        {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
        {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -341,60 +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}
-      } /* 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] =
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -402,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}
-      } /* 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] =
       {
-        {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] =
+      {
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 4,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 12,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
-        {0, 4, 0, BFD_RELOC_NDS32_HI20},
+       {0, 4, 0, BFD_RELOC_NDS32_HI20},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
        {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -463,85 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "beqz",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S16K */
+    .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_S64K */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-       {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
+      {
+       /* bnez range is 17 pcrel, but it use 15 pcrel here since link time
+          relaxtion.  If 17 pcrel can reach, it do not have to use S16M.
+          Therefore, 15 pcrel is just for linker to distinguish LONGJUMP5
+          and LONGJUMP6.  */
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {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},
@@ -551,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},
-        {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 */
-      {
-        INSN_BGEZ /* bgez $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BGEZ /* bgez $rt, label */
-      }, /* BR_RANGE_S64K */
+    .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_BLTZ, /* bltz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BLTZ, /* bltz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BGEZ       /* bgez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZ       /* bgez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BLTZ,      /* bltz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -637,85 +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}
-      } /* 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_INSN16 , BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -726,82 +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}
-      } /* 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_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -811,82 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "blez",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
+    .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_S256 */
-      {
-        INSN_BLEZ /* blez $rt, label */
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BLEZ /* blez $rt, label */
-      }, /* BR_RANGE_S64K */
+       INSN_BLEZ       /* blez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        INSN_BGTZ, /* bgtz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        INSN_BGTZ, /* bgtz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BLEZ       /* blez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGTZ,      /* bgtz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BGTZ,      /* bgtz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -896,82 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "bltz",                                    /* opcode */
-    BR_RANGE_S64K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "bltz",
+    .br_range = BR_RANGE_S64K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BLTZ /* bltz $rt, label */
-      }, /* BR_RANGE_S64K */
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        INSN_BGEZ, /* bgez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BLTZ       /* bltz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 4, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BGEZ,      /* bgez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE},
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
        {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
@@ -981,97 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "beq",                                     /* opcode */
-    BR_RANGE_S16K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 15, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BEQ /* beq $rt, $ra, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BEQ /* beq $rt, $ra, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNE, /* bne $rt, $ra, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+    .opcode = "beq",
+    .br_range = BR_RANGE_S16K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQ        /* beq $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQ        /* beq $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-       {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BNE,       /* bne $rt, $ra, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1082,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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "bne",                                     /* opcode */
-    BR_RANGE_S16K,                             /* br_range */
-    {
-      {0, 20, 0x1F, FALSE},
-      {0, 15, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
-      {
-        INSN_BNE /* bne $rt, $ra, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNE /* bne $rt, $ra, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQ, /* beq $rt, $ra, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+    .opcode = "bne",
+    .br_range = BR_RANGE_S16K,
+    .cond_field =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNE        /* bne $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BNE        /* bne $rt, $ra, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 15, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 4, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQ,       /* beq $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BEQ,       /* beq $rt, $ra, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 15, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       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, 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},
@@ -1182,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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "beqz38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                         /* cond_field */
-    {
-      {
-        INSN_BEQZ38 << 16 /* beqz $rt, label */
-      }, /* BR_RANGE_S256 */
+    .opcode = "beqz38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BEQZ38 << 16       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQZ /* beqz $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BNEZ, /* bnez $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ       /* beqz $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BNEZ,      /* bnez $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1270,84 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "bnez38",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BNEZ38 << 16 /* bnez $rt, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S16K */
+    .opcode = "bnez38",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+       INSN_BNEZ38 << 16       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_BNEZ /* bnez $rt, label */
-      }, /* BR_RANGE_S64K */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
-      {
-        INSN_BEQZ, /* beqz $rt, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       INSN_BNEZ       /* bnez $rt, label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BEQZ,      /* beqz $rt, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1358,66 +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}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+      },
   },
   {
-    "beqzs8",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "beqzs8",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
       {
-        INSN_BEQZS8 << 16 /* beqz $r15, label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
-        INSN_BEQZ_TA /* bnez $rt, label */
-      }, /* BR_RANGE_S16K */
+       INSN_BEQZS8 << 16       /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_BEQZ_TA /* bnez $rt, label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BNEZ_TA, /* bnez $r15, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_BEQZ_TA    /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        INSN_BNEZ_TA, /* bnez $r15, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQZ_TA    /* beqz $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BNEZ_TA,   /* bnez $r15, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BNEZ_TA,   /* bnez $r15, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1427,67 +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},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
-    "bnezs8",                                  /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {{0, 0, 0, FALSE}},                        /* cond_field */
-    {
+    .opcode = "bnezs8",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
       {
-        INSN_BNEZS8 << 16 /* bnez $r15, label */
-      }, /* BR_RANGE_S256 */
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
       {
-        INSN_BNEZ_TA /* bnez $r15, label */
-      }, /* BR_RANGE_S16K */
+       INSN_BNEZS8 << 16       /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S256] = 2,
+    .relax_branch_isize[BR_RANGE_S256] = 2,
+    .relax_fixup[BR_RANGE_S256] =
       {
-        INSN_BNEZ_TA /* bnez $r15, label */
-      }, /* BR_RANGE_S64K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BEQZ_TA, /* beqz $r15, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_BNEZ_TA    /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        INSN_BEQZ_TA, /* beqz $r15, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
-      {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
-      {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 4, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNEZ_TA    /* bnez $r15, label */
+      },
+    .relax_code_size[BR_RANGE_S64K] = 4,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQZ_TA,   /* beqz $r15, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       INSN_BEQZ_TA,   /* beqz $r15, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1498,89 +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}
-      } /* 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 */
+    .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] =
       {
-        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 */
-    {
-      {
-        {0, 8, 0x7, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BNE_R5     /* bne $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 8, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BEQ_R5,    /* beq $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BEQ_R5,    /* beq $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
       {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       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_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
        {4, 4, 0, BFD_RELOC_NDS32_HI20},
@@ -1591,89 +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}
-      } /* 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 */
+    .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] =
       {
-        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 */
-      {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       INSN_BEQ_R5     /* beq $rt, $r5, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 4,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {2, 4, 8, 8, 16},                          /* relax_code_size */
-    {2, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-       {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       INSN_BNE_R5,    /* bne $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
+      {
+       INSN_BNE_R5,    /* bne $rt, $r5, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
+      {
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
        {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
        {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
        {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       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},
@@ -1684,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}
-      } /* 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},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
+       {0, 0, 0, 0}
+      },
   },
   {
-    "bnec",                                    /* opcode */
-    BR_RANGE_S256,                             /* br_range */
-    {
-      {0, 8, 0x7FF, TRUE},
-      {0, 20, 0x1F, FALSE},
-      {0, 0, 0, FALSE}
-    },                                                 /* cond_field */
-    {
-      {
-        INSN_BNEC /* bnec $rt, imm11s, label */
-      }, /* BR_RANGE_S256 */
-      {
-        INSN_MOVI_TA, /* movi $ta, imm11s */
-        INSN_BNE_TA /* bne $rt, $ta, label */
-      }, /* BR_RANGE_S16K */
-      {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S64K */
+    .opcode = "bnec",
+    .br_range = BR_RANGE_S256,
+    .cond_field =
+      {
+       {0, 8, 0x7FF, TRUE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_seq[BR_RANGE_S256] =
+      {
+         INSN_BNEC     /* bnec $rt, imm11s, label */
+      },
+    .relax_code_condition[BR_RANGE_S256] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S256] = 4,
+    .relax_branch_isize[BR_RANGE_S256] = 4,
+    .relax_fixup[BR_RANGE_S256] =
+      {
+       {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16K] =
       {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_J /* j label */
-      }, /* BR_RANGE_S16M */
+       INSN_MOVI_TA,   /* movi $ta, imm11s */
+       INSN_BNE_TA     /* bne $rt, $ta, label */
+      },
+    .relax_code_condition[BR_RANGE_S16K] =
       {
-        INSN_BEQC, /* beqc $rt, imm11s, $1 */
-        INSN_SETHI_TA, /* sethi $ta, label */
-        INSN_ORI_TA, /* ori $ta, $ta, label */
-        INSN_JR_TA /* jr $ta */
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_seq */
-    {
+       {0, 0, 0xFFFFF, FALSE},
+       {4, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16K] = 8,
+    .relax_branch_isize[BR_RANGE_S16K] = 4,
+    .relax_fixup[BR_RANGE_S16K] =
       {
-        {0, 8, 0x7FF, TRUE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S256 */
+       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S64K] =
       {
-        {0, 0, 0xFFFFF, FALSE},
-        {4, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16K */
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S64K] =
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S64K */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S64K] = 8,
+    .relax_branch_isize[BR_RANGE_S64K] = 4,
+    .relax_fixup[BR_RANGE_S64K] =
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      }, /* BR_RANGE_S16M */
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_S16M] =
       {
-        {0, 8, 0x7FF, FALSE},
-        {0, 20, 0x1F, FALSE},
-        {0, 0, 0, FALSE}
-      } /* BR_RANGE_U4G */
-    },                                         /* relax_code_condition */
-    {4, 8, 8, 8, 16},                          /* relax_code_size */
-    {4, 4, 4, 4, 4},                           /* relax_branch_isize */
-    {
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_J          /* j label */
+      },
+    .relax_code_condition[BR_RANGE_S16M] =
       {
-        {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S256 */
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_S16M] = 8,
+    .relax_branch_isize[BR_RANGE_S16M] = 4,
+    .relax_fixup[BR_RANGE_S16M] =
       {
-       {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
-       {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
-       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S64K */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
-        {0, 0, 0, 0}
-      }, /* BR_RANGE_S16M */
-      {
-        {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
-        {4, 4, 0, BFD_RELOC_NDS32_HI20},
-        {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
+       {0, 0, 0, 0}
+      },
+
+    .relax_code_seq[BR_RANGE_U4G] =
+      {
+       INSN_BEQC,      /* beqc $rt, imm11s, $1 */
+       INSN_SETHI_TA,  /* sethi $ta, label */
+       INSN_ORI_TA,    /* ori $ta, $ta, label */
+       INSN_JR_TA      /* jr $ta */
+      },
+    .relax_code_condition[BR_RANGE_U4G] =
+      {
+       {0, 8, 0x7FF, FALSE},
+       {0, 20, 0x1F, FALSE},
+       {0, 0, 0, FALSE}
+      },
+    .relax_code_size[BR_RANGE_U4G] = 16,
+    .relax_branch_isize[BR_RANGE_U4G] = 4,
+    .relax_fixup[BR_RANGE_U4G] =
+      {
+       {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
+       {4, 4, 0, BFD_RELOC_NDS32_HI20},
+       {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
        {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
-        {0, 0, 0, 0}
-      } /* BR_RANGE_U4G */
-    }                                          /* relax_fixup */
-  }
+       {0, 0, 0, 0}
+      },
+  },
+  {
+    .opcode = NULL,
+  },
 };
 \f
+
 /* GAS definitions for command-line options.  */
 enum options
 {
@@ -1935,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 void add_mapping_symbol (enum mstate state,
+                               unsigned int padding_byte,
+                               unsigned int align);
 
 static struct nds32_parse_option_table parse_opts [] =
 {
@@ -1959,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_dx_regs = 1;
-static int nds32_perf_ext = 1;
-static int nds32_perf_ext2 = 1;
-static int nds32_string_ext = 1;
-static int nds32_audio_ext = 1;
+static int nds32_dx_regs = NDS32_DEFAULT_DX_REGS;
+static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT;
+static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2;
+static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT;
+static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT;
+static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT;
+static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT;
 static int nds32_fpu_fma = 0;
 static int nds32_pic = 0;
 static int nds32_relax_fp_as_gp = 1;
@@ -1994,6 +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},
+  {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1},
+  {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1},
   {NULL, NULL, NULL, 0}
 };
 
@@ -2007,7 +2445,7 @@ nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
                         char **pstr, int64_t *value);
 
 \f
-struct nds32_asm_desc asm_desc;
+static struct nds32_asm_desc asm_desc;
 
 /* md_after_parse_args ()
 
@@ -2196,7 +2634,7 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* b   label */
-  if (nds32_pic && strstr (arg_label, "@PLT"))
+  if (nds32_pic)
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
@@ -2217,12 +2655,11 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
   char *arg_label = argv[0];
   relaxing = TRUE;
   /* bal|call  label */
-  if (nds32_pic
-      && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
+  if (nds32_pic)
     {
       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
-      md_assemble  ((char *) "add $ta,$ta,$gp");
+      md_assemble ((char *) "add $ta,$ta,$gp");
       md_assemble ((char *) "jral $ta");
     }
   else
@@ -2336,7 +2773,7 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label,
 
   relaxing = TRUE;
   /* rt, label */
-  if (!nds32_pic && !strstr(arg_label, "@"))
+  if (!nds32_pic && !strstr (arg_label, "@"))
     {
       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
@@ -2690,11 +3127,11 @@ do_pseudo_pushpopm (int argc, char *argv[],
   /* Reduce register.  */
   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
     {
-      if (re >= 15 && strstr(opc, "smw") != NULL)
+      if (re >= 15 && strstr (opc, "smw") != NULL)
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
       if (rb <= 10)
        md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
-      if (re >= 15 && strstr(opc, "lmw") != NULL)
+      if (re >= 15 && strstr (opc, "lmw") != NULL)
        md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
     }
   else
@@ -2898,7 +3335,7 @@ do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
   md_assemblef ("smw.adm $ta,[%s],$ta", location);
 }
 
-struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
+static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
 {
   {"b",      1, do_pseudo_b,      0, 0},
   {"bal",    1, do_pseudo_bal,    0, 0},
@@ -2974,8 +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
-       push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
-       pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
+     push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
+     pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
@@ -3015,22 +3452,23 @@ nds32_init_nds32_pseudo_opcodes (void)
 static struct nds32_pseudo_opcode *
 nds32_lookup_pseudo_opcode (const char *str)
 {
+  struct nds32_pseudo_opcode *result;
   int i = 0;
-  /* Assume pseudo-opcode are less than 16-char in length.  */
-  char op[16] = {0};
 
-  for (i = 0; i < (int)ARRAY_SIZE (op); i++)
+  /* (*op) is the first word of current source line (*str)  */
+  int maxlen = strlen (str);
+  char *op = xmalloc (maxlen + 1);
+
+  for (i = 0; i < maxlen; i++)
     {
       if (ISSPACE (op[i] = str[i]))
        break;
     }
-
-  if (i >= (int)ARRAY_SIZE (op))
-    return NULL;
-
   op[i] = '\0';
 
-  return hash_find (nds32_pseudo_opcode_hash, op);
+  result = hash_find (nds32_pseudo_opcode_hash, op);
+  free (op);
+  return result;
 }
 
 static void
@@ -3205,6 +3643,10 @@ nds32_all_ext (void)
   nds32_fpu_fma = 1;
   nds32_fpu_sp_ext = 1;
   nds32_fpu_dp_ext = 1;
+  nds32_dsp_ext = 1;
+  nds32_zol_ext = 1;
+  /* Turn off reduced register.  */
+  nds32_gpr16 = 0;
 
   return 1;
 }
@@ -3399,7 +3841,7 @@ do_nds32_seg (int i, subsegT sub)
       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;
        }
@@ -3418,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.  */
 
+static void
+add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align)
+{
+  if ((shift > 1) && (addr & 1))
+    {
+      int n = (1 << shift) - 1;
+      if (!is_data_align)
+       add_mapping_symbol (MAP_CODE, 1, 0);
+      else if ((int) (addr & n) != n)
+       add_mapping_symbol (MAP_CODE, 1, 0);
+    }
+  else if ((shift > 1) && ((int) (addr & 1) == 0))
+    add_mapping_symbol (MAP_CODE, 0, 0);
+}
+
 /* This code is referred from D30V for adjust label to be with pending
    alignment.  For example,
      LBYTE: .byte      0x12
@@ -3451,7 +3908,10 @@ nds32_adjust_label (int n)
   if (frag_now_fix () & ((1 << n) -1 ))
     {
       if (subseg_text_p (now_seg))
-       frag_align_code (n, 0);
+       {
+         add_mapping_symbol_for_align (n, frag_now_fix (), 1);
+         frag_align_code (n, 0);
+       }
       else
        frag_align (n, 0, 0);
 
@@ -3516,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.  */
 }
 
+static void
+make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align)
+{
+  symbolS *symbol_p = NULL;
+  const char *symbol_name = NULL;
+  switch (state)
+    {
+    case MAP_DATA:
+      if (align == 0)
+       symbol_name = "$d0";
+      else if (align == 1)
+       symbol_name = "$d1";
+      else if (align == 2)
+       symbol_name = "$d2";
+      else if (align == 3)
+       symbol_name = "$d3";
+      else if (align == 4)
+       symbol_name = "$d4";
+      break;
+    case MAP_CODE:
+      symbol_name = "$c";
+      break;
+    default:
+      abort ();
+    }
+
+  symbol_p = symbol_new (symbol_name, now_seg, value, frag);
+  /* local scope attribute  */
+  symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL;
+}
+
+static void
+add_mapping_symbol (enum mstate state, unsigned int padding_byte,
+                   unsigned int align)
+{
+  enum mstate current_mapping_state =
+    seg_info (now_seg)->tc_segment_info_data.mapstate;
+
+  if (state == MAP_CODE
+      && current_mapping_state == state)
+    return;
+
+  if (!SEG_NORMAL (now_seg)
+      || !subseg_text_p (now_seg))
+    return;
+
+  /* start adding mapping symbol  */
+  seg_info (now_seg)->tc_segment_info_data.mapstate = state;
+  make_mapping_symbol (state, (valueT) frag_now_fix () + padding_byte,
+                      frag_now, align);
+}
+
 static void
 nds32_aligned_cons (int idx)
 {
   nds32_adjust_label (idx);
+  add_mapping_symbol (MAP_DATA, 0, idx);
   /* Call default handler.  */
   cons (1 << idx);
   if (now_seg->flags & SEC_CODE
       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
     {
-      /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data.  */
+      /* Use BFD_RELOC_NDS32_DATA to avoid linker
+        optimization replacing data.  */
       expressionS exp;
 
       exp.X_add_number = 0;
@@ -3585,7 +4099,7 @@ nds32_relax_relocs (int relax)
   char *name;
   int i;
   const char *subtype_relax[] =
-    {"", "", "ex9", "ifc"};
+    {"", "",};
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
@@ -3602,14 +4116,6 @@ nds32_relax_relocs (int relax)
            case 0:
            case 1:
              enable_relax_relocs = relax & enable_relax_relocs;
-             enable_relax_ex9 = relax & enable_relax_ex9;
-             enable_relax_ifc = relax & enable_relax_ifc;
-             break;
-           case 2:
-             enable_relax_ex9 = relax;
-             break;
-           case 3:
-             enable_relax_ifc = relax;
              break;
            default:
              break;
@@ -3659,31 +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)
 {
@@ -3713,16 +4194,49 @@ struct nds32_relocs_group
 };
 
 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
+/* Used to reorder the id for ".relax_hint id".  */
+static int relax_hint_bias = 0;
+/* Record current relax hint id.  */
+static int relax_hint_id_current = -1;
+int reset_bias = 0;
+/* If ".relax_hint begin" is triggered?  */
+int relax_hint_begin = 0;
+
+/* Record the reordered relax hint id.  */
+
+struct relax_hint_id
+{
+  int old_id;
+  int new_id;
+  struct relax_hint_id *next;
+};
+
+/* FIXME: Need to find somewhere to free the list.  */
+struct relax_hint_id *record_id_head = NULL;
+
+/* Is the buffer large enough?  */
+#define MAX_BUFFER 12
+
+static char *nds_itoa (int n);
+
+static char *
+nds_itoa (int n)
+{
+  char *buf = xmalloc (MAX_BUFFER * sizeof (char));
+  snprintf (buf, MAX_BUFFER, "%d", n);
+  return buf;
+}
 
 /* Insert a relax hint.  */
 
 static void
 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
 {
-  char *name;
+  char *name = NULL;
   char saved_char;
   struct nds32_relocs_pattern *relocs = NULL;
   struct nds32_relocs_group *group, *new;
+  struct relax_hint_id *record_id;
 
   name = input_line_pointer;
   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
@@ -3731,12 +4245,57 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   *input_line_pointer = 0;
   name = strdup (name);
 
+  if (name && strcmp (name, "begin") == 0)
+    {
+      if (relax_hint_id_current == -1)
+       reset_bias = 1;
+      relax_hint_bias++;
+      relax_hint_id_current++;
+      relax_hint_begin = 1;
+    }
+
+  /* Original case ".relax_hint id".  It's id may need to be reordered. */
+  if (!relax_hint_begin)
+    {
+      int tmp = strtol (name, NULL, 10);
+      record_id = record_id_head;
+      while (record_id)
+       {
+         if (record_id->old_id == tmp)
+           {
+             name = nds_itoa (record_id->new_id);
+             goto reordered_id;
+           }
+         record_id = record_id->next;
+       }
+      if (reset_bias)
+       {
+         relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
+         reset_bias = 0;
+       }
+      relax_hint_id_current = tmp + relax_hint_bias;
+
+      /* Insert the element to the head of the link list.  */
+      struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
+      tmp_id->old_id = tmp;
+      tmp_id->new_id = relax_hint_id_current;
+      tmp_id->next = record_id_head;
+      record_id_head = tmp_id;
+    }
+
+  if (name && strcmp (name, "end") == 0)
+    relax_hint_begin = 0;
+  name = nds_itoa (relax_hint_id_current);
+
+reordered_id:
+
   /* Find relax hint entry for next instruction, and all member will be
      initialized at that time.  */
   relocs = hash_find (nds32_hint_hash, name);
   if (relocs == NULL)
     {
       relocs = XNEW (struct nds32_relocs_pattern);
+      memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
       hash_insert (nds32_hint_hash, name, relocs);
     }
   else
@@ -3745,6 +4304,7 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
        relocs=relocs->next;
       relocs->next = XNEW (struct nds32_relocs_pattern);
       relocs = relocs->next;
+      memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
     }
 
   relocs->next = NULL;
@@ -3757,6 +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);
+  memset (new, 0, sizeof (struct nds32_relocs_group));
   new->pattern = relocs;
   new->next = NULL;
   group = nds32_relax_hint_current;
@@ -3840,6 +4401,7 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED)
   *input_line_pointer = saved_char;
   ignore_rest_of_line ();
 }
+
 static void
 ict_model (int ignore ATTRIBUTE_UNUSED)
 {
@@ -3940,8 +4502,6 @@ const pseudo_typeS md_pseudo_table[] =
   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   {"omit_fp_end", nds32_omit_fp_begin, 0},
-  {"no_ex9_begin", nds32_no_ex9_begin, 1},
-  {"no_ex9_end", nds32_no_ex9_begin, 0},
   {"vec_size", nds32_vec_size, 0},
   {"flag", nds32_flag, 0},
   {"innermost_loop_begin", nds32_loop_begin, 1},
@@ -3964,6 +4524,7 @@ nds32_pre_do_align (int n, char *fill, int len, int max)
            {
              dwarf2_emit_insn (0);
              fragP = frag_now;
+             add_mapping_symbol_for_align (n, frag_now_fix (), 0);
              frag_align_code (n, max);
 
              /* Tag this alignment when there is a label before it.  */
@@ -4050,13 +4611,16 @@ void
 md_begin (void)
 {
   struct nds32_keyword *k;
-  unsigned int i;
+  relax_info_t *relax_info;
+  int flags = 0;
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
 
   nds32_init_nds32_pseudo_opcodes ();
   asm_desc.parse_operand = nds32_asm_parse_operand;
-  nds32_asm_init (&asm_desc, 0);
+  if (nds32_gpr16)
+    flags |= NASM_OPEN_REDUCED_REG;
+  nds32_asm_init (&asm_desc, flags);
 
   /* Initial general purpose registers hash table.  */
   nds32_gprs_hash = hash_new ();
@@ -4065,9 +4629,8 @@ md_begin (void)
 
   /* Initial branch hash table.  */
   nds32_relax_info_hash = hash_new ();
-  for (i = 0; i < ARRAY_SIZE (relax_table); i++)
-    hash_insert (nds32_relax_info_hash, relax_table[i].opcode,
-                &relax_table[i]);
+  for (relax_info = relax_table; relax_info->opcode; relax_info++)
+    hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
 
   /* Initial relax hint hash table.  */
   nds32_hint_hash = hash_new ();
@@ -4185,11 +4748,12 @@ get_range_type (const struct nds32_field *field)
 /* Save pseudo instruction relocation list.  */
 
 static struct nds32_relocs_pattern*
-nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
+nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
                               char *out, symbolS *sym,
                               struct nds32_relocs_pattern *reloc_ptr,
                               fragS *fragP)
 {
+  struct nds32_opcode *opcode = insn->opcode;
   if (!reloc_ptr)
     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   reloc_ptr->seg = now_seg;
@@ -4199,6 +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->insn = insn->insn;
   reloc_ptr->next = NULL;
   return reloc_ptr;
 }
@@ -4240,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_IE_HI20;
+         reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
+         break;
+       case BFD_RELOC_NDS32_TLS_DESC:  /* @TLSDESC */
+         reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
          break;
-       default:        /* No suffix.  */
-         reloc = BFD_RELOC_NDS32_HI20;
+       default:        /* No suffix */
+         if (nds32_pic)
+           /* When the file is pic, the address must be offset to gp.
+              It may define another relocation or use GOTOFF.  */
+           reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
+         else
+           reloc = BFD_RELOC_NDS32_HI20;
          break;
        }
       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
@@ -4275,8 +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;
-           default:    /* No suffix.  */
-             reloc = BFD_RELOC_NDS32_LO12S0;
+           case BFD_RELOC_NDS32_GOTTPOFF:      /* @GOTTPOFF */
+             reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
+             break;
+           case BFD_RELOC_NDS32_TLS_DESC:      /* @TLSDESC */
+             reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
+             break;
+           default:    /* No suffix */
+             if (nds32_pic)
+               /* When the file is pic, the address must be offset to gp.
+                  It may define another relocation or use GOTOFF.  */
+               reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
+             else
+               reloc = BFD_RELOC_NDS32_LO12S0;
              break;
            }
        }
@@ -4288,9 +4872,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
          switch (pexp->X_md)
            {
            case BFD_RELOC_NDS32_GOTTPOFF:      /* @GOTTPOFF */
-             reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
+             reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
              break;
-           default:    /* No suffix */
+           default:    /* No suffix */
              reloc = BFD_RELOC_NDS32_LO12S2;
              break;
            }
@@ -4298,7 +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)
-       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);
@@ -4354,20 +4938,6 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
       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);
     }
@@ -4382,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,
-                               struct nds32_opcode *opcode, fragS *fragP,
-                               const struct nds32_field *fld)
+                               struct nds32_asm_insn *insn, fragS *fragP,
+                               const struct nds32_field *fld,
+                               bfd_boolean pseudo_hint)
 {
   struct nds32_relocs_pattern *reloc_ptr;
   struct nds32_relocs_group *group;
@@ -4393,10 +4964,32 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
   if (fld)
     sym = pexp->X_add_symbol;
 
-  if (pseudo_opcode)
+  if (pseudo_hint)
+    {
+      /* We cannot know how many instructions will be expanded for
+        the pseudo instruction here.  The first expanded instruction fills
+        the memory created by relax_hint.  The follower will created and link
+        here.  */
+      group = nds32_relax_hint_current;
+      while (group)
+       {
+         if (group->pattern->opcode == NULL)
+           nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
+                                          group->pattern, fragP);
+         else
+           {
+             group->pattern->next =
+               nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
+                                              NULL, fragP);
+             group->pattern = group->pattern->next;
+           }
+         group = group->next;
+       }
+    }
+  else if (pseudo_opcode)
     {
       /* Save instruction relation for pseudo instruction expanding pattern.  */
-      reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+      reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
                                                 NULL, fragP);
       if (!relocs_list)
        relocs_list = reloc_ptr;
@@ -4414,7 +5007,7 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
       group = nds32_relax_hint_current;
       while (group)
        {
-         nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+         nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
                                         group->pattern, fragP);
          group = group->next;
          free (nds32_relax_hint_current);
@@ -4430,40 +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.  */
+/* Relaxation types only! relocation types are not necessary.  */
+/* Refer to nds32_elf_record_fixup_exp ().  */
 
 static struct nds32_relax_hint_table relax_ls_table[] =
 {
   {
-    /* Set address: la -> sethi ori.  */
-    NDS32_RELAX_HINT_LA,       /* main_type */
-    8,                         /* relax_code_size */
-    {
-      OP6 (SETHI),
-      OP6 (ORI),
-    },                         /* relax_code_seq */
-    {
-      {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
-      {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
-    }                          /* relax_fixup */
+    /* LA and Floating LSI.  */
+    .main_type = NDS32_RELAX_HINT_LA_FLSI,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
   },
   {
-    /* Set address: l.w -> sethi ori.  */
-    NDS32_RELAX_HINT_LS,       /* main_type */
-    8,                         /* relax_code_size */
-    {
-      OP6 (SETHI),
-      OP6 (LBI),
-    },                         /* relax_code_seq */
-    {
-      {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
-      {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
-    }                          /* relax_fixup */
+    /* Load Address / Load-Store (LALS).  */
+    .main_type = NDS32_RELAX_HINT_LALS,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
   },
   {
-    0,
-    0,
-    {0},
-    {{0, 0 , 0, 0}}
+    /* B(AL) symbol@PLT  */
+    .main_type = NDS32_RELAX_HINT_LA_PLT,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (JREG),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* LA (@GOT).  */
+    .main_type = NDS32_RELAX_HINT_LA_GOT,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* LA (@GOTOFF).  */
+    .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS LE LS|LA */
+    .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
+    .relax_code_size = 16,
+    .relax_code_seq =
+      {
+       OP6(SETHI),
+       OP6(ORI),
+       OP6(MEM),
+       OP6(ALU1),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
+       {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS IE LA */
+    .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
+    .relax_code_size = 8,
+    .relax_code_seq =
+      {
+       OP6(SETHI),
+       OP6(LBI),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS IEGP LA */
+    .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
+    .relax_code_size = 12,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (MEM),
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    /* TLS DESC LS:  */
+    .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
+    .relax_code_size = 24,
+    .relax_code_seq =
+      {
+       OP6 (SETHI),
+       OP6 (ORI),
+       OP6 (ALU1),
+       OP6 (LBI),      /* load argument */
+       OP6 (JREG),
+       OP6 (MEM),      /* load/store variable or load argument */
+      },
+    .relax_fixup =
+      {
+       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+       {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
+       {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
+       {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
+       {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
+       {16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
+       {20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
+       {0, 0, 0, 0}
+      }
+  },
+  {
+    .main_type = 0,
+    .relax_code_seq = {0},
+    .relax_fixup = {{0, 0 , 0, 0}}
   }
 };
 
@@ -4524,122 +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.  */
+
 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
    | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
+#define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
 
 static void
 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
 {
-  /* Set E_NDS32_HAS_EXT_INST.  */
-  if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
-    {
-      if (nds32_perf_ext)
-       nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
-      else
-       as_bad (_("instruction %s requires enabling performance extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
-    {
-      if (nds32_perf_ext2)
-       nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
-      else
-       as_bad (_("instruction %s requires enabling performance extension II"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
-    {
-      if (nds32_audio_ext)
-       nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
-      else
-       as_bad (_("instruction %s requires enabling AUDIO extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
-    {
-      if (nds32_string_ext)
-       nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
-      else
-       as_bad (_("instruction %s requires enabling STRING extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_DIV)
-          && (insn->opcode->attr & NASM_ATTR_DXREG))
-    {
-      if (nds32_div && nds32_dx_regs)
-       nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
-      else
-       as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU)
-    {
-      if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
-       {
-         if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
-           nds32_fpu_com = 1;
-       }
-      else
-       as_bad (_("instruction %s requires enabling FPU extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
-    {
-      if (nds32_fpu_sp_ext)
-       nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
-      else
-       as_bad (_("instruction %s requires enabling FPU_SP extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
-          && (insn->opcode->attr & NASM_ATTR_MAC))
-    {
-      if (nds32_fpu_sp_ext && nds32_mac)
-       {
-         nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
-         nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
-       }
-      else
-       as_bad (_("instruction %s requires enabling FPU_MAC extension"),
-               insn->opcode->opcode);
-    }
-  else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
-    {
-      if (nds32_fpu_dp_ext)
-       nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
-      else
-       as_bad (_("instruction %s requires enabling FPU_DP extension"),
-               insn->opcode->opcode);
-    }
-  else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
-          && (insn->opcode->attr & NASM_ATTR_MAC))
+  static int skip_flags = NASM_ATTR_FPU_FMA
+    | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT
+    | NASM_ATTR_GPREL | NASM_ATTR_DXREG
+    | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2
+    | NASM_ATTR_ISA_V3 | NASM_ATTR_ISA_V3M
+    | NASM_ATTR_PCREL;
+
+  int new_flags = insn->opcode->attr & ~skip_flags;
+  while (new_flags)
     {
-      if (nds32_fpu_dp_ext && nds32_mac)
+      int next = 1 << (ffs (new_flags) - 1);
+      new_flags &= ~next;
+      switch (next)
        {
-         nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
-         nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+       case NASM_ATTR_PERF_EXT:
+         {
+           if (nds32_perf_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
+               skip_flags |= NASM_ATTR_PERF_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling performance "
+                       "extension"), insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_PERF2_EXT:
+         {
+           if (nds32_perf_ext2)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
+               skip_flags |= NASM_ATTR_PERF2_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling performance "
+                       "extension II"), insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_AUDIO_ISAEXT:
+         {
+           if (nds32_audio_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
+               skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling AUDIO extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_STR_EXT:
+         {
+           if (nds32_string_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
+               skip_flags |= NASM_ATTR_STR_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling STRING extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_DIV:
+         {
+           if (insn->opcode->attr & NASM_ATTR_DXREG)
+             {
+               if (nds32_div && nds32_dx_regs)
+                 {
+                   nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
+                   skip_flags |= NASM_ATTR_DIV;
+                 }
+               else
+                 as_bad (_("instruction %s requires enabling DIV & DX_REGS "
+                           "extension"), insn->opcode->opcode);
+             }
+         }
+         break;
+       case NASM_ATTR_FPU:
+         {
+           if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
+             {
+               if (!(nds32_elf_flags
+                     & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
+                 nds32_fpu_com = 1;
+               skip_flags |= NASM_ATTR_FPU;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_FPU_SP_EXT:
+         {
+           if (nds32_fpu_sp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
+               skip_flags |= NASM_ATTR_FPU_SP_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU_SP extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_FPU_DP_EXT:
+         {
+           if (nds32_fpu_dp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+               skip_flags |= NASM_ATTR_FPU_DP_EXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling FPU_DP extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_MAC:
+         {
+           if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
+             {
+               if (nds32_fpu_sp_ext && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+               else
+                 as_bad (_("instruction %s requires enabling FPU_MAC "
+                           "extension"), insn->opcode->opcode);
+             }
+           else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
+             {
+               if (nds32_fpu_dp_ext && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+               else
+                 as_bad (_("instruction %s requires enabling FPU_MAC "
+                           "extension"), insn->opcode->opcode);
+             }
+           else if (insn->opcode->attr & NASM_ATTR_DXREG)
+             {
+               if (nds32_dx_regs && nds32_mac)
+                 nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
+               else
+                 as_bad (_("instruction %s requires enabling DX_REGS "
+                           "extension"), insn->opcode->opcode);
+             }
+
+           if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
+             skip_flags |= NASM_ATTR_MAC;
+         }
+         break;
+       case NASM_ATTR_DSP_ISAEXT:
+         {
+           if (nds32_dsp_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
+               skip_flags |= NASM_ATTR_DSP_ISAEXT;
+             }
+           else
+             as_bad (_("instruction %s requires enabling dsp extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       case NASM_ATTR_ZOL:
+         {
+           if (nds32_zol_ext)
+             {
+               nds32_elf_flags |= E_NDS32_HAS_ZOL;
+               skip_flags |= NASM_ATTR_ZOL;
+             }
+           else
+             as_bad (_("instruction %s requires enabling zol extension"),
+                     insn->opcode->opcode);
+         }
+         break;
+       default:
+         as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
+                 next);
        }
-      else
-       as_bad (_("instruction %s requires enabling FPU_MAC extension"),
-               insn->opcode->opcode);
-    }
-  /* TODO: FPU_BOTH */
-  else if ((insn->opcode->attr & NASM_ATTR_MAC)
-          && (insn->opcode->attr & NASM_ATTR_DXREG))
-    {
-      if (nds32_mac && nds32_dx_regs)
-       nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
-      else
-       as_bad (_("instruction %s requires enabling DX_REGS extension"),
-               insn->opcode->opcode);
     }
-  /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
-  else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
-    {
-      nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
-    }
-  /* TODO: E_NDS32_HAS_SATURATION_INST */
 }
 
 /* Flag for analysis relaxation type.  */
@@ -4654,97 +5474,199 @@ enum nds32_insn_type
   N32_RELAX_ORI = (1 << 5),
   N32_RELAX_MEM = (1 << 6),
   N32_RELAX_MOVI = (1 << 7),
+  N32_RELAX_ALU1 = (1 << 8),
+  N32_RELAX_16BIT = (1 << 9),
 };
 
 struct nds32_hint_map
 {
+  /* the preamble relocation */
   bfd_reloc_code_real_type hi_type;
+  /* mnemonic */
   const char *opc;
+  /* relax pattern ID */
   enum nds32_relax_hint_type hint_type;
+  /* range */
   enum nds32_br_range range;
+  /* pattern character flags */
   enum nds32_insn_type insn_list;
+  /* optional pattern character flags */
+  enum nds32_insn_type option_list;
 };
 
 /* Table to match instructions with hint and relax pattern.  */
 
 static struct nds32_hint_map hint_map [] =
 {
-    {
-      /* LONGCALL4.  */
-      BFD_RELOC_NDS32_HI20,
-      "jal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
-    },
-    {
-      /* LONGCALL5.  */
-      _dummy_first_bfd_reloc_code_real,
-      "bgezal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16M,
-      N32_RELAX_BR | N32_RELAX_CALL
-    },
-    {
-      /* LONGCALL6.  */
-      BFD_RELOC_NDS32_HI20,
-      "bgezal",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
-    },
-    {
-      /* LONGJUMP4.  */
-      BFD_RELOC_NDS32_HI20,
-      "j",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP5.  */
-      /* There is two kinds of variations of LONGJUMP5.  One of them
-        generate EMPTY relocation for converted INSN16 if needed.
-        But we don't distinguish them here.  */
-      _dummy_first_bfd_reloc_code_real,
-      "beq",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16M,
-      N32_RELAX_BR | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP6.  */
-      BFD_RELOC_NDS32_HI20,
-      "beq",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
-    },
-    {
-      /* LONGJUMP7.  */
-      _dummy_first_bfd_reloc_code_real,
-      "beqc",
-      NDS32_RELAX_HINT_NONE,
-      BR_RANGE_S16K,
-      N32_RELAX_MOVI | N32_RELAX_BR
-    },
-    {
-      /* LOADSTORE ADDRESS.  */
-      BFD_RELOC_NDS32_HI20,
-      NULL,
-      NDS32_RELAX_HINT_LA,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_ORI
-    },
-    {
-      /* LOADSTORE ADDRESS.  */
-      BFD_RELOC_NDS32_HI20,
-      NULL,
-      NDS32_RELAX_HINT_LS,
-      BR_RANGE_U4G,
-      N32_RELAX_SETHI | N32_RELAX_LSI
-    },
-    {0, NULL, 0, 0 ,0}
+  {
+    /* LONGCALL4.  */
+    BFD_RELOC_NDS32_HI20,
+    "jal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGCALL5.  */
+    _dummy_first_bfd_reloc_code_real,
+    "bgezal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16M,
+    N32_RELAX_BR | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGCALL6.  */
+    BFD_RELOC_NDS32_HI20,
+    "bgezal",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
+    0,
+  },
+  {
+    /* LONGJUMP4.  */
+    BFD_RELOC_NDS32_HI20,
+    "j",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP5.  */
+    /* There is two kinds of variation of LONGJUMP5.  One of them
+       generate EMPTY relocation for converted INSN16 if needed.
+       But we don't distinguish them here.  */
+    _dummy_first_bfd_reloc_code_real,
+    "beq",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16M,
+    N32_RELAX_BR | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP6.  */
+    BFD_RELOC_NDS32_HI20,
+    "beq",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
+    0,
+  },
+  {
+    /* LONGJUMP7.  */
+    _dummy_first_bfd_reloc_code_real,
+    "beqc",
+    NDS32_RELAX_HINT_NONE,
+    BR_RANGE_S16K,
+    N32_RELAX_MOVI | N32_RELAX_BR,
+    0,
+  },
+  {
+    /* LONGCALL (BAL|JR|LA symbol@PLT).  */
+    BFD_RELOC_NDS32_PLT_GOTREL_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_PLT,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
+  },
+  /* relative issue: #12566 */
+  {
+    /* LA and Floating LSI.  */
+    BFD_RELOC_NDS32_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_FLSI,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
+    0,
+  },
+  /* relative issue: #11685 #11602 */
+  {
+    /* load address / load-store (LALS).  */
+    BFD_RELOC_NDS32_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LALS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI,
+    N32_RELAX_ORI | N32_RELAX_LSI,
+  },
+  {
+    /* setup $GP (_GLOBAL_OFFSET_TABLE_)  */
+    BFD_RELOC_NDS32_GOTPC_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LALS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    0,
+  },
+  {
+    /* GOT LA/LS (symbol@GOT)  */
+    BFD_RELOC_NDS32_GOT_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_GOT,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_MEM,
+  },
+  {
+    /* GOTOFF LA/LS (symbol@GOTOFF)  */
+    BFD_RELOC_NDS32_GOTOFF_HI20,
+    NULL,
+    NDS32_RELAX_HINT_LA_GOTOFF,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1  | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
+  },
+  {
+    /* TLS LE LA|LS (@TPOFF)  */
+    BFD_RELOC_NDS32_TLS_LE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_LE_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI,
+    N32_RELAX_ALU1 | N32_RELAX_MEM,
+  },
+  {
+    /* TLS IE LA */
+    BFD_RELOC_NDS32_TLS_IE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IE_LA,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_LSI,
+    0,
+  },
+{
+    /* TLS IE LS */
+    BFD_RELOC_NDS32_TLS_IE_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IE_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
+    0,
+  },
+  {
+    /* TLS IEGP LA */
+    BFD_RELOC_NDS32_TLS_IEGP_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_IEGP_LA,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
+    0,
+  },
+  {
+    /* TLS DESC LS */
+    BFD_RELOC_NDS32_TLS_DESC_HI20,
+    NULL,
+    NDS32_RELAX_HINT_TLS_DESC_LS,
+    BR_RANGE_U4G,
+    N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
+    N32_RELAX_LSI | N32_RELAX_MEM,
+  },
+  /* last one */
+  {0, NULL, 0, 0 ,0, 0}
 };
 
 /* Find the relaxation pattern according to instructions.  */
@@ -4786,6 +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_ALU1:
+             relax_type |= N32_RELAX_ALU1;
+             break;
            case N32_OP6_ORI:
              relax_type |= N32_RELAX_ORI;
              break;
@@ -4807,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_LDC:
+           case N32_OP6_SDC:
              relax_type |= N32_RELAX_LSI;
              break;
            case N32_OP6_JREG:
@@ -4829,18 +5756,20 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
        }
       else
        {
-         /* 2 byte instruction.  Compare by opcode name because the opcode of
-            2byte instruction is not regular.  */
-         for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+         /* 2 byte instruction.  Compare by opcode name because
+            the opcode of 2byte instruction is not regular.  */
+         int is_matched = 0;
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
            {
              if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
                {
                  relax_type |= N32_RELAX_BR;
+                 is_matched += 1;
                  break;
                }
            }
-         if (strcmp (pattern->opcode->opcode, "movi55") == 0)
-           relax_type |= N32_RELAX_MOVI;
+         if (!is_matched)
+           relax_type |= N32_RELAX_16BIT;
        }
       pattern = pattern->next;
     }
@@ -4848,23 +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)
     {
-      if (map_ptr->insn_list == relax_type
-         && (!hi_pattern
-             || (hi_pattern->fixP
-                 && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
+      struct nds32_hint_map *hint = map_ptr++;
+      enum nds32_insn_type must = hint->insn_list;
+      enum nds32_insn_type optional = hint->option_list;
+      enum nds32_insn_type extra;
+
+      if (must != (must & relax_type))
+       continue;
+
+      extra = relax_type ^ must;
+      if (extra != (extra & optional))
+       continue;
+
+      if (!hi_pattern
+         || (hi_pattern->fixP
+             && hi_pattern->fixP->fx_r_type == hint->hi_type))
        {
-         opc = map_ptr->opc;
-         hint_type = map_ptr->hint_type;
-         range = map_ptr->range;
+         opc = hint->opc;
+         hint_type = hint->hint_type;
+         range = hint->range;
+         map_ptr = hint;
          break;
        }
-      map_ptr++;
     }
 
   if (map_ptr->insn_list == 0)
     {
-      as_warn (_("Can not find match relax hint.  Line: %d"),
-              relocs_pattern->frag->fr_line);
+      if (!nds32_pic)
+       as_warn (_("Can not find match relax hint.  Line: %d"),
+                relocs_pattern->frag->fr_line);
       return FALSE;
     }
 
@@ -4923,12 +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.  */
 
-#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
+#define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
+#define GET_OPCODE(insn) ((insn) & 0xfe000000)
+
 static bfd_boolean
 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
 {
   const char *check_insn[] =
-    { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+    { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
   uint32_t insn = opcode->value;
   unsigned int i;
 
@@ -4944,22 +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)
-         || insn == OP6 (LWC) || insn == OP6 (SWC))
-        return TRUE;
+         || insn == OP6 (LWC) || insn == OP6 (SWC)
+         || insn == OP6 (LDC) || insn == OP6 (SDC))
+       return TRUE;
       break;
     case OP6 (BR2):
       /* This is for LONGCALL5 and LONGCALL6.  */
       if (insn == OP6 (BR2))
-        return TRUE;
+       return TRUE;
       break;
     case OP6 (BR1):
       /* This is for LONGJUMP5 and LONGJUMP6.  */
       if (opcode->isize == 4
          && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
-        return TRUE;
+       return TRUE;
       else if (opcode->isize == 2)
        {
-         for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
            if (strcmp (opcode->opcode, check_insn[i]) == 0)
              return TRUE;
        }
@@ -4967,8 +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)
-        return TRUE;
+       return TRUE;
+      break;
+    case OP6 (MEM):
+      if (OP6 (MEM) == GET_OPCODE (insn))
+       return TRUE;
       break;
+    case OP6 (JREG):
+      /* bit 24: N32_JI_JAL  */ /* feed me!  */
+      if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
+       return TRUE;
+      break;
+    default:
+      if (opcode->isize == 2)
+       {
+         for (i = 0; i < ARRAY_SIZE (check_insn); i++)
+           if (strcmp (opcode->opcode, check_insn[i]) == 0)
+             return TRUE;
+
+         if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
+             (strcmp (opcode->opcode, "add45") == 0))
+           return TRUE;
+       }
     }
   return FALSE;
 }
@@ -4976,7 +5940,7 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
 /* Append relax relocation for link time relaxing.  */
 
 static void
-nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
+nds32_elf_append_relax_relocs (const char *key, void *value)
 {
   struct nds32_relocs_pattern *relocs_pattern =
     (struct nds32_relocs_pattern *) value;
@@ -4989,7 +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;
-  offsetT branch_offset;
+  offsetT branch_offset, hi_branch_offset = 0;
   fixS *fixP;
   int range, offset;
   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
@@ -5010,6 +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;
+         hi_branch_offset = pattern_now->fixP->fx_offset;
          break;
        }
       pattern_now = pattern_now->next;
@@ -5026,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;
 
+#ifdef NDS32_LINUX_TOOLCHAIN
+  /* prepare group relocation ID (number).  */
+  long group_id = 0;
+  if (key)
+    {
+      /* convert .relax_hint key to number */
+      errno = 0;
+      group_id = strtol (key, NULL, 10);
+      if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
+         || (errno != 0 && group_id == 0))
+       {
+         as_bad (_("Internal error: .relax_hint KEY is not a number!"));
+         goto restore;
+       }
+    }
+#endif
+
   /* Insert relaxation.  */
   exp.X_op = O_symbol;
 
+  /* For each instruction in the hint group.  */
   while (pattern_now)
     {
+      if (count >= relax_code_size / 4)
+       count = 0;
+
       /* Choose the match fixup by instruction.  */
       code_insn = CLEAN_REG (*(code_seq + count));
       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
        {
+         /* Try search from head again */
          count = 0;
          code_insn = CLEAN_REG (*(code_seq + count));
 
@@ -5043,8 +6030,11 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
              count++;
              if (count >= relax_code_size / 4)
                {
-                 as_bad (_("Internal error: Relax hint error. %s: %x"),
-                         now_seg->name, pattern_now->opcode->value);
+                 as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
+                         key,
+                         now_seg->name,
+                         pattern_now->opcode->opcode,
+                         pattern_now->opcode->value);
                  goto restore;
                }
              code_insn = CLEAN_REG (*(code_seq + count));
@@ -5140,7 +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;
-             exp.X_add_number = branch_offset;
+             exp.X_add_number = hi_branch_offset;
+           }
+         else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
+           {
+             /* Do the same as NDS32_SYM.  */
+             exp.X_add_symbol = hi_sym;
+             exp.X_add_number = hi_branch_offset;
+
+             /* Extra to NDS32_SYM.  */
+             /* Detect if DESC_FUNC relax type do apply.  */
+             if ((REG_GP == N32_RA5 (pattern_now->insn))
+                 || (REG_GP == N32_RB5 (pattern_now->insn)))
+               {
+                 fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+                                     fixup_size, &exp, pcrel,
+                                     BFD_RELOC_NDS32_TLS_DESC_FUNC);
+                 fixP->fx_addnumber = fixP->fx_offset;
+
+                 fixup_size = 0;
+               }
+             /* Else do as usual.  */
+           }
+         else if (fixup_now->ramp & NDS32_PTR_PATTERN)
+           {
+             /* Find out PTR_RESOLVED code pattern.  */
+             nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
+             uint32_t resolved_pattern = 0;
+             while (next_fixup->offset)
+               {
+                 if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
+                   {
+                     uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
+                     if (!resolved_pattern)
+                       resolved_pattern = new_pattern;
+                     else if (new_pattern != resolved_pattern)
+                       {
+                         as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
+                                    "patterns are not supported yet!"));
+                         break;
+                       }
+                   }
+                 ++next_fixup;
+               }
+
+             /* Find matched code and insert fix-ups.  */
+             struct nds32_relocs_pattern *next_pattern = pattern_now->next;
+             /* This relocation has to point to another instruction.
+                Make sure each resolved relocation has to be pointed.  */
+             /* All instruction in relax_table should be 32-bit.  */
+             while (next_pattern)
+               {
+                 uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
+                 if (cur_pattern == resolved_pattern)
+                   {
+                     ptr_offset = next_pattern->where
+                       - next_pattern->frag->fr_literal;
+                     exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
+                                                         next_pattern->frag);
+                     exp.X_add_number = 0;
+                     fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+                                         fixup_size, &exp, 0,
+                                         fixup_now->r_type);
+                     fixP->fx_addnumber = fixP->fx_offset;
+                   }
+                 next_pattern = next_pattern->next;
+               }
+
+             fixup_size = 0;
+           }
+         else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
+           {
+             /* Find each PTR_RESOLVED pattern after PTR.  */
+             nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
+             while (next_fixup->offset)
+               {
+                 if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
+                   {
+                     uint32_t pattern = code_seq[next_fixup->offset >> 2];
+                     /* Find matched code to insert fix-ups.  */
+                     struct nds32_relocs_pattern *next_insn = pattern_now->next;
+                     while (next_insn)
+                       {
+                         uint32_t insn_pattern = GET_OPCODE (next_insn->opcode->value);
+                         if (insn_pattern == pattern)
+                           {
+                             ptr_offset = next_insn->where
+                               - next_insn->frag->fr_literal;
+                             exp.X_add_symbol = symbol_temp_new (now_seg,
+                                                                 ptr_offset,
+                                                                 next_insn->frag);
+                             exp.X_add_number = 0;
+                             fixP = fix_new_exp (fragP,
+                                                 where - fragP->fr_literal,
+                                                 fixup_size, &exp, 0,
+                                                 fixup_now->r_type);
+                             fixP->fx_addnumber = fixP->fx_offset;
+                           }
+                         next_insn = next_insn->next;
+                       }
+                   }
+                 ++next_fixup;
+               }
+             fixup_size = 0;
            }
          else
            {
@@ -5157,6 +6249,19 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
          fixup_now++;
          fixup_size = fixup_now->size;
        }
+
+#ifdef NDS32_LINUX_TOOLCHAIN
+      /* Insert group relocation for each relax hint.  */
+      if (key)
+       {
+         exp.X_add_symbol = hi_sym; /* for eyes only */
+         exp.X_add_number = group_id;
+         fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
+                             &exp, pcrel, BFD_RELOC_NDS32_GROUP);
+         fixP->fx_addnumber = fixP->fx_offset;
+       }
+#endif
+
       if (count < relax_code_size / 4)
        count++;
       pattern_now = pattern_now->next;
@@ -5167,6 +6272,19 @@ restore:
   frchain_now = frchain_bak;
 }
 
+static void
+nds32_str_tolower (const char *src, char *dest)
+{
+  unsigned int i, len;
+
+  len = strlen (src);
+
+  for (i = 0; i < len; i++)
+    *(dest + i) = TOLOWER (*(src + i));
+
+  *(dest + i) = '\0';
+}
+
 /* Check instruction if it can be used for the baseline.  */
 
 static bfd_boolean
@@ -5174,6 +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;
+  char *s;
+
+  s = xmalloc (strlen (str) + 1);
+  nds32_str_tolower (str, s);
+  if (verbatim
+      && (((insn.opcode->value == ALU2 (MTUSR)
+           || insn.opcode->value == ALU2 (MFUSR))
+          && (strstr (s, "lc")
+              || strstr (s, "le")
+              || strstr (s, "lb")))
+         || (insn.attr & NASM_ATTR_ZOL)))
+    {
+      as_bad (_("Not support instruction %s in verbatim."), str);
+      return FALSE;
+    }
+  free (s);
+
+  if (!enable_16bit && insn.opcode->isize == 2)
+    {
+      as_bad (_("16-bit instruction is disabled: %s."), str);
+      return FALSE;
+    }
+
   /* No isa setting or all isa can use.  */
   if (attr == 0 || attr == ATTR_ALL)
     return TRUE;
@@ -5209,16 +6350,16 @@ void
 md_assemble (char *str)
 {
   struct nds32_asm_insn insn;
-  expressionS insn_expr;
   char *out;
   struct nds32_pseudo_opcode *popcode;
   const struct nds32_field *fld = NULL;
   fixS *fixP;
   uint16_t insn_16;
   struct nds32_relocs_pattern *relocs_temp;
-  expressionS *pexp;
+  struct nds32_relocs_group *group_temp;
   fragS *fragP;
   int label = label_exist;
+  static bfd_boolean pseudo_hint = FALSE;
 
   popcode = nds32_lookup_pseudo_opcode (str);
   /* Note that we need to check 'verbatim' and
@@ -5227,11 +6368,23 @@ md_assemble (char *str)
      need to perform pseudo instruction expansion/transformation.  */
   if (popcode && !(verbatim && popcode->physical_op))
     {
+      /* Pseudo instruction is with relax_hint.  */
+      if (relaxing)
+       pseudo_hint = TRUE;
       pseudo_opcode = TRUE;
       nds32_pseudo_opcode_wrapper (str, popcode);
       pseudo_opcode = FALSE;
+      pseudo_hint = FALSE;
       nds32_elf_append_relax_relocs (NULL, relocs_list);
 
+      /* Free relax_hint group list.  */
+      while (nds32_relax_hint_current)
+       {
+         group_temp = nds32_relax_hint_current->next;
+         free (nds32_relax_hint_current);
+         nds32_relax_hint_current = group_temp;
+       }
+
       /* Free pseudo list.  */
       relocs_temp = relocs_list;
       while (relocs_temp)
@@ -5245,7 +6398,7 @@ md_assemble (char *str)
     }
 
   label_exist = 0;
-  insn.info = &insn_expr;
+  insn.info = XNEW (expressionS);
   asm_desc.result = NASM_OK;
   nds32_assemble (&asm_desc, &insn, str);
 
@@ -5282,11 +6435,13 @@ md_assemble (char *str)
 
   /* Make sure the beginning of text being 2-byte align.  */
   nds32_adjust_label (1);
+  add_mapping_symbol (MAP_CODE, 0, 0);
   fld = insn.field;
   /* Try to allocate the max size to guarantee relaxable same branch
      instructions in the same fragment.  */
   frag_grow (NDS32_MAXCHAR);
   fragP = frag_now;
+
   if (fld && (insn.attr & NASM_ATTR_BRANCH)
       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
                            && insn.opcode->value != INSN_J))
@@ -5304,8 +6459,8 @@ md_assemble (char *str)
       /* Get branch range type.  */
       dwarf2_emit_insn (0);
       enum nds32_br_range range_type;
+      expressionS *pexp = insn.info;
 
-      pexp = insn.info;
       range_type = get_range_type (fld);
 
       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
@@ -5321,6 +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;
+
+      free (insn.info);
       return;
       /* md_convert_frag will insert relocations.  */
     }
@@ -5331,7 +6488,7 @@ md_assemble (char *str)
                   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
     {
       /* Record this one is relaxable.  */
-      pexp = insn.info;
+      expressionS *pexp = insn.info;
       dwarf2_emit_insn (0);
       if (fld)
        {
@@ -5361,6 +6518,8 @@ md_assemble (char *str)
        bfd_putb16 (insn_16, out);
       else if (insn.opcode->isize == 2)
        bfd_putb16 (insn.insn, out);
+
+      free (insn.info);
       return;
     }
   else if ((verbatim || !relaxing) && optimize && label)
@@ -5390,18 +6549,21 @@ md_assemble (char *str)
 
   if (insn.opcode->isize == 4)
     bfd_putb32 (insn.insn, out);
-  if (insn.opcode->isize == 2)
+  else if (insn.opcode->isize == 2)
     bfd_putb16 (insn.insn, out);
 
   dwarf2_emit_insn (insn.opcode->isize);
 
   /* Compiler generating code and user assembly pseudo load-store, insert
      fixup here.  */
-  pexp = insn.info;
+  expressionS *pexp = insn.info;
   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   /* Build relaxation pattern when relaxing is enable.  */
   if (relaxing)
-    nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
+    nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
+                                   pseudo_hint);
+
+  free (insn.info);
 }
 
 /* md_macro_start  */
@@ -5447,9 +6609,9 @@ md_operand (expressionS *expressionP)
 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
@@ -5552,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,
@@ -5581,15 +6742,36 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
   if (opcode == NULL)
     return adjust;
 
+  /* Use U4G mode for b and bal in verbatim mode because lto may combine
+     functions into a file.  And order the file in the last when linking.
+     Once there is multiple definition, the same function will be kicked.
+     This may cause relocation truncated error.  */
+  if (verbatim && !nds32_pic
+      && (strcmp (opcode->opcode, "j") == 0
+         || strcmp (opcode->opcode, "jal") == 0))
+    {
+      fragP->fr_subtype = BR_RANGE_U4G;
+      if (init)
+       return 8;
+      else
+       return 0;
+    }
+
   relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
 
   if (relax_info == NULL)
     return adjust;
 
   if (init)
-    branch_range_type = relax_info->br_range;
+    {
+      branch_range_type = relax_info->br_range;
+      i = BR_RANGE_S256;
+    }
   else
-    branch_range_type = fragP->fr_subtype;
+    {
+      branch_range_type = fragP->fr_subtype;
+      i = branch_range_type;
+    }
 
   offset = nds32_calc_branch_offset (segment, fragP, stretch,
                                     relax_info, branch_range_type);
@@ -5598,15 +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)
-    return adjust;
+    {
+      fragP->fr_subtype = real_range_type;
+      return adjust;
+    }
 
   /* Find out proper relaxation code sequence.  */
-  for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
+  for (; i < BR_RANGE_NUM; i++)
     {
       if (real_range_type <= (unsigned int) i)
        {
          if (init)
            diff = relax_info->relax_code_size[i] - opcode->isize;
+         else if (real_range_type < (unsigned int) i)
+           diff = relax_info->relax_code_size[real_range_type]
+             - relax_info->relax_code_size[branch_range_type];
          else
            diff = relax_info->relax_code_size[i]
              - relax_info->relax_code_size[branch_range_type];
@@ -5639,7 +6827,7 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP,
            }
 
          /* Update fr_subtype to new NDS32_BR_RANGE.  */
-         fragP->fr_subtype = i;
+         fragP->fr_subtype = real_range_type;
          break;
        }
     }
@@ -5678,19 +6866,19 @@ nds32_get_align (addressT address, int align)
 {
   addressT mask, new_address;
 
-  mask = ~((~0U) << align);
+  mask = ~((addressT) (~0) << align);
   new_address = (address + mask) & (~mask);
   return (new_address - address);
 }
 
 /* Check the prev_frag is legal.  */
 static void
-invalid_prev_frag (fragS * fragP, fragS **prev_frag)
+invalid_prev_frag (fragS * fragP, fragS **prev_frag, bfd_boolean relax)
 {
   addressT address;
   fragS *frag_start = *prev_frag;
 
-  if (!frag_start)
+  if (!frag_start || !relax)
     return;
 
   if (frag_start->last_fr_address >= fragP->last_fr_address)
@@ -5758,7 +6946,7 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
-  invalid_prev_frag (fragP, &prev_frag);
+  invalid_prev_frag (fragP, &prev_frag, TRUE);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
@@ -5795,7 +6983,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
   static fragS *prev_frag = NULL;
   int adjust = 0;
 
-  invalid_prev_frag (fragP, &prev_frag);
+  invalid_prev_frag (fragP, &prev_frag, FALSE);
 
   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
@@ -5845,6 +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;
+  enum bfd_reloc_code_real final_r_type;
 
   /* Replace with gas_assert (branch_symbol != NULL); */
   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
@@ -6025,9 +7214,10 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
 
          if (fixup_info[i].r_type != 0)
            {
+             final_r_type = fixup_info[i].r_type;
              fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
                                  fixup_size, &exp, pcrel,
-                                 fixup_info[i].r_type);
+                                 final_r_type);
              fixP->fx_addnumber = fixP->fx_offset;
            }
        }
@@ -6126,9 +7316,6 @@ md_number_to_chars (char *buf, valueT val, int 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.  */
 
@@ -6251,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;
-  /* If there is no relocation and relax is disabled, it is not necessary to
-     insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization.  */
+
   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
     if (!fixp->fx_done)
       break;
-  if (!fixp && !enable_relax_ex9 && !verbatim && ict_flag == ICT_NONE)
+
+  if (!fixp && !verbatim && ict_flag == ICT_NONE)
     return;
 
   subseg_change (sec, 0);
@@ -6264,7 +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;
-  exp.X_add_symbol = section_symbol (sec);
+  exp.X_add_symbol = abs_section_sym;
   exp.X_add_number = 0;
   if (!enable_relax_relocs)
     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
@@ -6273,10 +7460,6 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
       /* These flags are only enabled when global relax is enabled.
         Maybe we can check DISABLE_RELAX_FLAG at link-time,
         so we set them anyway.  */
-      if (enable_relax_ex9)
-       exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
-      if (enable_relax_ifc)
-       exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
       if (verbatim)
        exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
       if (ict_flag == ICT_SMALL)
@@ -6382,13 +7565,13 @@ compar_relent (const void *lhs, const void *rhs)
    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
@@ -6515,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.
-        Tag data here for ex9 relaxation and tag tls data for linker.  */
+        Tag tls data for linker.  */
       switch (fixP->fx_r_type)
        {
        case BFD_RELOC_NDS32_DATA:
-         if (!enable_relax_ex9)
-           fixP->fx_done = 1;
+         /* This reloc is obselete, we do not need it so far.  */
+         fixP->fx_done = 1;
          break;
        case BFD_RELOC_NDS32_TPOFF:
        case BFD_RELOC_NDS32_TLS_LE_HI20:
@@ -6530,6 +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_TLS_DESC_HI20:
+       case BFD_RELOC_NDS32_TLS_DESC_LO12:
+       case BFD_RELOC_NDS32_TLS_IE_LO12:
+       case BFD_RELOC_NDS32_TLS_IEGP_HI20:
+       case BFD_RELOC_NDS32_TLS_IEGP_LO12:
+       case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
          break;
        default:
@@ -6712,13 +7901,14 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   return reloc;
 }
 
-struct suffix_name suffix_table[] =
+static struct suffix_name suffix_table[] =
 {
-  {"GOTOFF",   BFD_RELOC_NDS32_GOTOFF, 1},
-  {"GOT",      BFD_RELOC_NDS32_GOT20,  1},
-  {"TPOFF",    BFD_RELOC_NDS32_TPOFF,  0},
-  {"PLT",      BFD_RELOC_NDS32_25_PLTREL,      1},
-  {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF,       0}
+  {"GOTOFF",   BFD_RELOC_NDS32_GOTOFF},
+  {"GOT",      BFD_RELOC_NDS32_GOT20},
+  {"TPOFF",    BFD_RELOC_NDS32_TPOFF},
+  {"PLT",      BFD_RELOC_NDS32_25_PLTREL},
+  {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF},
+  {"TLSDESC",  BFD_RELOC_NDS32_TLS_DESC},
 };
 
 /* Implement md_parse_name.  */
@@ -6739,7 +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);
-  if (segment != undefined_section)
+  if ((segment != undefined_section) && (*nextcharP != '@'))
     return 0;
 
   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
@@ -6753,13 +7943,11 @@ nds32_parse_name (char const *name, expressionS *exprP,
       char *next;
       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
        {
-         next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
+         next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
          if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
                           strlen (suffix_table[i].suffix)) == 0
              && !is_part_of_name (*next))
            {
-             if (!nds32_pic && suffix_table[i].pic)
-               as_bad (_("need PIC qualifier with symbol."));
              exprP->X_md = suffix_table[i].reloc;
              *input_line_pointer = *nextcharP;
              input_line_pointer = next;
@@ -6769,6 +7957,7 @@ nds32_parse_name (char const *name, expressionS *exprP,
            }
        }
     }
+
   return 1;
 }
 
This page took 0.132323 seconds and 4 git commands to generate.