Home | History | Annotate | Line # | Download | only in config
tc-nds32.c revision 1.1.1.8
      1 /* tc-nds32.c -- Assemble for the nds32
      2    Copyright (C) 2012-2025 Free Software Foundation, Inc.
      3    Contributed by Andes Technology Corporation.
      4 
      5    This file is part of GAS, the GNU Assembler.
      6 
      7    GAS is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GAS is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GAS; see the file COPYING.  If not, write to the Free
     19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20    02110-1301, USA.  */
     21 
     22 #include "as.h"
     23 #include "safe-ctype.h"
     24 #include "subsegs.h"
     25 #include "symcat.h"
     26 #include "dwarf2dbg.h"
     27 #include "dw2gencfi.h"
     28 #include "opcodes/nds32-asm.h"
     29 #include "elf/nds32.h"
     30 #include "bfd/elf32-nds32.h"
     31 #include "hash.h"
     32 #include "sb.h"
     33 #include "macro.h"
     34 #include "opcode/nds32.h"
     35 
     36 #include <stdio.h>
     37 #include <errno.h>
     38 #include <limits.h>
     39 
     40 /* GAS definitions.  */
     41 
     42 /* Characters which start a comment.  */
     43 const char comment_chars[] = "!";
     44 /* Characters which start a comment when they appear at the start of a line.  */
     45 const char line_comment_chars[] = "#!";
     46 /* Characters which separate lines (null and newline are by default).  */
     47 const char line_separator_chars[] = ";";
     48 /* Characters which may be used as the exponent character
     49    in a floating point number.  */
     50 const char EXP_CHARS[] = "eE";
     51 /* Characters which may be used to indicate a floating point constant.  */
     52 const char FLT_CHARS[] = "dDfF";
     53 
     54 static int enable_16bit = 1;
     55 /* Save for md_assemble to distinguish if this instruction is
     56    expanded from the pseudo instruction.  */
     57 static bool pseudo_opcode = false;
     58 static struct nds32_relocs_pattern *relocs_list = NULL;
     59 /* Save instruction relation to inserting relaxation relocation.  */
     60 struct nds32_relocs_pattern
     61 {
     62   segT seg;
     63   fragS *frag;
     64   frchainS *frchain;
     65   symbolS *sym;
     66   fixS* fixP;
     67   struct nds32_opcode *opcode;
     68   char *where;
     69   struct nds32_relocs_pattern *next;
     70   /* Assembled instruction bytes.  */
     71   uint32_t insn;
     72 };
     73 
     74 /* Suffix name and relocation.  */
     75 struct suffix_name
     76 {
     77   const char *suffix;
     78   short unsigned int reloc;
     79 };
     80 static int vec_size = 0;
     81 /* If the assembly code is generated by compiler, it is supposed to have
     82    ".flag verbatim" at beginning of the content.  We have
     83    'nds32_flag' to parse it and set this field to be non-zero.  */
     84 static int verbatim = 0;
     85 static htab_t nds32_gprs_hash;
     86 static htab_t nds32_hint_hash;
     87 #define TLS_REG "$r27"
     88 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
     89 
     90 /* Generate relocation for relax or not, and the default is true.  */
     91 static int enable_relax_relocs = 1;
     92 /* Save option -O for performance.  */
     93 static int optimize = 0;
     94 /* Save option -Os for code size.  */
     95 static int optimize_for_space = 0;
     96 /* Flag to save label exist.  */
     97 static int label_exist = 0;
     98 /* Flag to save state in omit_fp region.  */
     99 static int in_omit_fp = 0;
    100 /* Tag there is relax relocation having to link.  */
    101 static bool relaxing = false;
    102 /* ICT model.  */
    103 enum ict_option {
    104   ICT_NONE = 0,
    105   ICT_SMALL,
    106   ICT_LARGE
    107 };
    108 static enum ict_option ict_flag = ICT_NONE;
    109 
    110 
    112 static htab_t nds32_relax_info_hash;
    113 
    114 /* Branch patterns.  */
    115 static relax_info_t relax_table[] =
    116 {
    117   {
    118     .opcode = "jal",
    119     .br_range = BR_RANGE_S16M,
    120     .cond_field =
    121       {
    122 	{0, 0, 0, false}
    123       },
    124     .relax_code_seq[BR_RANGE_S256] =
    125       {
    126 	INSN_JAL	/* jal label */
    127       },
    128     .relax_code_size[BR_RANGE_S256] = 4,
    129     .relax_branch_isize[BR_RANGE_S256] = 4,
    130     .relax_fixup[BR_RANGE_S256] =
    131       {
    132 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    133 	{0, 0, 0, 0}
    134       },
    135 
    136     .relax_code_seq[BR_RANGE_S16K] =
    137       {
    138 	INSN_JAL	/* jal label */
    139       },
    140     .relax_code_size[BR_RANGE_S16K] = 4,
    141     .relax_branch_isize[BR_RANGE_S16K] = 4,
    142     .relax_fixup[BR_RANGE_S16K] =
    143       {
    144 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    145 	{0, 0, 0, 0}
    146       },
    147 
    148     .relax_code_seq[BR_RANGE_S64K] =
    149       {
    150 	INSN_JAL	/* jal label */
    151       },
    152     .relax_code_size[BR_RANGE_S64K] = 4,
    153     .relax_branch_isize[BR_RANGE_S64K] = 4,
    154     .relax_fixup[BR_RANGE_S64K] =
    155       {
    156 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    157 	{0, 0, 0, 0}
    158       },
    159 
    160     .relax_code_seq[BR_RANGE_S16M] =
    161       {
    162 	INSN_JAL	/* jal label */
    163       },
    164     .relax_code_size[BR_RANGE_S16M] = 4,
    165     .relax_branch_isize[BR_RANGE_S16M] = 4,
    166     .relax_fixup[BR_RANGE_S16M] =
    167       {
    168 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    169 	{0, 0, 0, 0}
    170       },
    171 
    172     .relax_code_seq[BR_RANGE_U4G] =
    173       {
    174 	INSN_SETHI_TA,	/* sethi $ta, label */
    175 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    176 	INSN_JRAL_TA	/* jral $ta */
    177       },
    178     .relax_code_size[BR_RANGE_U4G] = 12,
    179     .relax_branch_isize[BR_RANGE_U4G] = 4,
    180     .relax_fixup[BR_RANGE_U4G] =
    181       {
    182 	{0, 4, 0, BFD_RELOC_NDS32_HI20},
    183 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
    184 	{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
    185 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    186 	{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    187 	{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    188 	{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    189 	{0, 0, 0, 0}
    190       },
    191   },
    192   {
    193     .opcode = "bgezal",
    194     .br_range = BR_RANGE_S64K,
    195     .cond_field =
    196       {
    197 	{0, 20, 0x1F, false},
    198 	{0, 0, 0, false}
    199       },
    200     .relax_code_seq[BR_RANGE_S256] =
    201       {
    202 	  INSN_BGEZAL	/* bgezal $rt, label */
    203       },
    204     .relax_code_condition[BR_RANGE_S256] =
    205       {
    206 	{0, 20, 0x1F, false},
    207 	{0, 0, 0, false},
    208       },
    209     .relax_code_size[BR_RANGE_S256] = 4,
    210     .relax_branch_isize[BR_RANGE_S256] = 4,
    211     .relax_fixup[BR_RANGE_S256] =
    212       {
    213 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    214 	{0, 0, 0, 0}
    215       },
    216 
    217     .relax_code_seq[BR_RANGE_S16K] =
    218       {
    219 	INSN_BGEZAL	/* bgezal $rt, label */
    220       },
    221     .relax_code_condition[BR_RANGE_S16K] =
    222       {
    223 	{0, 20, 0x1F, false},
    224 	{0, 0, 0, false},
    225       },
    226     .relax_code_size[BR_RANGE_S16K] = 4,
    227     .relax_branch_isize[BR_RANGE_S16K] = 4,
    228     .relax_fixup[BR_RANGE_S16K] =
    229       {
    230 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    231 	{0, 0, 0, 0}
    232       },
    233 
    234     .relax_code_seq[BR_RANGE_S64K] =
    235       {
    236 	INSN_BGEZAL	/* bgezal $rt, label */
    237       },
    238     .relax_code_condition[BR_RANGE_S64K] =
    239       {
    240 	{0, 20, 0x1F, false},
    241 	{0, 0, 0, false},
    242       },
    243     .relax_code_size[BR_RANGE_S64K] = 4,
    244     .relax_branch_isize[BR_RANGE_S64K] = 4,
    245     .relax_fixup[BR_RANGE_S64K] =
    246       {
    247 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    248 	{0, 0, 0, 0}
    249       },
    250 
    251     .relax_code_seq[BR_RANGE_S16M] =
    252       {
    253 	INSN_BLTZ,	/* bltz $rt, $1 */
    254 	INSN_JAL	/* jal label */
    255       },
    256     .relax_code_condition[BR_RANGE_S16M] =
    257       {
    258 	{0, 20, 0x1F, false},
    259 	{0, 0, 0, false},
    260       },
    261     .relax_code_size[BR_RANGE_S16M] = 8,
    262     .relax_branch_isize[BR_RANGE_S16M] = 4,
    263     .relax_fixup[BR_RANGE_S16M] =
    264       {
    265 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    266 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
    267 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    268 	{0, 0, 0, 0}
    269       },
    270 
    271     .relax_code_seq[BR_RANGE_U4G] =
    272       {
    273 	INSN_BLTZ,	/* bltz $rt, $1 */
    274 	INSN_SETHI_TA,	/* sethi $ta, label */
    275 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    276 	INSN_JRAL_TA	/* jral $ta */
    277       },
    278     .relax_code_condition[BR_RANGE_U4G] =
    279       {
    280 	{0, 20, 0x1F, false},
    281 	{0, 0, 0, false},
    282       },
    283     .relax_code_size[BR_RANGE_U4G] = 16,
    284     .relax_branch_isize[BR_RANGE_U4G] = 4,
    285     .relax_fixup[BR_RANGE_U4G] =
    286       {
    287 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    288 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
    289 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    290 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    291 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    292 	{8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    293 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    294 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    295 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    296 	{0, 0, 0, 0}
    297       },
    298   },
    299   {
    300     .opcode = "bltzal",
    301     .br_range = BR_RANGE_S64K,
    302     .cond_field =
    303       {
    304 	{0, 20, 0x1F, false},
    305 	{0, 0, 0, false}
    306       },
    307     .relax_code_seq[BR_RANGE_S256] =
    308       {
    309 	  INSN_BLTZAL	/* bltzal $rt, label */
    310       },
    311     .relax_code_condition[BR_RANGE_S256] =
    312       {
    313 	{0, 20, 0x1F, false},
    314 	{0, 0, 0, false},
    315       },
    316     .relax_code_size[BR_RANGE_S256] = 4,
    317     .relax_branch_isize[BR_RANGE_S256] = 4,
    318     .relax_fixup[BR_RANGE_S256] =
    319       {
    320 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    321 	{0, 0, 0, 0}
    322       },
    323 
    324     .relax_code_seq[BR_RANGE_S16K] =
    325       {
    326 	INSN_BLTZAL	/* bltzal $rt, label */
    327       },
    328     .relax_code_condition[BR_RANGE_S16K] =
    329       {
    330 	{0, 20, 0x1F, false},
    331 	{0, 0, 0, false},
    332       },
    333     .relax_code_size[BR_RANGE_S16K] = 4,
    334     .relax_branch_isize[BR_RANGE_S16K] = 4,
    335     .relax_fixup[BR_RANGE_S16K] =
    336       {
    337 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    338 	{0, 0, 0, 0}
    339       },
    340 
    341     .relax_code_seq[BR_RANGE_S64K] =
    342       {
    343 	INSN_BLTZAL	/* bltzal $rt, label */
    344       },
    345     .relax_code_condition[BR_RANGE_S64K] =
    346       {
    347 	{0, 20, 0x1F, false},
    348 	{0, 0, 0, false},
    349       },
    350     .relax_code_size[BR_RANGE_S64K] = 4,
    351     .relax_branch_isize[BR_RANGE_S64K] = 4,
    352     .relax_fixup[BR_RANGE_S64K] =
    353       {
    354 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    355 	{0, 0, 0, 0}
    356       },
    357 
    358     .relax_code_seq[BR_RANGE_S16M] =
    359       {
    360 	INSN_BGEZ,	/* bgez $rt, $1 */
    361 	INSN_JAL	/* jal label */
    362       },
    363     .relax_code_condition[BR_RANGE_S16M] =
    364       {
    365 	{0, 20, 0x1F, false},
    366 	{0, 0, 0, false},
    367       },
    368     .relax_code_size[BR_RANGE_S16M] = 8,
    369     .relax_branch_isize[BR_RANGE_S16M] = 4,
    370     .relax_fixup[BR_RANGE_S16M] =
    371       {
    372 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    373 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
    374 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    375 	{0, 0, 0, 0}
    376       },
    377 
    378     .relax_code_seq[BR_RANGE_U4G] =
    379       {
    380 	INSN_BGEZ,	/* bgez $rt, $1 */
    381 	INSN_SETHI_TA,	/* sethi $ta, label */
    382 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    383 	INSN_JRAL_TA	/* jral $ta */
    384       },
    385     .relax_code_condition[BR_RANGE_U4G] =
    386       {
    387 	{0, 20, 0x1F, false},
    388 	{0, 0, 0, false},
    389       },
    390     .relax_code_size[BR_RANGE_U4G] = 16,
    391     .relax_branch_isize[BR_RANGE_U4G] = 4,
    392     .relax_fixup[BR_RANGE_U4G] =
    393       {
    394 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    395 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
    396 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    397 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    398 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    399 	{8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    400 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    401 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    402 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    403 	{0, 0, 0, 0}
    404       },
    405   },
    406   {
    407     .opcode = "j",
    408     .br_range = BR_RANGE_S16M,
    409     .cond_field =
    410       {
    411 	{0, 0, 0, false}
    412       },
    413     .relax_code_seq[BR_RANGE_S256] =
    414       {
    415 	(INSN_J8 << 16)	/* j8 label */
    416       },
    417     .relax_code_size[BR_RANGE_S256] = 2,
    418     .relax_branch_isize[BR_RANGE_S256] = 2,
    419     .relax_fixup[BR_RANGE_S256] =
    420       {
    421 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
    422 	{0, 0, 0, 0}
    423       },
    424 
    425     .relax_code_seq[BR_RANGE_S16K] =
    426       {
    427 	INSN_J		/* j label */
    428       },
    429     . relax_code_size[BR_RANGE_S16K] = 4,
    430     .relax_branch_isize[BR_RANGE_S16K] = 4,
    431     .relax_fixup[BR_RANGE_S16K] =
    432       {
    433 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    434 	{0, 0, 0, 0}
    435       },
    436 
    437     .relax_code_seq[BR_RANGE_S64K] =
    438       {
    439 	INSN_J		/* j label */
    440       },
    441     .relax_code_size[BR_RANGE_S64K] = 4,
    442     .relax_branch_isize[BR_RANGE_S64K] = 4,
    443     .relax_fixup[BR_RANGE_S64K] =
    444       {
    445 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    446 	{0, 0, 0, 0}
    447       },
    448 
    449     .relax_code_seq[BR_RANGE_S16M] =
    450       {
    451 	INSN_J		/* j label */
    452       },
    453     .relax_code_size[BR_RANGE_S16M] = 4,
    454     .relax_branch_isize[BR_RANGE_S16M] = 4,
    455     .relax_fixup[BR_RANGE_S16M] =
    456       {
    457 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    458 	{0, 0, 0, 0}
    459       },
    460 
    461     .relax_code_seq[BR_RANGE_U4G] =
    462       {
    463 	INSN_SETHI_TA,	/* sethi $ta, label */
    464 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    465 	INSN_JR_TA	/* jr $ta */
    466       },
    467     .relax_code_size[BR_RANGE_U4G] = 12,
    468     .relax_branch_isize[BR_RANGE_U4G] = 4,
    469     .relax_fixup[BR_RANGE_U4G] =
    470       {
    471 	{0, 4, 0, BFD_RELOC_NDS32_HI20},
    472 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
    473 	{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
    474 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    475 	{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    476 	{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    477 	{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    478 	{0, 0, 0, 0}
    479       },
    480   },
    481   {
    482     .opcode = "j8",
    483     .br_range = BR_RANGE_S256,
    484     .cond_field =
    485       {
    486 	{0, 0, 0, false}
    487       },
    488     .relax_code_seq[BR_RANGE_S256] =
    489       {
    490 	(INSN_J8 << 16)	/* j8 label */
    491       },
    492     .relax_code_size[BR_RANGE_S256] = 2,
    493     .relax_branch_isize[BR_RANGE_S256] = 2,
    494     .relax_fixup[BR_RANGE_S256] =
    495       {
    496 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
    497 	{0, 0, 0, 0}
    498       },
    499 
    500     .relax_code_seq[BR_RANGE_S16K] =
    501       {
    502 	INSN_J		/* j label */
    503       },
    504     .relax_code_size[BR_RANGE_S16K] = 4,
    505     .relax_branch_isize[BR_RANGE_S16K] = 4,
    506     .relax_fixup[BR_RANGE_S16K] =
    507       {
    508 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    509 	{0, 0, 0, 0}
    510       },
    511 
    512     .relax_code_seq[BR_RANGE_S64K] =
    513       {
    514 	INSN_J		/* j label */
    515       },
    516     .relax_code_size[BR_RANGE_S64K] = 4,
    517     .relax_branch_isize[BR_RANGE_S64K] = 4,
    518     .relax_fixup[BR_RANGE_S64K] =
    519       {
    520 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    521 	{0, 0, 0, 0}
    522       },
    523 
    524     .relax_code_seq[BR_RANGE_S16M] =
    525       {
    526 	INSN_J		/* j label */
    527       },
    528     .relax_code_size[BR_RANGE_S16M] = 4,
    529     .relax_branch_isize[BR_RANGE_S16M] = 4,
    530     .relax_fixup[BR_RANGE_S16M] =
    531       {
    532 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    533 	{0, 0, 0, 0}
    534       },
    535 
    536     .relax_code_seq[BR_RANGE_U4G] =
    537       {
    538 	INSN_SETHI_TA,	/* sethi $ta, label */
    539 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    540 	INSN_JR_TA	/* jr $ta */
    541       },
    542     .relax_code_size[BR_RANGE_U4G] = 12,
    543     .relax_branch_isize[BR_RANGE_U4G] = 4,
    544     .relax_fixup[BR_RANGE_U4G] =
    545       {
    546 	{0, 4, 0, BFD_RELOC_NDS32_HI20},
    547 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
    548 	{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
    549 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    550 	{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    551 	{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    552 	{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    553 	{0, 0, 0, 0}
    554       },
    555   },
    556   {
    557     .opcode = "beqz",
    558     .br_range = BR_RANGE_S64K,
    559     .cond_field =
    560       {
    561 	{0, 20, 0x1F, false},
    562 	{0, 0, 0, false}
    563       },
    564     /* We do not use beqz38 and beqzs8 here directly because we
    565        don't want to check register number for specail condition.  */
    566     .relax_code_seq[BR_RANGE_S256] =
    567       {
    568 	  INSN_BEQZ	/* beqz $rt, label */
    569       },
    570     .relax_code_condition[BR_RANGE_S256] =
    571       {
    572 	{0, 20, 0x1F, false},
    573 	{0, 0, 0, false},
    574       },
    575     .relax_code_size[BR_RANGE_S256] = 4,
    576     .relax_branch_isize[BR_RANGE_S256] = 4,
    577     .relax_fixup[BR_RANGE_S256] =
    578       {
    579 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    580 	{0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
    581 	{0, 0, 0, 0}
    582       },
    583 
    584     .relax_code_seq[BR_RANGE_S16K] =
    585       {
    586 	INSN_BEQZ	/* beqz $rt, label */
    587       },
    588     .relax_code_condition[BR_RANGE_S16K] =
    589       {
    590 	{0, 20, 0x1F, false},
    591 	{0, 0, 0, false},
    592       },
    593     .relax_code_size[BR_RANGE_S16K] = 4,
    594     .relax_branch_isize[BR_RANGE_S16K] = 4,
    595     .relax_fixup[BR_RANGE_S16K] =
    596       {
    597 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    598 	{0, 0, 0, 0}
    599       },
    600 
    601     .relax_code_seq[BR_RANGE_S64K] =
    602       {
    603 	INSN_BEQZ	/* beqz $rt, label */
    604       },
    605     .relax_code_condition[BR_RANGE_S64K] =
    606       {
    607 	{0, 20, 0x1F, false},
    608 	{0, 0, 0, false},
    609       },
    610     .relax_code_size[BR_RANGE_S64K] = 4,
    611     .relax_branch_isize[BR_RANGE_S64K] = 4,
    612     .relax_fixup[BR_RANGE_S64K] =
    613       {
    614 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    615 	{0, 0, 0, 0}
    616       },
    617 
    618     .relax_code_seq[BR_RANGE_S16M] =
    619       {
    620 	INSN_BNEZ,	/* bnez $rt, $1 */
    621 	INSN_J		/* j label */
    622       },
    623     .relax_code_condition[BR_RANGE_S16M] =
    624       {
    625 	{0, 20, 0x1F, false},
    626 	{0, 0, 0, false},
    627       },
    628     .relax_code_size[BR_RANGE_S16M] = 8,
    629     .relax_branch_isize[BR_RANGE_S16M] = 4,
    630     .relax_fixup[BR_RANGE_S16M] =
    631       {
    632 	/* bnez range is 17 pcrel, but it use 15 pcrel here since link time
    633 	   relaxtion.  If 17 pcrel can reach, it do not have to use S16M.
    634 	   Therefore, 15 pcrel is just for linker to distinguish LONGJUMP5
    635 	   and LONGJUMP6.  */
    636 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    637 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    638 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
    639 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    640 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    641 	{0, 0, 0, 0}
    642       },
    643 
    644     .relax_code_seq[BR_RANGE_U4G] =
    645       {
    646 	INSN_BNEZ,	/* bnez $rt, $1 */
    647 	INSN_SETHI_TA,	/* sethi $ta, label */
    648 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    649 	INSN_JR_TA	/* jr $ta */
    650       },
    651     .relax_code_condition[BR_RANGE_U4G] =
    652       {
    653 	{0, 20, 0x1F, false},
    654 	{0, 0, 0, false},
    655       },
    656     .relax_code_size[BR_RANGE_U4G] = 16,
    657     .relax_branch_isize[BR_RANGE_U4G] = 4,
    658     .relax_fixup[BR_RANGE_U4G] =
    659       {
    660 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    661 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    662 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
    663 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    664 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    665 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    666 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
    667 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    668 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    669 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    670 	{0, 0, 0, 0}
    671       },
    672   },
    673   {
    674     .opcode = "bgez",
    675     .br_range = BR_RANGE_S64K,
    676     .cond_field =
    677       {
    678 	{0, 20, 0x1F, false},
    679 	{0, 0, 0, false}
    680       },
    681     .relax_code_seq[BR_RANGE_S256] =
    682       {
    683 	INSN_BGEZ	/* bgez $rt, label */
    684       },
    685     .relax_code_condition[BR_RANGE_S256] =
    686       {
    687 	{0, 20, 0x1F, false},
    688 	{0, 0, 0, false},
    689       },
    690     .relax_code_size[BR_RANGE_S256] = 4,
    691     .relax_branch_isize[BR_RANGE_S256] = 4,
    692     .relax_fixup[BR_RANGE_S256] =
    693       {
    694 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    695 	{0, 0, 0, 0}
    696       },
    697 
    698     .relax_code_seq[BR_RANGE_S16K] =
    699       {
    700 	INSN_BGEZ	/* bgez $rt, label */
    701       },
    702     .relax_code_condition[BR_RANGE_S16K] =
    703       {
    704 	{0, 20, 0x1F, false},
    705 	{0, 0, 0, false},
    706       },
    707     .relax_code_size[BR_RANGE_S16K] = 4,
    708     .relax_branch_isize[BR_RANGE_S16K] = 4,
    709     .relax_fixup[BR_RANGE_S16K] =
    710       {
    711 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    712 	{0, 0, 0, 0}
    713       },
    714 
    715     .relax_code_seq[BR_RANGE_S64K] =
    716       {
    717 	INSN_BGEZ	/* bgez $rt, label */
    718       },
    719     .relax_code_condition[BR_RANGE_S64K] =
    720       {
    721 	{0, 20, 0x1F, false},
    722 	{0, 0, 0, false},
    723       },
    724     .relax_code_size[BR_RANGE_S64K] = 4,
    725     .relax_branch_isize[BR_RANGE_S64K] = 4,
    726     .relax_fixup[BR_RANGE_S64K] =
    727       {
    728 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    729 	{0, 0, 0, 0}
    730       },
    731 
    732     .relax_code_seq[BR_RANGE_S16M] =
    733       {
    734 	INSN_BLTZ,	/* bltz $rt, $1 */
    735 	INSN_J		/* j label */
    736       },
    737     .relax_code_condition[BR_RANGE_S16M] =
    738       {
    739 	{0, 20, 0x1F, false},
    740 	{0, 0, 0, false},
    741       },
    742     .relax_code_size[BR_RANGE_S16M] = 8,
    743     .relax_branch_isize[BR_RANGE_S16M] = 4,
    744     .relax_fixup[BR_RANGE_S16M] =
    745       {
    746 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    747 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
    748 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    749 	{0, 0, 0, 0}
    750       },
    751     .relax_code_seq[BR_RANGE_U4G] =
    752       {
    753 	INSN_BLTZ,	/* bltz $rt, $1 */
    754 	INSN_SETHI_TA,	/* sethi $ta, label */
    755 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    756 	INSN_JR_TA	/* jr $ta */
    757       },
    758     .relax_code_condition[BR_RANGE_U4G] =
    759       {
    760 	{0, 20, 0x1F, false},
    761 	{0, 0, 0, false},
    762       },
    763     .relax_code_size[BR_RANGE_U4G] = 16,
    764     .relax_branch_isize[BR_RANGE_U4G] = 4,
    765     .relax_fixup[BR_RANGE_U4G] =
    766       {
    767 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    768 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
    769 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    770 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    771 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    772 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
    773 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    774 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    775 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    776 	{0, 0, 0, 0}
    777       },
    778   },
    779   {
    780     .opcode = "bnez",
    781     .br_range = BR_RANGE_S64K,
    782     .cond_field =
    783       {
    784 	{0, 20, 0x1F, false},
    785 	{0, 0, 0, false}
    786       },
    787     .relax_code_seq[BR_RANGE_S256] =
    788       {
    789 	INSN_BNEZ	/* bnez $rt, label */
    790       },
    791     .relax_code_condition[BR_RANGE_S256] =
    792       {
    793 	{0, 20, 0x1F, false},
    794 	{0, 0, 0, false},
    795       },
    796     .relax_code_size[BR_RANGE_S256] = 4,
    797     .relax_branch_isize[BR_RANGE_S256] = 4,
    798     .relax_fixup[BR_RANGE_S256] =
    799       {
    800 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    801 	{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
    802 	{0, 0, 0, 0}
    803       },
    804 
    805     .relax_code_seq[BR_RANGE_S16K] =
    806       {
    807 	INSN_BNEZ	/* bnez $rt, label */
    808       },
    809     .relax_code_condition[BR_RANGE_S16K] =
    810       {
    811 	{0, 20, 0x1F, false},
    812 	{0, 0, 0, false},
    813       },
    814     .relax_code_size[BR_RANGE_S16K] = 4,
    815     .relax_branch_isize[BR_RANGE_S16K] = 4,
    816     .relax_fixup[BR_RANGE_S16K] =
    817       {
    818 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    819 	{0, 0, 0, 0}
    820       },
    821 
    822     .relax_code_seq[BR_RANGE_S64K] =
    823       {
    824 	INSN_BNEZ	/* bnez $rt, label */
    825       },
    826     .relax_code_condition[BR_RANGE_S64K] =
    827       {
    828 	{0, 20, 0x1F, false},
    829 	{0, 0, 0, false},
    830       },
    831     .relax_code_size[BR_RANGE_S64K] = 4,
    832     .relax_branch_isize[BR_RANGE_S64K] = 4,
    833     .relax_fixup[BR_RANGE_S64K] =
    834       {
    835 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    836 	{0, 0, 0, 0}
    837       },
    838 
    839     .relax_code_seq[BR_RANGE_S16M] =
    840       {
    841 	INSN_BEQZ,	/* beqz $rt, $1 */
    842 	INSN_J		/* j label */
    843       },
    844     .relax_code_condition[BR_RANGE_S16M] =
    845       {
    846 	{0, 20, 0x1F, false},
    847 	{0, 0, 0, false},
    848       },
    849     .relax_code_size[BR_RANGE_S16M] = 8,
    850     .relax_branch_isize[BR_RANGE_S16M] = 4,
    851     .relax_fixup[BR_RANGE_S16M] =
    852       {
    853 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    854 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    855 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
    856 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    857 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    858 	{0, 0, 0, 0}
    859       },
    860 
    861     .relax_code_seq[BR_RANGE_U4G] =
    862       {
    863 	INSN_BEQZ,	/* beqz $rt, $1 */
    864 	INSN_SETHI_TA,	/* sethi $ta, label */
    865 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    866 	INSN_JR_TA	/* jr $ta */
    867       },
    868     .relax_code_condition[BR_RANGE_U4G] =
    869       {
    870 	{0, 20, 0x1F, false},
    871 	{0, 0, 0, false},
    872       },
    873     .relax_code_size[BR_RANGE_U4G] = 16,
    874     .relax_branch_isize[BR_RANGE_U4G] = 4,
    875     .relax_fixup[BR_RANGE_U4G] =
    876       {
    877 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    878 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    879 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
    880 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    881 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    882 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    883 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
    884 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    885 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    886 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    887 	{0, 0, 0, 0}
    888       },
    889   },
    890   {
    891     .opcode = "bgtz",
    892     .br_range = BR_RANGE_S64K,
    893     .cond_field =
    894       {
    895 	{0, 20, 0x1F, false},
    896 	{0, 0, 0, false}
    897       },
    898     .relax_code_seq[BR_RANGE_S256] =
    899       {
    900 	INSN_BGTZ	/* bgtz $rt, label */
    901       },
    902     .relax_code_condition[BR_RANGE_S256] =
    903       {
    904 	{0, 20, 0x1F, false},
    905 	{0, 0, 0, false},
    906       },
    907     .relax_code_size[BR_RANGE_S256] = 4,
    908     .relax_branch_isize[BR_RANGE_S256] = 4,
    909     .relax_fixup[BR_RANGE_S256] =
    910       {
    911 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    912 	{0, 0, 0, 0}
    913       },
    914 
    915     .relax_code_seq[BR_RANGE_S16K] =
    916       {
    917 	INSN_BGTZ	/* bgtz $rt, label */
    918       },
    919     .relax_code_condition[BR_RANGE_S16K] =
    920       {
    921 	{0, 20, 0x1F, false},
    922 	{0, 0, 0, false},
    923       },
    924     .relax_code_size[BR_RANGE_S16K] = 4,
    925     .relax_branch_isize[BR_RANGE_S16K] = 4,
    926     .relax_fixup[BR_RANGE_S16K] =
    927       {
    928 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    929 	{0, 0, 0, 0}
    930       },
    931 
    932     .relax_code_seq[BR_RANGE_S64K] =
    933       {
    934 	INSN_BGTZ	/* bgtz $rt, label */
    935       },
    936     .relax_code_condition[BR_RANGE_S64K] =
    937       {
    938 	{0, 20, 0x1F, false},
    939 	{0, 0, 0, false},
    940       },
    941     .relax_code_size[BR_RANGE_S64K] = 4,
    942     .relax_branch_isize[BR_RANGE_S64K] = 4,
    943     .relax_fixup[BR_RANGE_S64K] =
    944       {
    945 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
    946 	{0, 0, 0, 0}
    947       },
    948 
    949     .relax_code_seq[BR_RANGE_S16M] =
    950       {
    951 	INSN_BLEZ,	/* blez $rt, $1 */
    952 	INSN_J		/* j label */
    953       },
    954     .relax_code_condition[BR_RANGE_S16M] =
    955       {
    956 	{0, 20, 0x1F, false},
    957 	{0, 0, 0, false},
    958       },
    959     .relax_code_size[BR_RANGE_S16M] = 8,
    960     .relax_branch_isize[BR_RANGE_S16M] = 4,
    961     .relax_fixup[BR_RANGE_S16M] =
    962       {
    963 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    964 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
    965 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
    966 	{0, 0, 0, 0}
    967       },
    968 
    969     .relax_code_seq[BR_RANGE_U4G] =
    970       {
    971 	INSN_BLEZ,	/* blez $rt, $1 */
    972 	INSN_SETHI_TA,	/* sethi $ta, label */
    973 	INSN_ORI_TA,	/* ori $ta, $ta, label */
    974 	INSN_JR_TA	/* jr $ta */
    975       },
    976     .relax_code_condition[BR_RANGE_U4G] =
    977       {
    978 	{0, 20, 0x1F, false},
    979 	{0, 0, 0, false},
    980       },
    981     .relax_code_size[BR_RANGE_U4G] = 16,
    982     .relax_branch_isize[BR_RANGE_U4G] = 4,
    983     .relax_fixup[BR_RANGE_U4G] =
    984       {
    985 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
    986 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
    987 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
    988 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
    989 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
    990 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
    991 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
    992 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
    993 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
    994 	{0, 0, 0, 0}
    995       },
    996   },
    997   {
    998     .opcode = "blez",
    999     .br_range = BR_RANGE_S64K,
   1000     .cond_field =
   1001       {
   1002 	{0, 20, 0x1F, false},
   1003 	{0, 0, 0, false}
   1004       },
   1005     .relax_code_seq[BR_RANGE_S256] =
   1006       {
   1007 	INSN_BLEZ	/* blez $rt, label */
   1008       },
   1009     .relax_code_condition[BR_RANGE_S256] =
   1010       {
   1011 	{0, 20, 0x1F, false},
   1012 	{0, 0, 0, false},
   1013       },
   1014     .relax_code_size[BR_RANGE_S256] = 4,
   1015     .relax_branch_isize[BR_RANGE_S256] = 4,
   1016     .relax_fixup[BR_RANGE_S256] =
   1017       {
   1018 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1019 	{0, 0, 0, 0}
   1020       },
   1021 
   1022     .relax_code_seq[BR_RANGE_S16K] =
   1023       {
   1024 	INSN_BLEZ	/* blez $rt, label */
   1025       },
   1026     .relax_code_condition[BR_RANGE_S16K] =
   1027       {
   1028 	{0, 20, 0x1F, false},
   1029 	{0, 0, 0, false},
   1030       },
   1031     .relax_code_size[BR_RANGE_S16K] = 4,
   1032     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1033     .relax_fixup[BR_RANGE_S16K] =
   1034       {
   1035 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1036 	{0, 0, 0, 0}
   1037       },
   1038 
   1039     .relax_code_seq[BR_RANGE_S64K] =
   1040       {
   1041 	INSN_BLEZ	/* blez $rt, label */
   1042       },
   1043     .relax_code_condition[BR_RANGE_S64K] =
   1044       {
   1045 	{0, 20, 0x1F, false},
   1046 	{0, 0, 0, false},
   1047       },
   1048     .relax_code_size[BR_RANGE_S64K] = 4,
   1049     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1050     .relax_fixup[BR_RANGE_S64K] =
   1051       {
   1052 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1053 	{0, 0, 0, 0}
   1054       },
   1055 
   1056     .relax_code_seq[BR_RANGE_S16M] =
   1057       {
   1058 	INSN_BGTZ,	/* bgtz $rt, $1 */
   1059 	INSN_J		/* j label */
   1060       },
   1061     .relax_code_condition[BR_RANGE_S16M] =
   1062       {
   1063 	{0, 20, 0x1F, false},
   1064 	{0, 0, 0, false},
   1065       },
   1066     .relax_code_size[BR_RANGE_S16M] = 8,
   1067     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1068     .relax_fixup[BR_RANGE_S16M] =
   1069       {
   1070 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1071 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1072 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1073 	{0, 0, 0, 0}
   1074       },
   1075 
   1076     .relax_code_seq[BR_RANGE_U4G] =
   1077       {
   1078 	INSN_BGTZ,	/* bgtz $rt, $1 */
   1079 	INSN_SETHI_TA,	/* sethi $ta, label */
   1080 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1081 	INSN_JR_TA	/* jr $ta */
   1082       },
   1083     .relax_code_condition[BR_RANGE_U4G] =
   1084       {
   1085 	{0, 20, 0x1F, false},
   1086 	{0, 0, 0, false},
   1087       },
   1088     .relax_code_size[BR_RANGE_U4G] = 16,
   1089     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1090     .relax_fixup[BR_RANGE_U4G] =
   1091       {
   1092 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1093 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1094 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1095 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1096 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1097 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1098 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1099 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1100 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1101 	{0, 0, 0, 0}
   1102       },
   1103   },
   1104   {
   1105     .opcode = "bltz",
   1106     .br_range = BR_RANGE_S64K,
   1107     .cond_field =
   1108       {
   1109 	{0, 20, 0x1F, false},
   1110 	{0, 0, 0, false}
   1111       },
   1112     .relax_code_seq[BR_RANGE_S256] =
   1113       {
   1114 	INSN_BLTZ	/* bltz $rt, label */
   1115       },
   1116     .relax_code_condition[BR_RANGE_S256] =
   1117       {
   1118 	{0, 20, 0x1F, false},
   1119 	{0, 0, 0, false},
   1120       },
   1121     .relax_code_size[BR_RANGE_S256] = 4,
   1122     .relax_branch_isize[BR_RANGE_S256] = 4,
   1123     .relax_fixup[BR_RANGE_S256] =
   1124       {
   1125 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1126 	{0, 0, 0, 0}
   1127       },
   1128 
   1129     .relax_code_seq[BR_RANGE_S16K] =
   1130       {
   1131 	INSN_BLTZ	/* bltz $rt, label */
   1132       },
   1133     .relax_code_condition[BR_RANGE_S16K] =
   1134       {
   1135 	{0, 20, 0x1F, false},
   1136 	{0, 0, 0, false},
   1137       },
   1138     .relax_code_size[BR_RANGE_S16K] = 4,
   1139     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1140     .relax_fixup[BR_RANGE_S16K] =
   1141       {
   1142 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1143 	{0, 0, 0, 0}
   1144       },
   1145 
   1146     .relax_code_seq[BR_RANGE_S64K] =
   1147       {
   1148 	INSN_BLTZ	/* bltz $rt, label */
   1149       },
   1150     .relax_code_condition[BR_RANGE_S64K] =
   1151       {
   1152 	{0, 20, 0x1F, false},
   1153 	{0, 0, 0, false},
   1154       },
   1155     .relax_code_size[BR_RANGE_S64K] = 4,
   1156     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1157     .relax_fixup[BR_RANGE_S64K] =
   1158       {
   1159 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1160 	{0, 0, 0, 0}
   1161       },
   1162 
   1163     .relax_code_seq[BR_RANGE_S16M] =
   1164       {
   1165 	INSN_BGEZ,	/* bgez $rt, $1 */
   1166 	INSN_J		/* j label */
   1167       },
   1168     .relax_code_condition[BR_RANGE_S16M] =
   1169       {
   1170 	{0, 20, 0x1F, false},
   1171 	{0, 0, 0, false},
   1172       },
   1173     .relax_code_size[BR_RANGE_S16M] = 8,
   1174     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1175     .relax_fixup[BR_RANGE_S16M] =
   1176       {
   1177 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1178 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1179 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1180 	{0, 0, 0, 0}
   1181       },
   1182 
   1183     .relax_code_seq[BR_RANGE_U4G] =
   1184       {
   1185 	INSN_BGEZ,	/* bgez $rt, $1 */
   1186 	INSN_SETHI_TA,	/* sethi $ta, label */
   1187 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1188 	INSN_JR_TA	/* jr $ta */
   1189       },
   1190     .relax_code_condition[BR_RANGE_U4G] =
   1191       {
   1192 	{0, 20, 0x1F, false},
   1193 	{0, 0, 0, false},
   1194       },
   1195     .relax_code_size[BR_RANGE_U4G] = 16,
   1196     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1197     .relax_fixup[BR_RANGE_U4G] =
   1198       {
   1199 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1200 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1201 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1202 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1203 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1204 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1205 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1206 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1207 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1208 	{0, 0, 0, 0}
   1209       },
   1210   },
   1211   {
   1212     .opcode = "beq",
   1213     .br_range = BR_RANGE_S16K,
   1214     .cond_field =
   1215       {
   1216 	{0, 20, 0x1F, false},
   1217 	{0, 15, 0x1F, false},
   1218 	{0, 0, 0, false}
   1219       },
   1220     .relax_code_seq[BR_RANGE_S256] =
   1221       {
   1222 	INSN_BEQ	/* beq $rt, $ra, label */
   1223       },
   1224     .relax_code_condition[BR_RANGE_S256] =
   1225       {
   1226 	{0, 20, 0x1F, false},
   1227 	{0, 15, 0x1F, false},
   1228 	{0, 0, 0, false}
   1229       },
   1230     .relax_code_size[BR_RANGE_S256] = 4,
   1231     .relax_branch_isize[BR_RANGE_S256] = 4,
   1232     .relax_fixup[BR_RANGE_S256] =
   1233       {
   1234 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1235 	{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   1236 	{0, 0, 0, 0}
   1237       },
   1238 
   1239     .relax_code_seq[BR_RANGE_S16K] =
   1240       {
   1241 	INSN_BEQ	/* beq $rt, $ra, label */
   1242       },
   1243     .relax_code_condition[BR_RANGE_S16K] =
   1244       {
   1245 	{0, 20, 0x1F, false},
   1246 	{0, 15, 0x1F, false},
   1247 	{0, 0, 0, false}
   1248       },
   1249     .relax_code_size[BR_RANGE_S16K] = 4,
   1250     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1251     .relax_fixup[BR_RANGE_S16K] =
   1252       {
   1253 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1254 	{0, 0, 0, 0}
   1255       },
   1256 
   1257     .relax_code_seq[BR_RANGE_S64K] =
   1258       {
   1259 	INSN_BNE,	/* bne $rt, $ra, $1 */
   1260 	INSN_J		/* j label */
   1261       },
   1262     .relax_code_condition[BR_RANGE_S64K] =
   1263       {
   1264 	{0, 20, 0x1F, false},
   1265 	{0, 15, 0x1F, false},
   1266 	{0, 0, 0, false}
   1267       },
   1268     .relax_code_size[BR_RANGE_S64K] = 8,
   1269     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1270     .relax_fixup[BR_RANGE_S64K] =
   1271       {
   1272 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1273 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1274 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1275 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1276 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1277 	{0, 0, 0, 0}
   1278       },
   1279 
   1280     .relax_code_seq[BR_RANGE_S16M] =
   1281       {
   1282 	INSN_BNE,	/* bne $rt, $ra, $1 */
   1283 	INSN_J		/* j label */
   1284       },
   1285     .relax_code_condition[BR_RANGE_S16M] =
   1286       {
   1287 	{0, 20, 0x1F, false},
   1288 	{0, 15, 0x1F, false},
   1289 	{0, 0, 0, false}
   1290       },
   1291     .relax_code_size[BR_RANGE_S16M] = 8,
   1292     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1293     .relax_fixup[BR_RANGE_S16M] =
   1294       {
   1295 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1296 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1297 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1298 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1299 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1300 	{0, 0, 0, 0}
   1301       },
   1302 
   1303     .relax_code_seq[BR_RANGE_U4G] =
   1304       {
   1305 	INSN_BNE,	/* bne $rt, $ra, $1 */
   1306 	INSN_SETHI_TA,	/* sethi $ta, label */
   1307 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1308 	INSN_JR_TA	/* jr $ta */
   1309       },
   1310     .relax_code_condition[BR_RANGE_U4G] =
   1311       {
   1312 	{0, 20, 0x1F, false},
   1313 	{0, 15, 0x1F, false},
   1314 	{0, 0, 0, false}
   1315       },
   1316     .relax_code_size[BR_RANGE_U4G] = 16,
   1317     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1318     .relax_fixup[BR_RANGE_U4G] =
   1319       {
   1320 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1321 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1322 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1323 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1324 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1325 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1326 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1327 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1328 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1329 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1330 	{0, 0, 0, 0}
   1331       },
   1332   },
   1333   {
   1334     .opcode = "bne",
   1335     .br_range = BR_RANGE_S16K,
   1336     .cond_field =
   1337       {
   1338 	{0, 20, 0x1F, false},
   1339 	{0, 15, 0x1F, false},
   1340 	{0, 0, 0, false}
   1341       },
   1342     .relax_code_seq[BR_RANGE_S256] =
   1343       {
   1344 	INSN_BNE	/* bne $rt, $ra, label */
   1345       },
   1346     .relax_code_condition[BR_RANGE_S256] =
   1347       {
   1348 	{0, 20, 0x1F, false},
   1349 	{0, 15, 0x1F, false},
   1350 	{0, 0, 0, false}
   1351       },
   1352     .relax_code_size[BR_RANGE_S256] = 4,
   1353     .relax_branch_isize[BR_RANGE_S256] = 4,
   1354     .relax_fixup[BR_RANGE_S256] =
   1355       {
   1356 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1357 	{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   1358 	{0, 0, 0, 0}
   1359       },
   1360 
   1361     .relax_code_seq[BR_RANGE_S16K] =
   1362       {
   1363 	INSN_BNE	/* bne $rt, $ra, label */
   1364       },
   1365     .relax_code_condition[BR_RANGE_S16K] =
   1366       {
   1367 	{0, 20, 0x1F, false},
   1368 	{0, 15, 0x1F, false},
   1369 	{0, 0, 0, false}
   1370       },
   1371     .relax_code_size[BR_RANGE_S16K] = 4,
   1372     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1373     .relax_fixup[BR_RANGE_S16K] =
   1374       {
   1375 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1376 	{0, 0, 0, 0}
   1377       },
   1378 
   1379     .relax_code_seq[BR_RANGE_S64K] =
   1380       {
   1381 	INSN_BEQ,	/* beq $rt, $ra, $1 */
   1382 	INSN_J		/* j label */
   1383       },
   1384     .relax_code_condition[BR_RANGE_S64K] =
   1385       {
   1386 	{0, 20, 0x1F, false},
   1387 	{0, 15, 0x1F, false},
   1388 	{0, 0, 0, false}
   1389       },
   1390     .relax_code_size[BR_RANGE_S64K] = 8,
   1391     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1392     .relax_fixup[BR_RANGE_S64K] =
   1393       {
   1394 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1395 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1396 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1397 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1398 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1399 	{0, 0, 0, 0}
   1400       },
   1401 
   1402     .relax_code_seq[BR_RANGE_S16M] =
   1403       {
   1404 	INSN_BEQ,	/* beq $rt, $ra, $1 */
   1405 	INSN_J		/* j label */
   1406       },
   1407     .relax_code_condition[BR_RANGE_S16M] =
   1408       {
   1409 	{0, 20, 0x1F, false},
   1410 	{0, 15, 0x1F, false},
   1411 	{0, 0, 0, false}
   1412       },
   1413     .relax_code_size[BR_RANGE_S16M] = 8,
   1414     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1415     .relax_fixup[BR_RANGE_S16M] =
   1416       {
   1417 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1418 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1419 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1420 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1421 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1422 	{0, 0, 0, 0}
   1423       },
   1424 
   1425     .relax_code_seq[BR_RANGE_U4G] =
   1426       {
   1427 	INSN_BEQ,	/* beq $rt, $ra, $1 */
   1428 	INSN_SETHI_TA,	/* sethi $ta, label */
   1429 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1430 	INSN_JR_TA	/* jr $ta */
   1431       },
   1432     .relax_code_condition[BR_RANGE_U4G] =
   1433       {
   1434 	{0, 20, 0x1F, false},
   1435 	{0, 15, 0x1F, false},
   1436 	{0, 0, 0, false}
   1437       },
   1438     .relax_code_size[BR_RANGE_U4G] = 16,
   1439     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1440     .relax_fixup[BR_RANGE_U4G] =
   1441       {
   1442 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1443 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1444 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1445 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1446 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1447 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1448 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1449 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1450 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1451 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1452 	{0, 0, 0, 0}
   1453       },
   1454   },
   1455   {
   1456     .opcode = "beqz38",
   1457     .br_range = BR_RANGE_S256,
   1458     .cond_field =
   1459       {
   1460 	{0, 8, 0x7, false},
   1461 	{0, 0, 0, false}
   1462       },
   1463     .relax_code_seq[BR_RANGE_S256] =
   1464       {
   1465 	INSN_BEQZ38 << 16	/* beqz $rt, label */
   1466       },
   1467     .relax_code_condition[BR_RANGE_S256] =
   1468       {
   1469 	{0, 8, 0x7, false},
   1470 	{0, 0, 0, false}
   1471       },
   1472     .relax_code_size[BR_RANGE_S256] = 2,
   1473     .relax_branch_isize[BR_RANGE_S256] = 2,
   1474     .relax_fixup[BR_RANGE_S256] =
   1475       {
   1476 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1477 	{0, 0, 0, 0}
   1478       },
   1479 
   1480     .relax_code_seq[BR_RANGE_S16K] =
   1481       {
   1482 	INSN_BEQZ	/* beqz $rt, label */
   1483       },
   1484     .relax_code_condition[BR_RANGE_S16K] =
   1485       {
   1486 	{0, 20, 0x1F, false},
   1487 	{0, 0, 0, false}
   1488       },
   1489     .relax_code_size[BR_RANGE_S16K] = 4,
   1490     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1491     .relax_fixup[BR_RANGE_S16K] =
   1492       {
   1493 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1494 	{0, 0, 0, 0}
   1495       },
   1496 
   1497     .relax_code_seq[BR_RANGE_S64K] =
   1498       {
   1499 	INSN_BEQZ	/* beqz $rt, label */
   1500       },
   1501     .relax_code_condition[BR_RANGE_S64K] =
   1502       {
   1503 	{0, 20, 0x1F, false},
   1504 	{0, 0, 0, false}
   1505       },
   1506     .relax_code_size[BR_RANGE_S64K] = 4,
   1507     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1508     .relax_fixup[BR_RANGE_S64K] =
   1509       {
   1510 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1511 	{0, 0, 0, 0}
   1512       },
   1513 
   1514     .relax_code_seq[BR_RANGE_S16M] =
   1515       {
   1516 	INSN_BNEZ,	/* bnez $rt, $1 */
   1517 	INSN_J		/* j label */
   1518       },
   1519     .relax_code_condition[BR_RANGE_S16M] =
   1520       {
   1521 	{0, 20, 0x1F, false},
   1522 	{0, 0, 0, false}
   1523       },
   1524     .relax_code_size[BR_RANGE_S16M] = 8,
   1525     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1526     .relax_fixup[BR_RANGE_S16M] =
   1527       {
   1528 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1529 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1530 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1531 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1532 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1533 	{0, 0, 0, 0}
   1534       },
   1535 
   1536     .relax_code_seq[BR_RANGE_U4G] =
   1537       {
   1538 	INSN_BNEZ,	/* bnez $rt, $1 */
   1539 	INSN_SETHI_TA,	/* sethi $ta, label */
   1540 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1541 	INSN_JR_TA	/* jr $ta */
   1542       },
   1543     .relax_code_condition[BR_RANGE_U4G] =
   1544       {
   1545 	{0, 20, 0x1F, false},
   1546 	{0, 0, 0, false}
   1547       },
   1548     .relax_code_size[BR_RANGE_U4G] = 16,
   1549     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1550     .relax_fixup[BR_RANGE_U4G] =
   1551       {
   1552 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1553 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1554 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1555 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1556 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1557 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1558 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1559 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1560 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1561 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1562 	{0, 0, 0, 0}
   1563       },
   1564   },
   1565   {
   1566     .opcode = "bnez38",
   1567     .br_range = BR_RANGE_S256,
   1568     .cond_field =
   1569       {
   1570 	{0, 8, 0x7, false},
   1571 	{0, 0, 0, false}
   1572       },
   1573     .relax_code_seq[BR_RANGE_S256] =
   1574       {
   1575 	INSN_BNEZ38 << 16	/* bnez $rt, label */
   1576       },
   1577     .relax_code_condition[BR_RANGE_S256] =
   1578       {
   1579 	{0, 8, 0x7, false},
   1580 	{0, 0, 0, false}
   1581       },
   1582     .relax_code_size[BR_RANGE_S256] = 2,
   1583     .relax_branch_isize[BR_RANGE_S256] = 2,
   1584     .relax_fixup[BR_RANGE_S256] =
   1585       {
   1586 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1587 	{0, 0, 0, 0}
   1588       },
   1589 
   1590     .relax_code_seq[BR_RANGE_S16K] =
   1591       {
   1592 	INSN_BNEZ	/* bnez $rt, label */
   1593       },
   1594     .relax_code_condition[BR_RANGE_S16K] =
   1595       {
   1596 	{0, 20, 0x1F, false},
   1597 	{0, 0, 0, false}
   1598       },
   1599     .relax_code_size[BR_RANGE_S16K] = 4,
   1600     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1601     .relax_fixup[BR_RANGE_S16K] =
   1602       {
   1603 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1604 	{0, 0, 0, 0}
   1605       },
   1606 
   1607     .relax_code_seq[BR_RANGE_S64K] =
   1608       {
   1609 	INSN_BNEZ	/* bnez $rt, label */
   1610       },
   1611     .relax_code_condition[BR_RANGE_S64K] =
   1612       {
   1613 	{0, 20, 0x1F, false},
   1614 	{0, 0, 0, false}
   1615       },
   1616     .relax_code_size[BR_RANGE_S64K] = 4,
   1617     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1618     .relax_fixup[BR_RANGE_S64K] =
   1619       {
   1620 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1621 	{0, 0, 0, 0}
   1622       },
   1623 
   1624     .relax_code_seq[BR_RANGE_S16M] =
   1625       {
   1626 	INSN_BEQZ,	/* beqz $rt, $1 */
   1627 	INSN_J		/* j label */
   1628       },
   1629     .relax_code_condition[BR_RANGE_S16M] =
   1630       {
   1631 	{0, 20, 0x1F, false},
   1632 	{0, 0, 0, false}
   1633       },
   1634     .relax_code_size[BR_RANGE_S16M] = 8,
   1635     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1636     .relax_fixup[BR_RANGE_S16M] =
   1637       {
   1638 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1639 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1640 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1641 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1642 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1643 	{0, 0, 0, 0}
   1644       },
   1645 
   1646     .relax_code_seq[BR_RANGE_U4G] =
   1647       {
   1648 	INSN_BEQZ,	/* beqz $rt, $1 */
   1649 	INSN_SETHI_TA,	/* sethi $ta, label */
   1650 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1651 	INSN_JR_TA	/* jr $ta */
   1652       },
   1653     .relax_code_condition[BR_RANGE_U4G] =
   1654       {
   1655 	{0, 20, 0x1F, false},
   1656 	{0, 0, 0, false}
   1657       },
   1658     .relax_code_size[BR_RANGE_U4G] = 16,
   1659     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1660     .relax_fixup[BR_RANGE_U4G] =
   1661       {
   1662 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1663 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1664 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1665 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1666 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1667 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1668 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1669 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1670 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1671 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1672 	{0, 0, 0, 0}
   1673       },
   1674   },
   1675   {
   1676     .opcode = "beqzs8",
   1677     .br_range = BR_RANGE_S256,
   1678     .cond_field =
   1679       {
   1680 	{0, 0, 0, false}
   1681       },
   1682     .relax_code_seq[BR_RANGE_S256] =
   1683       {
   1684 	INSN_BEQZS8 << 16	/* beqz $r15, label */
   1685       },
   1686     .relax_code_size[BR_RANGE_S256] = 2,
   1687     .relax_branch_isize[BR_RANGE_S256] = 2,
   1688     .relax_fixup[BR_RANGE_S256] =
   1689       {
   1690 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1691 	{0, 0, 0, 0}
   1692       },
   1693 
   1694     .relax_code_seq[BR_RANGE_S16K] =
   1695       {
   1696 	INSN_BEQZ_TA	/* beqz $r15, label */
   1697       },
   1698     .relax_code_size[BR_RANGE_S16K] = 4,
   1699     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1700     .relax_fixup[BR_RANGE_S16K] =
   1701       {
   1702 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1703 	{0, 0, 0, 0}
   1704       },
   1705 
   1706     .relax_code_seq[BR_RANGE_S64K] =
   1707       {
   1708 	INSN_BEQZ_TA	/* beqz $r15, label */
   1709       },
   1710     .relax_code_size[BR_RANGE_S64K] = 4,
   1711     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1712     .relax_fixup[BR_RANGE_S64K] =
   1713       {
   1714 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1715 	{0, 0, 0, 0}
   1716       },
   1717 
   1718     .relax_code_seq[BR_RANGE_S16M] =
   1719       {
   1720 	INSN_BNEZ_TA,	/* bnez $r15, $1 */
   1721 	INSN_J		/* j label */
   1722       },
   1723     .relax_code_size[BR_RANGE_S16M] = 8,
   1724     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1725     .relax_fixup[BR_RANGE_S16M] =
   1726       {
   1727 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1728 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1729 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1730 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1731 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1732 	{0, 0, 0, 0}
   1733       },
   1734 
   1735     .relax_code_seq[BR_RANGE_U4G] =
   1736       {
   1737 	INSN_BNEZ_TA,	/* bnez $r15, $1 */
   1738 	INSN_SETHI_TA,	/* sethi $ta, label */
   1739 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1740 	INSN_JR_TA	/* jr $ta */
   1741       },
   1742     .relax_code_size[BR_RANGE_U4G] = 16,
   1743     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1744     .relax_fixup[BR_RANGE_U4G] =
   1745       {
   1746 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1747 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1748 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1749 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1750 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1751 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1752 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1753 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1754 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1755 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1756 	{0, 0, 0, 0}
   1757       },
   1758   },
   1759   {
   1760     .opcode = "bnezs8",
   1761     .br_range = BR_RANGE_S256,
   1762     .cond_field =
   1763       {
   1764 	{0, 0, 0, false}
   1765       },
   1766     .relax_code_seq[BR_RANGE_S256] =
   1767       {
   1768 	INSN_BNEZS8 << 16	/* bnez $r15, label */
   1769       },
   1770     .relax_code_size[BR_RANGE_S256] = 2,
   1771     .relax_branch_isize[BR_RANGE_S256] = 2,
   1772     .relax_fixup[BR_RANGE_S256] =
   1773       {
   1774 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1775 	{0, 0, 0, 0}
   1776       },
   1777 
   1778     .relax_code_seq[BR_RANGE_S16K] =
   1779       {
   1780 	INSN_BNEZ_TA	/* bnez $r15, label */
   1781       },
   1782     .relax_code_size[BR_RANGE_S16K] = 4,
   1783     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1784     .relax_fixup[BR_RANGE_S16K] =
   1785       {
   1786 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1787 	{0, 0, 0, 0}
   1788       },
   1789 
   1790     .relax_code_seq[BR_RANGE_S64K] =
   1791       {
   1792 	INSN_BNEZ_TA	/* bnez $r15, label */
   1793       },
   1794     .relax_code_size[BR_RANGE_S64K] = 4,
   1795     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1796     .relax_fixup[BR_RANGE_S64K] =
   1797       {
   1798 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
   1799 	{0, 0, 0, 0}
   1800       },
   1801 
   1802     .relax_code_seq[BR_RANGE_S16M] =
   1803       {
   1804 	INSN_BEQZ_TA,	/* beqz $r15, $1 */
   1805 	INSN_J		/* j label */
   1806       },
   1807     .relax_code_size[BR_RANGE_S16M] = 8,
   1808     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1809     .relax_fixup[BR_RANGE_S16M] =
   1810       {
   1811 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1812 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1813 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1814 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1815 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1816 	{0, 0, 0, 0}
   1817       },
   1818 
   1819     .relax_code_seq[BR_RANGE_U4G] =
   1820       {
   1821 	INSN_BEQZ_TA,	/* beqz $r15, $1 */
   1822 	INSN_SETHI_TA,	/* sethi $ta, label */
   1823 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1824 	INSN_JR_TA	/* jr $ta */
   1825       },
   1826     .relax_code_size[BR_RANGE_U4G] = 16,
   1827     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1828     .relax_fixup[BR_RANGE_U4G] =
   1829       {
   1830 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1831 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1832 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1833 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1834 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1835 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1836 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1837 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1838 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1839 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1840 	{0, 0, 0, 0}
   1841       },
   1842   },
   1843   {
   1844     .opcode = "bnes38",
   1845     .br_range = BR_RANGE_S256,
   1846     .cond_field =
   1847       {
   1848 	{0, 8, 0x7, false},
   1849 	{0, 0, 0, false}
   1850       },
   1851     .relax_code_seq[BR_RANGE_S256] =
   1852       {
   1853 	INSN_BNES38 << 16	/* bne $rt, $r5, label */
   1854       },
   1855     .relax_code_condition[BR_RANGE_S256] =
   1856       {
   1857 	{0, 8, 0x7, false},
   1858 	{0, 0, 0, false}
   1859       },
   1860     .relax_code_size[BR_RANGE_S256] = 2,
   1861     .relax_branch_isize[BR_RANGE_S256] = 2,
   1862     .relax_fixup[BR_RANGE_S256] =
   1863       {
   1864 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1865 	{0, 0, 0, 0}
   1866       },
   1867 
   1868     .relax_code_seq[BR_RANGE_S16K] =
   1869       {
   1870 	INSN_BNE_R5	/* bne $rt, $r5, label */
   1871       },
   1872     .relax_code_condition[BR_RANGE_S16K] =
   1873       {
   1874 	{0, 20, 0x1F, false},
   1875 	{0, 0, 0, false}
   1876       },
   1877     .relax_code_size[BR_RANGE_S16K] = 4,
   1878     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1879     .relax_fixup[BR_RANGE_S16K] =
   1880       {
   1881 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1882 	{0, 0, 0, 0}
   1883       },
   1884 
   1885     .relax_code_seq[BR_RANGE_S64K] =
   1886       {
   1887 	INSN_BEQ_R5,	/* beq $rt, $r5, $1 */
   1888 	INSN_J		/* j label */
   1889       },
   1890     .relax_code_condition[BR_RANGE_S64K] =
   1891       {
   1892 	{0, 20, 0x1F, false},
   1893 	{0, 0, 0, false}
   1894       },
   1895     .relax_code_size[BR_RANGE_S64K] = 8,
   1896     .relax_branch_isize[BR_RANGE_S64K] = 4,
   1897     .relax_fixup[BR_RANGE_S64K] =
   1898       {
   1899 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1900 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1901 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1902 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1903 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1904 	{0, 0, 0, 0}
   1905       },
   1906 
   1907     .relax_code_seq[BR_RANGE_S16M] =
   1908       {
   1909 	INSN_BEQ_R5,	/* beq $rt, $r5, $1 */
   1910 	INSN_J		/* j label */
   1911       },
   1912     .relax_code_condition[BR_RANGE_S16M] =
   1913       {
   1914 	{0, 20, 0x1F, false},
   1915 	{0, 0, 0, false}
   1916       },
   1917     .relax_code_size[BR_RANGE_S16M] = 8,
   1918     .relax_branch_isize[BR_RANGE_S16M] = 4,
   1919     .relax_fixup[BR_RANGE_S16M] =
   1920       {
   1921 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1922 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1923 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   1924 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   1925 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1926 	{0, 0, 0, 0}
   1927       },
   1928 
   1929     .relax_code_seq[BR_RANGE_U4G] =
   1930       {
   1931 	INSN_BEQ_R5,	/* beq $rt, $r5, $1 */
   1932 	INSN_SETHI_TA,	/* sethi $ta, label */
   1933 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   1934 	INSN_JR_TA	/* jr $ta */
   1935       },
   1936     .relax_code_condition[BR_RANGE_U4G] =
   1937       {
   1938 	{0, 20, 0x1F, false},
   1939 	{0, 0, 0, false}
   1940       },
   1941     .relax_code_size[BR_RANGE_U4G] = 16,
   1942     .relax_branch_isize[BR_RANGE_U4G] = 4,
   1943     .relax_fixup[BR_RANGE_U4G] =
   1944       {
   1945 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1946 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1947 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   1948 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   1949 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1950 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   1951 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   1952 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   1953 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   1954 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   1955 	{0, 0, 0, 0}
   1956       },
   1957   },
   1958   {
   1959     .opcode = "beqs38",
   1960     .br_range = BR_RANGE_S256,
   1961     .cond_field =
   1962       {
   1963 	{0, 8, 0x7, false},
   1964 	{0, 0, 0, false}
   1965       },
   1966     .relax_code_seq[BR_RANGE_S256] =
   1967       {
   1968 	INSN_BEQS38 << 16	/* beq $rt, $r5, label */
   1969       },
   1970     .relax_code_condition[BR_RANGE_S256] =
   1971       {
   1972 	{0, 8, 0x7, false},
   1973 	{0, 0, 0, false}
   1974       },
   1975     .relax_code_size[BR_RANGE_S256] = 2,
   1976     .relax_branch_isize[BR_RANGE_S256] = 2,
   1977     .relax_fixup[BR_RANGE_S256] =
   1978       {
   1979 	{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
   1980 	{0, 0, 0, 0}
   1981       },
   1982 
   1983     .relax_code_seq[BR_RANGE_S16K] =
   1984       {
   1985 	INSN_BEQ_R5	/* beq $rt, $r5, label */
   1986       },
   1987     .relax_code_condition[BR_RANGE_S16K] =
   1988       {
   1989 	{0, 20, 0x1F, false},
   1990 	{0, 0, 0, false}
   1991       },
   1992     .relax_code_size[BR_RANGE_S16K] = 4,
   1993     .relax_branch_isize[BR_RANGE_S16K] = 4,
   1994     .relax_fixup[BR_RANGE_S16K] =
   1995       {
   1996 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   1997 	{0, 0, 0, 0}
   1998       },
   1999 
   2000     .relax_code_seq[BR_RANGE_S64K] =
   2001       {
   2002 	INSN_BNE_R5,	/* bne $rt, $r5, $1 */
   2003 	INSN_J		/* j label */
   2004       },
   2005     .relax_code_condition[BR_RANGE_S64K] =
   2006       {
   2007 	{0, 20, 0x1F, false},
   2008 	{0, 0, 0, false}
   2009       },
   2010     .relax_code_size[BR_RANGE_S64K] = 8,
   2011     .relax_branch_isize[BR_RANGE_S64K] = 4,
   2012     .relax_fixup[BR_RANGE_S64K] =
   2013       {
   2014 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   2015 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2016 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   2017 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2018 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2019 	{0, 0, 0, 0}
   2020       },
   2021 
   2022     .relax_code_seq[BR_RANGE_S16M] =
   2023       {
   2024 	INSN_BNE_R5,	/* bne $rt, $r5, $1 */
   2025 	INSN_J		/* j label */
   2026       },
   2027     .relax_code_condition[BR_RANGE_S16M] =
   2028       {
   2029 	{0, 20, 0x1F, false},
   2030 	{0, 0, 0, false}
   2031       },
   2032     .relax_code_size[BR_RANGE_S16M] = 8,
   2033     .relax_branch_isize[BR_RANGE_S16M] = 4,
   2034     .relax_fixup[BR_RANGE_S16M] =
   2035       {
   2036 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   2037 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2038 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
   2039 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2040 	{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2041 	{0, 0, 0, 0}
   2042       },
   2043 
   2044     .relax_code_seq[BR_RANGE_U4G] =
   2045       {
   2046 	INSN_BNE_R5,	/* bne $rt, $r5, $1 */
   2047 	INSN_SETHI_TA,	/* sethi $ta, label */
   2048 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   2049 	INSN_JR_TA	/* jr $ta */
   2050       },
   2051     .relax_code_condition[BR_RANGE_U4G] =
   2052       {
   2053 	{0, 20, 0x1F, false},
   2054 	{0, 0, 0, false}
   2055       },
   2056     .relax_code_size[BR_RANGE_U4G] = 16,
   2057     .relax_branch_isize[BR_RANGE_U4G] = 4,
   2058     .relax_fixup[BR_RANGE_U4G] =
   2059       {
   2060 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   2061 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2062 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
   2063 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   2064 	{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
   2065 	{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
   2066 	{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
   2067 	{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
   2068 	{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
   2069 	{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2070 	{0, 0, 0, 0}
   2071       },
   2072   },
   2073   {
   2074     .opcode = "beqc",
   2075     .br_range = BR_RANGE_S256,
   2076     .cond_field =
   2077       {
   2078 	{0, 8, 0x7FF, true},
   2079 	{0, 20, 0x1F, false},
   2080 	{0, 0, 0, false}
   2081       },
   2082     .relax_code_seq[BR_RANGE_S256] =
   2083       {
   2084 	INSN_BEQC	/* beqc $rt, imm11s, label */
   2085       },
   2086     .relax_code_condition[BR_RANGE_S256] =
   2087       {
   2088 	{0, 8, 0x7FF, false},
   2089 	{0, 20, 0x1F, false},
   2090 	{0, 0, 0, false}
   2091       },
   2092     .relax_code_size[BR_RANGE_S256] = 4,
   2093     .relax_branch_isize[BR_RANGE_S256] = 4,
   2094     .relax_fixup[BR_RANGE_S256] =
   2095       {
   2096 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2097 	{0, 0, 0, 0}
   2098       },
   2099 
   2100     .relax_code_seq[BR_RANGE_S16K] =
   2101       {
   2102 	INSN_MOVI_TA,	/* movi $ta, imm11s */
   2103 	INSN_BEQ_TA	/* beq $rt, $ta, label */
   2104       },
   2105     .relax_code_condition[BR_RANGE_S16K] =
   2106       {
   2107 	{0, 0, 0xFFFFF, false},
   2108 	{4, 20, 0x1F, false},
   2109 	{0, 0, 0, false}
   2110       },
   2111     .relax_code_size[BR_RANGE_S16K] = 8,
   2112     .relax_branch_isize[BR_RANGE_S16K] = 4,
   2113     .relax_fixup[BR_RANGE_S16K] =
   2114       {
   2115 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2116 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
   2117 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   2118 	{0, 0, 0, 0}
   2119       },
   2120 
   2121     .relax_code_seq[BR_RANGE_S64K] =
   2122       {
   2123 	INSN_BNEC,	/* bnec $rt, imm11s, $1 */
   2124 	INSN_J		/* j label */
   2125       },
   2126     .relax_code_condition[BR_RANGE_S64K] =
   2127       {
   2128 	{0, 8, 0x7FF, false},
   2129 	{0, 20, 0x1F, false},
   2130 	{0, 0, 0, false}
   2131       },
   2132     .relax_code_size[BR_RANGE_S64K] = 8,
   2133     .relax_branch_isize[BR_RANGE_S64K] = 4,
   2134     .relax_fixup[BR_RANGE_S64K] =
   2135       {
   2136 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2137 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2138 	{0, 0, 0, 0}
   2139       },
   2140 
   2141     .relax_code_seq[BR_RANGE_S16M] =
   2142       {
   2143 	INSN_BNEC,	/* bnec $rt, imm11s, $1 */
   2144 	INSN_J		/* j label */
   2145       },
   2146     .relax_code_condition[BR_RANGE_S16M] =
   2147       {
   2148 	{0, 8, 0x7FF, false},
   2149 	{0, 20, 0x1F, false},
   2150 	{0, 0, 0, false}
   2151       },
   2152     .relax_code_size[BR_RANGE_S16M] = 8,
   2153     .relax_branch_isize[BR_RANGE_S16M] = 4,
   2154     .relax_fixup[BR_RANGE_S16M] =
   2155       {
   2156 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2157 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2158 	{0, 0, 0, 0}
   2159       },
   2160 
   2161     .relax_code_seq[BR_RANGE_U4G] =
   2162       {
   2163 	INSN_BNEC,	/* bnec $rt, imm11s, $1 */
   2164 	INSN_SETHI_TA,	/* sethi $ta, label */
   2165 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   2166 	INSN_JR_TA	/* jr $ta */
   2167       },
   2168     .relax_code_condition[BR_RANGE_U4G] =
   2169       {
   2170 	{0, 8, 0x7FF, false},
   2171 	{0, 20, 0x1F, false},
   2172 	{0, 0, 0, false}
   2173       },
   2174     .relax_code_size[BR_RANGE_U4G] = 16,
   2175     .relax_branch_isize[BR_RANGE_U4G] = 4,
   2176     .relax_fixup[BR_RANGE_U4G] =
   2177       {
   2178 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2179 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   2180 	{8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
   2181 	{12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   2182 	{0, 0, 0, 0}
   2183       },
   2184   },
   2185   {
   2186     .opcode = "bnec",
   2187     .br_range = BR_RANGE_S256,
   2188     .cond_field =
   2189       {
   2190 	{0, 8, 0x7FF, true},
   2191 	{0, 20, 0x1F, false},
   2192 	{0, 0, 0, false}
   2193       },
   2194     .relax_code_seq[BR_RANGE_S256] =
   2195       {
   2196 	  INSN_BNEC	/* bnec $rt, imm11s, label */
   2197       },
   2198     .relax_code_condition[BR_RANGE_S256] =
   2199       {
   2200 	{0, 8, 0x7FF, false},
   2201 	{0, 20, 0x1F, false},
   2202 	{0, 0, 0, false}
   2203       },
   2204     .relax_code_size[BR_RANGE_S256] = 4,
   2205     .relax_branch_isize[BR_RANGE_S256] = 4,
   2206     .relax_fixup[BR_RANGE_S256] =
   2207       {
   2208 	{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2209 	{0, 0, 0, 0}
   2210       },
   2211 
   2212     .relax_code_seq[BR_RANGE_S16K] =
   2213       {
   2214 	INSN_MOVI_TA,	/* movi $ta, imm11s */
   2215 	INSN_BNE_TA	/* bne $rt, $ta, label */
   2216       },
   2217     .relax_code_condition[BR_RANGE_S16K] =
   2218       {
   2219 	{0, 0, 0xFFFFF, false},
   2220 	{4, 20, 0x1F, false},
   2221 	{0, 0, 0, false}
   2222       },
   2223     .relax_code_size[BR_RANGE_S16K] = 8,
   2224     .relax_branch_isize[BR_RANGE_S16K] = 4,
   2225     .relax_fixup[BR_RANGE_S16K] =
   2226       {
   2227 	{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
   2228 	{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
   2229 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
   2230 	{0, 0, 0, 0}
   2231       },
   2232 
   2233     .relax_code_seq[BR_RANGE_S64K] =
   2234       {
   2235 	INSN_BEQC,	/* beqc $rt, imm11s, $1 */
   2236 	INSN_J		/* j label */
   2237       },
   2238     .relax_code_condition[BR_RANGE_S64K] =
   2239       {
   2240 	{0, 8, 0x7FF, false},
   2241 	{0, 20, 0x1F, false},
   2242 	{0, 0, 0, false}
   2243       },
   2244     .relax_code_size[BR_RANGE_S64K] = 8,
   2245     .relax_branch_isize[BR_RANGE_S64K] = 4,
   2246     .relax_fixup[BR_RANGE_S64K] =
   2247       {
   2248 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2249 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2250 	{0, 0, 0, 0}
   2251       },
   2252 
   2253     .relax_code_seq[BR_RANGE_S16M] =
   2254       {
   2255 	INSN_BEQC,	/* beqc $rt, imm11s, $1 */
   2256 	INSN_J		/* j label */
   2257       },
   2258     .relax_code_condition[BR_RANGE_S16M] =
   2259       {
   2260 	{0, 8, 0x7FF, false},
   2261 	{0, 20, 0x1F, false},
   2262 	{0, 0, 0, false}
   2263       },
   2264     .relax_code_size[BR_RANGE_S16M] = 8,
   2265     .relax_branch_isize[BR_RANGE_S16M] = 4,
   2266     .relax_fixup[BR_RANGE_S16M] =
   2267       {
   2268 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2269 	{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
   2270 	{0, 0, 0, 0}
   2271       },
   2272 
   2273     .relax_code_seq[BR_RANGE_U4G] =
   2274       {
   2275 	INSN_BEQC,	/* beqc $rt, imm11s, $1 */
   2276 	INSN_SETHI_TA,	/* sethi $ta, label */
   2277 	INSN_ORI_TA,	/* ori $ta, $ta, label */
   2278 	INSN_JR_TA	/* jr $ta */
   2279       },
   2280     .relax_code_condition[BR_RANGE_U4G] =
   2281       {
   2282 	{0, 8, 0x7FF, false},
   2283 	{0, 20, 0x1F, false},
   2284 	{0, 0, 0, false}
   2285       },
   2286     .relax_code_size[BR_RANGE_U4G] = 16,
   2287     .relax_branch_isize[BR_RANGE_U4G] = 4,
   2288     .relax_fixup[BR_RANGE_U4G] =
   2289       {
   2290 	{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
   2291 	{4, 4, 0, BFD_RELOC_NDS32_HI20},
   2292 	{8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
   2293 	{12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   2294 	{0, 0, 0, 0}
   2295       },
   2296   },
   2297   {
   2298     .opcode = NULL,
   2299   },
   2300 };
   2301 
   2302 
   2304 /* GAS definitions for command-line options.  */
   2305 enum options
   2306 {
   2307   OPTION_BIG = OPTION_MD_BASE,
   2308   OPTION_LITTLE,
   2309   OPTION_TURBO,
   2310   OPTION_PIC,
   2311   OPTION_RELAX_FP_AS_GP_OFF,
   2312   OPTION_RELAX_B2BB_ON,
   2313   OPTION_RELAX_ALL_OFF,
   2314   OPTION_OPTIMIZE,
   2315   OPTION_OPTIMIZE_SPACE
   2316 };
   2317 
   2318 const char md_shortopts[] = "m:O:";
   2319 const struct option md_longopts[] =
   2320 {
   2321   {"O1", no_argument, NULL, OPTION_OPTIMIZE},
   2322   {"Os", no_argument, NULL, OPTION_OPTIMIZE_SPACE},
   2323   {"big", no_argument, NULL, OPTION_BIG},
   2324   {"little", no_argument, NULL, OPTION_LITTLE},
   2325   {"EB", no_argument, NULL, OPTION_BIG},
   2326   {"EL", no_argument, NULL, OPTION_LITTLE},
   2327   {"meb", no_argument, NULL, OPTION_BIG},
   2328   {"mel", no_argument, NULL, OPTION_LITTLE},
   2329   {"mall-ext", no_argument, NULL, OPTION_TURBO},
   2330   {"mext-all", no_argument, NULL, OPTION_TURBO},
   2331   {"mpic", no_argument, NULL, OPTION_PIC},
   2332   /* Relaxation related options.  */
   2333   {"mno-fp-as-gp-relax", no_argument, NULL, OPTION_RELAX_FP_AS_GP_OFF},
   2334   {"mb2bb", no_argument, NULL, OPTION_RELAX_B2BB_ON},
   2335   {"mno-all-relax", no_argument, NULL, OPTION_RELAX_ALL_OFF},
   2336   {NULL, no_argument, NULL, 0}
   2337 };
   2338 
   2339 const size_t md_longopts_size = sizeof (md_longopts);
   2340 
   2341 struct nds32_parse_option_table
   2342 {
   2343   const char *name;		/* Option string.  */
   2344   const char *help;			/* Help description.  */
   2345   int (*func) (const char *arg);	/* How to parse it.  */
   2346 };
   2347 
   2348 
   2349 /* The value `-1' represents this option has *NOT* been set.  */
   2350 #ifdef NDS32_DEFAULT_ARCH_NAME
   2351 static const char* nds32_arch_name = NDS32_DEFAULT_ARCH_NAME;
   2352 #else
   2353 static const char* nds32_arch_name = "v3";
   2354 #endif
   2355 static int nds32_baseline = -1;
   2356 static int nds32_gpr16 = -1;
   2357 static int nds32_fpu_sp_ext = -1;
   2358 static int nds32_fpu_dp_ext = -1;
   2359 static int nds32_freg = -1;
   2360 static int nds32_abi = -1;
   2361 
   2362 /* Record ELF flags */
   2363 static int nds32_elf_flags = 0;
   2364 static int nds32_fpu_com = 0;
   2365 
   2366 static int nds32_parse_arch (const char *str);
   2367 static int nds32_parse_baseline (const char *str);
   2368 static int nds32_parse_freg (const char *str);
   2369 static int nds32_parse_abi (const char *str);
   2370 static void add_mapping_symbol (enum mstate state,
   2371 				unsigned int padding_byte,
   2372 				unsigned int align);
   2373 
   2374 static struct nds32_parse_option_table parse_opts [] =
   2375 {
   2376   {"arch=", N_("<arch name>\t  Assemble for architecture <arch name>\n\
   2377 			  <arch name> could be\n\
   2378 			  v3, v3j, v3m, v3f, v3s, "\
   2379 			  "v2, v2j, v2f, v2s"), nds32_parse_arch},
   2380   {"baseline=", N_("<baseline>\t  Assemble for baseline <baseline>\n\
   2381 			  <baseline> could be v2, v3, v3m"),
   2382 		  nds32_parse_baseline},
   2383   {"fpu-freg=", N_("<freg>\t  Specify a FPU configuration\n\
   2384 			  <freg>\n\
   2385 			  0:     8 SP /  4 DP registers\n\
   2386 			  1:    16 SP /  8 DP registers\n\
   2387 			  2:    32 SP / 16 DP registers\n\
   2388 			  3:    32 SP / 32 DP registers"), nds32_parse_freg},
   2389   {"abi=", N_("<abi>\t          Specify a abi version\n\
   2390 			  <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi},
   2391   {NULL, NULL, NULL}
   2392 };
   2393 
   2394 static int nds32_mac = 1;
   2395 static int nds32_div = 1;
   2396 static int nds32_16bit_ext = 1;
   2397 static int nds32_dx_regs = NDS32_DEFAULT_DX_REGS;
   2398 static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT;
   2399 static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2;
   2400 static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT;
   2401 static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT;
   2402 static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT;
   2403 static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT;
   2404 static int nds32_fpu_fma = 0;
   2405 static int nds32_pic = 0;
   2406 static int nds32_relax_fp_as_gp = 1;
   2407 static int nds32_relax_b2bb = 0;
   2408 static int nds32_relax_all = 1;
   2409 struct nds32_set_option_table
   2410 {
   2411   const char *name;		/* Option string.  */
   2412   const char *help;			/* Help description.  */
   2413   int *var;			/* Variable to be set.  */
   2414   int value;			/* Value to set.  */
   2415 };
   2416 
   2417 /* The option in this group has both Enable/Disable settings.
   2418    Just list on here.  */
   2419 
   2420 static struct nds32_set_option_table toggle_opts [] =
   2421 {
   2422   {"mac", N_("Multiply instructions support"), &nds32_mac, 1},
   2423   {"div", N_("Divide instructions support"), &nds32_div, 1},
   2424   {"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext, 1},
   2425   {"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs, 1},
   2426   {"perf-ext", N_("Performance extension"), &nds32_perf_ext, 1},
   2427   {"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2, 1},
   2428   {"string-ext", N_("String extension"), &nds32_string_ext, 1},
   2429   {"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16, 1},
   2430   {"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext, 1},
   2431   {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
   2432   {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
   2433   {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
   2434   {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1},
   2435   {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1},
   2436   {NULL, NULL, NULL, 0}
   2437 };
   2438 
   2439 
   2440 /* GAS declarations.  */
   2442 
   2443 /* This is the callback for nds32-asm.c to parse operands.  */
   2444 int
   2445 nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
   2446 			 struct nds32_asm_insn *pinsn,
   2447 			 char **pstr, int64_t *value);
   2448 
   2449 
   2450 static struct nds32_asm_desc asm_desc;
   2452 
   2453 /* md_after_parse_args ()
   2454 
   2455    GAS will call md_after_parse_args whenever it is defined.
   2456    This function checks any conflicting options specified.  */
   2457 
   2458 void
   2459 nds32_after_parse_args (void)
   2460 {
   2461   /* If -march option is not used in command-line, set the value of option
   2462      variable according to NDS32_DEFAULT_ARCH_NAME.  */
   2463   nds32_parse_arch (nds32_arch_name);
   2464 }
   2465 
   2466 /* This function is called when printing usage message (--help).  */
   2467 
   2468 void
   2469 md_show_usage (FILE *stream)
   2470 {
   2471   struct nds32_parse_option_table *coarse_tune;
   2472   struct nds32_set_option_table *fine_tune;
   2473 
   2474   fprintf (stream, _("\n NDS32-specific assembler options:\n"));
   2475   fprintf (stream, _("\
   2476   -O1,			  Optimize for performance\n\
   2477   -Os			  Optimize for space\n"));
   2478   fprintf (stream, _("\
   2479   -EL, -mel or -little    Produce little endian output\n\
   2480   -EB, -meb or -big       Produce big endian output\n\
   2481   -mpic			  Generate PIC\n\
   2482   -mno-fp-as-gp-relax	  Suppress fp-as-gp relaxation for this file\n\
   2483   -mb2bb-relax		  Back-to-back branch optimization\n\
   2484   -mno-all-relax	  Suppress all relaxation for this file\n"));
   2485 
   2486   for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
   2487     {
   2488       if (coarse_tune->help != NULL)
   2489 	fprintf (stream, _("  -m%s%s\n"),
   2490 		 coarse_tune->name, _(coarse_tune->help));
   2491     }
   2492 
   2493   for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
   2494     {
   2495       if (fine_tune->help != NULL)
   2496 	fprintf (stream, _("  -m[no-]%-17sEnable/Disable %s\n"),
   2497 		 fine_tune->name, _(fine_tune->help));
   2498     }
   2499 
   2500   fprintf (stream, _("\
   2501   -mall-ext		  Turn on all extensions and instructions support\n"));
   2502 }
   2503 
   2504 void
   2505 nds32_frag_init (fragS *fragp)
   2506 {
   2507   fragp->tc_frag_data.flag = 0;
   2508   fragp->tc_frag_data.opcode = NULL;
   2509   fragp->tc_frag_data.fixup = NULL;
   2510 }
   2511 
   2512 
   2513 
   2515 /* This function reads an expression from a C string and returns a pointer past
   2516    the end of the expression.  */
   2517 
   2518 static char *
   2519 parse_expression (char *str, expressionS *exp)
   2520 {
   2521   char *s;
   2522   char *tmp;
   2523 
   2524   tmp = input_line_pointer;	/* Save line pointer.  */
   2525   input_line_pointer = str;
   2526   expression (exp);
   2527   resolve_register (exp);
   2528   s = input_line_pointer;
   2529   input_line_pointer = tmp;	/* Restore line pointer.  */
   2530 
   2531   return s;			/* Return pointer to where parsing stopped.  */
   2532 }
   2533 
   2534 void
   2535 nds32_start_line_hook (void)
   2536 {
   2537 }
   2538 
   2539 /*
   2541  * Pseudo opcodes
   2542  */
   2543 
   2544 typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], unsigned int pv);
   2545 struct nds32_pseudo_opcode
   2546 {
   2547   const char *opcode;
   2548   int argc;
   2549   nds32_pseudo_opcode_func proc;
   2550   unsigned int pseudo_val;
   2551 
   2552   /* Some instructions are not pseudo opcode, but they might still be
   2553      expanded or changed with other instruction combination for some
   2554      conditions.  We also apply this structure to assist such work.
   2555 
   2556      For example, if the distance of branch target '.L0' is larger than
   2557      imm8s<<1 range,
   2558 
   2559      the instruction:
   2560 
   2561          beqzs8 .L0
   2562 
   2563      will be transformed into:
   2564 
   2565          bnezs8  .LCB0
   2566          j  .L0
   2567        .LCB0:
   2568 
   2569      However, sometimes we do not want assembler to do such changes
   2570      because compiler knows how to generate corresponding instruction sequence.
   2571      Use this field to indicate that this opcode is also a physical instruction.
   2572      If the flag 'verbatim' is nozero and this opcode
   2573      is a physical instruction, we should not expand it.  */
   2574   int physical_op;
   2575 };
   2576 #define PV_DONT_CARE 0
   2577 
   2578 static htab_t nds32_pseudo_opcode_hash = NULL;
   2579 
   2580 static int
   2581 builtin_isreg (const char *s, const char *x ATTRIBUTE_UNUSED)
   2582 {
   2583   if (s [0] == '$' && str_hash_find (nds32_gprs_hash, (s + 1)))
   2584     return 1;
   2585   return 0;
   2586 }
   2587 
   2588 static int
   2589 builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
   2590 {
   2591   struct nds32_keyword *k;
   2592   if (*s != '$')
   2593     return -1;
   2594   s++;
   2595   k = str_hash_find (nds32_gprs_hash, s);
   2596 
   2597   if (k == NULL)
   2598     return -1;
   2599 
   2600   return k->value;
   2601 }
   2602 
   2603 static int
   2604 builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
   2605 {
   2606   const char *ptr = s;
   2607 
   2608   while (*ptr != '+' && *ptr != '-' && *ptr)
   2609     ++ptr;
   2610 
   2611   if (*ptr == 0)
   2612     return 0;
   2613   else
   2614     return strtol (ptr, NULL, 0);
   2615 }
   2616 
   2617 static void
   2618 md_assemblef (const char *format, ...)
   2619 {
   2620   /* FIXME: hope this is long enough.  */
   2621   char line[1024];
   2622   va_list ap;
   2623   unsigned int r;
   2624 
   2625   va_start (ap, format);
   2626   r = vsnprintf (line, sizeof (line), format, ap);
   2627   md_assemble (line);
   2628 
   2629   gas_assert (r < sizeof (line));
   2630 }
   2631 
   2632 /* Some prototypes here, since some op may use another op.  */
   2633 static void do_pseudo_li_internal (const char *rt, int imm32s);
   2634 static void do_pseudo_move_reg_internal (char *dst, char *src);
   2635 
   2636 static void
   2637 do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
   2638 	     unsigned int pv ATTRIBUTE_UNUSED)
   2639 {
   2640   char *arg_label = argv[0];
   2641   relaxing = true;
   2642   /* b   label */
   2643   if (nds32_pic)
   2644     {
   2645       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2646       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2647       md_assemble  ((char *) "add $ta,$ta,$gp");
   2648       md_assemble  ((char *) "jr $ta");
   2649     }
   2650   else
   2651     {
   2652       md_assemblef ("j %s", arg_label);
   2653     }
   2654   relaxing = false;
   2655 }
   2656 
   2657 static void
   2658 do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
   2659 	       unsigned int pv ATTRIBUTE_UNUSED)
   2660 {
   2661   char *arg_label = argv[0];
   2662   relaxing = true;
   2663   /* bal|call  label */
   2664   if (nds32_pic)
   2665     {
   2666       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2667       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2668       md_assemble ((char *) "add $ta,$ta,$gp");
   2669       md_assemble ((char *) "jral $ta");
   2670     }
   2671   else
   2672     {
   2673       md_assemblef ("jal %s", arg_label);
   2674     }
   2675   relaxing = false;
   2676 }
   2677 
   2678 static void
   2679 do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[],
   2680 	       unsigned int pv ATTRIBUTE_UNUSED)
   2681 {
   2682   /* rt5, ra5, label */
   2683   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
   2684   md_assemblef ("beqz $ta,%s", argv[2]);
   2685 }
   2686 
   2687 static void
   2688 do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[],
   2689 		unsigned int pv ATTRIBUTE_UNUSED)
   2690 {
   2691   /* rt5, ra5, label */
   2692   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
   2693   md_assemblef ("beqz $ta,%s", argv[2]);
   2694 }
   2695 
   2696 static void
   2697 do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[],
   2698 	       unsigned int pv ATTRIBUTE_UNUSED)
   2699 {
   2700   /* bgt rt5, ra5, label */
   2701   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
   2702   md_assemblef ("bnez $ta,%s", argv[2]);
   2703 }
   2704 
   2705 static void
   2706 do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[],
   2707 		unsigned int pv ATTRIBUTE_UNUSED)
   2708 {
   2709   /* bgt rt5, ra5, label */
   2710   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
   2711   md_assemblef ("bnez $ta,%s", argv[2]);
   2712 }
   2713 
   2714 static void
   2715 do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[],
   2716 	       unsigned int pv ATTRIBUTE_UNUSED)
   2717 {
   2718   /* bgt rt5, ra5, label */
   2719   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
   2720   md_assemblef ("beqz $ta,%s", argv[2]);
   2721 }
   2722 
   2723 static void
   2724 do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[],
   2725 		unsigned int pv ATTRIBUTE_UNUSED)
   2726 {
   2727   /* bgt rt5, ra5, label */
   2728   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
   2729   md_assemblef ("beqz $ta,%s", argv[2]);
   2730 }
   2731 
   2732 static void
   2733 do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[],
   2734 	       unsigned int pv ATTRIBUTE_UNUSED)
   2735 {
   2736   /* rt5, ra5, label */
   2737   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
   2738   md_assemblef ("bnez $ta,%s", argv[2]);
   2739 }
   2740 
   2741 static void
   2742 do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[],
   2743 		unsigned int pv ATTRIBUTE_UNUSED)
   2744 {
   2745   /* rt5, ra5, label */
   2746   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
   2747   md_assemblef ("bnez $ta,%s", argv[2]);
   2748 }
   2749 
   2750 static void
   2751 do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[],
   2752 	      unsigned int pv ATTRIBUTE_UNUSED)
   2753 {
   2754   md_assemblef ("jr %s", argv[0]);
   2755 }
   2756 
   2757 static void
   2758 do_pseudo_bral (int argc, char *argv[],
   2759 		unsigned int pv ATTRIBUTE_UNUSED)
   2760 {
   2761   if (argc == 1)
   2762     md_assemblef ("jral $lp,%s", argv[0]);
   2763   else
   2764     md_assemblef ("jral %s,%s", argv[0], argv[1]);
   2765 }
   2766 
   2767 static void
   2768 do_pseudo_la_internal (const char *arg_reg, char *arg_label,
   2769 		       const char *line)
   2770 {
   2771   expressionS exp;
   2772 
   2773   parse_expression (arg_label, &exp);
   2774   if (exp.X_op != O_symbol)
   2775     {
   2776       as_bad (_("la must use with symbol. '%s'"), line);
   2777       return;
   2778     }
   2779 
   2780   relaxing = true;
   2781   /* rt, label */
   2782   if (!nds32_pic && !strstr (arg_label, "@"))
   2783     {
   2784       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
   2785       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
   2786     }
   2787   else if (strstr (arg_label, "@TPOFF"))
   2788     {
   2789       /* la $rt, sym@TPOFF  */
   2790       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2791       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2792       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
   2793     }
   2794   else if (strstr(arg_label, "@GOTTPOFF"))
   2795     {
   2796       /* la $rt, sym@GOTTPOFF*/
   2797       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2798       md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
   2799       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
   2800     }
   2801   else if (nds32_pic && ((strstr (arg_label, "@PLT")
   2802 			  || strstr (arg_label, "@GOTOFF"))))
   2803     {
   2804       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2805       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2806       md_assemblef ("add %s,$ta,$gp", arg_reg);
   2807     }
   2808   else if (nds32_pic && strstr (arg_label, "@GOT"))
   2809     {
   2810       long addend = builtin_addend (arg_label, NULL);
   2811 
   2812       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2813       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2814       md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
   2815       if (addend != 0)
   2816 	{
   2817 	  if (addend < 0x4000 && addend >= -0x4000)
   2818 	    {
   2819 	      md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
   2820 	    }
   2821 	  else
   2822 	    {
   2823 	      do_pseudo_li_internal ("$ta", addend);
   2824 	      md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
   2825 	    }
   2826 	}
   2827     }
   2828    else
   2829       as_bad (_("need PIC qualifier with symbol. '%s'"), line);
   2830   relaxing = false;
   2831 }
   2832 
   2833 static void
   2834 do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[],
   2835 	      unsigned int pv ATTRIBUTE_UNUSED)
   2836 {
   2837   do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
   2838 }
   2839 
   2840 static void
   2841 do_pseudo_li_internal (const char *rt, int imm32s)
   2842 {
   2843   if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
   2844     md_assemblef ("movi55 %s,%d", rt, imm32s);
   2845   else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
   2846     md_assemblef ("movi %s,%d", rt, imm32s);
   2847   else if ((imm32s & 0xfff) == 0)
   2848     md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
   2849   else
   2850     {
   2851       md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
   2852       md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
   2853     }
   2854 }
   2855 
   2856 static void
   2857 do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[],
   2858 	      unsigned int pv ATTRIBUTE_UNUSED)
   2859 {
   2860   /* Validate argv[1] for constant expression.  */
   2861   expressionS exp;
   2862 
   2863   parse_expression (argv[1], &exp);
   2864   if (exp.X_op != O_constant)
   2865     {
   2866       as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
   2867       return;
   2868     }
   2869 
   2870   do_pseudo_li_internal (argv[0], exp.X_add_number);
   2871 }
   2872 
   2873 static void
   2874 do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[],
   2875 		  unsigned int pv)
   2876 {
   2877   char ls = 'r';
   2878   char size = 'x';
   2879   const char *sign = "";
   2880 
   2881   /* Prepare arguments for various load/store.  */
   2882   sign = (pv & 0x10) ? "s" : "";
   2883   ls = (pv & 0x80000000) ? 's' : 'l';
   2884   switch (pv & 0x3)
   2885     {
   2886     case 0: size = 'b'; break;
   2887     case 1: size = 'h'; break;
   2888     case 2: size = 'w'; break;
   2889     }
   2890 
   2891   if (ls == 's' || size == 'w')
   2892     sign = "";
   2893 
   2894   if (builtin_isreg (argv[1], NULL))
   2895     {
   2896       /* lwi */
   2897       md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
   2898     }
   2899   else if (!nds32_pic)
   2900     {
   2901       relaxing = true;
   2902       if (strstr (argv[1], "@TPOFF"))
   2903 	{
   2904 	  /* ls.w $rt, sym@TPOFF  */
   2905 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2906 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2907 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
   2908 	}
   2909       else if (strstr (argv[1], "@GOTTPOFF"))
   2910 	{
   2911 	  /* ls.w $rt, sym@GOTTPOFF  */
   2912 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2913 	  md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
   2914 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
   2915 	}
   2916       else
   2917 	{
   2918 	  /* lwi */
   2919 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2920 	  md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
   2921 	}
   2922       relaxing = false;
   2923     }
   2924   else
   2925     {
   2926       relaxing = true;
   2927       /* PIC code.  */
   2928       if (strstr (argv[1], "@GOTOFF"))
   2929 	{
   2930 	  /* lw */
   2931 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2932 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2933 	  md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
   2934 	}
   2935       else if (strstr (argv[1], "@GOT"))
   2936 	{
   2937 	  long addend = builtin_addend (argv[1], NULL);
   2938 	  /* lw */
   2939 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2940 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2941 	  md_assemble ((char *) "lw $ta,[$gp+$ta]");	/* Load address word.  */
   2942 	  if (addend < 0x10000 && addend >= -0x10000)
   2943 	    {
   2944 	      md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
   2945 	    }
   2946 	  else
   2947 	    {
   2948 	      /* lw */
   2949 	      do_pseudo_li_internal (argv[0], addend);
   2950 	      md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
   2951 	    }
   2952 	}
   2953       else
   2954 	{
   2955 	  as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
   2956 	}
   2957       relaxing = false;
   2958     }
   2959 }
   2960 
   2961 static void
   2962 do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[],
   2963 		   unsigned int pv)
   2964 {
   2965   char *arg_rt = argv[0];
   2966   char *arg_label = argv[1];
   2967   char *arg_inc = argv[2];
   2968   char ls = 'r';
   2969   char size = 'x';
   2970   const char *sign = "";
   2971 
   2972   /* Prepare arguments for various load/store.  */
   2973   sign = (pv & 0x10) ? "s" : "";
   2974   ls = (pv & 0x80000000) ? 's' : 'l';
   2975   switch (pv & 0x3)
   2976     {
   2977     case 0: size = 'b'; break;
   2978     case 1: size = 'h'; break;
   2979     case 2: size = 'w'; break;
   2980     }
   2981 
   2982   if (ls == 's' || size == 'w')
   2983     sign = "";
   2984 
   2985   do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
   2986   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
   2987 }
   2988 
   2989 static void
   2990 do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[],
   2991 		    unsigned int pv)
   2992 {
   2993   char *arg_rt = argv[0];
   2994   char *arg_inc = argv[1];
   2995   char ls = 'r';
   2996   char size = 'x';
   2997   const char *sign = "";
   2998 
   2999   /* Prepare arguments for various load/store.  */
   3000   sign = (pv & 0x10) ? "s" : "";
   3001   ls = (pv & 0x80000000) ? 's' : 'l';
   3002   switch (pv & 0x3)
   3003     {
   3004     case 0: size = 'b'; break;
   3005     case 1: size = 'h'; break;
   3006     case 2: size = 'w'; break;
   3007     }
   3008 
   3009   if (ls == 's' || size == 'w')
   3010     sign = "";
   3011 
   3012   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
   3013 }
   3014 
   3015 static void
   3016 do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[],
   3017 		   unsigned int pv)
   3018 {
   3019   char ls = 'r';
   3020   char size = 'x';
   3021   const char *sign = "";
   3022 
   3023   /* Prepare arguments for various load/store.  */
   3024   sign = (pv & 0x10) ? "s" : "";
   3025   ls = (pv & 0x80000000) ? 's' : 'l';
   3026   switch (pv & 0x3)
   3027     {
   3028     case 0: size = 'b'; break;
   3029     case 1: size = 'h'; break;
   3030     case 2: size = 'w'; break;
   3031     }
   3032 
   3033   if (ls == 's' || size == 'w')
   3034     sign = "";
   3035 
   3036   md_assemblef ("%c%c%si.bi %s,%s,%s",
   3037 		ls, size, sign, argv[0], argv[1], argv[2]);
   3038 }
   3039 
   3040 static void
   3041 do_pseudo_move_reg_internal (char *dst, char *src)
   3042 {
   3043   if (enable_16bit)
   3044     md_assemblef ("mov55 %s,%s", dst, src);
   3045   else
   3046     md_assemblef ("ori %s,%s,0", dst, src);
   3047 }
   3048 
   3049 static void
   3050 do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[],
   3051 		unsigned int pv ATTRIBUTE_UNUSED)
   3052 {
   3053   expressionS exp;
   3054 
   3055   if (builtin_isreg (argv[1], NULL))
   3056     do_pseudo_move_reg_internal (argv[0], argv[1]);
   3057   else
   3058     {
   3059       parse_expression (argv[1], &exp);
   3060       if (exp.X_op == O_constant)
   3061 	/* move $rt, imm  -> li $rt, imm  */
   3062 	do_pseudo_li_internal (argv[0], exp.X_add_number);
   3063       else
   3064 	/* l.w $rt, var  -> l.w $rt, var  */
   3065 	do_pseudo_ls_bhw (argc, argv, 2);
   3066     }
   3067 }
   3068 
   3069 static void
   3070 do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[],
   3071 	       unsigned int pv ATTRIBUTE_UNUSED)
   3072 {
   3073   /* Instead of "subri".  */
   3074   md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
   3075 }
   3076 
   3077 static void
   3078 do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[],
   3079 	       unsigned int pv ATTRIBUTE_UNUSED)
   3080 {
   3081   md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
   3082 }
   3083 
   3084 static void
   3085 do_pseudo_pushpopm (int argc, char *argv[],
   3086 		    unsigned int pv ATTRIBUTE_UNUSED)
   3087 {
   3088   /* posh/pop $ra, $rb */
   3089   /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
   3090   int rb, re, ra, en4;
   3091   int i;
   3092   const char *opc = "pushpopm";
   3093 
   3094   if (argc == 3)
   3095     as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated.  "
   3096 	    "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
   3097   else if (argc == 1)
   3098     as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
   3099 
   3100   if (strstr (argv[argc], "pop") == argv[argc])
   3101     opc = "lmw.bim";
   3102   else if (strstr (argv[argc], "push") == argv[argc])
   3103     opc = "smw.adm";
   3104   else
   3105     as_fatal ("nds32-as internal error. %s", argv[argc]);
   3106 
   3107   rb = builtin_regnum (argv[0], NULL);
   3108   re = builtin_regnum (argv[1], NULL);
   3109 
   3110   if (re < rb)
   3111     {
   3112       as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
   3113       /* Swap to right order.  */
   3114       ra = re;
   3115       re = rb;
   3116       rb = ra;
   3117     }
   3118 
   3119   /* Build enable4 mask.  */
   3120   en4 = 0;
   3121   if (re >= 28 || rb >= 28)
   3122     {
   3123       for (i = (rb >= 28? rb: 28); i <= re; i++)
   3124 	en4 |= 1 << (3 - (i - 28));
   3125     }
   3126 
   3127   /* Adjust $re, $rb.  */
   3128   if (rb >= 28)
   3129     rb = re = 31;
   3130   else if (nds32_gpr16 != 1 && re >= 28)
   3131     re = 27;
   3132 
   3133   /* Reduce register.  */
   3134   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
   3135     {
   3136       if (re >= 15 && strstr (opc, "smw") != NULL)
   3137 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
   3138       if (rb <= 10)
   3139 	md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
   3140       if (re >= 15 && strstr (opc, "lmw") != NULL)
   3141 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
   3142     }
   3143   else
   3144     md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
   3145 }
   3146 
   3147 static void
   3148 do_pseudo_pushpop (int argc, char *argv[],
   3149 		   unsigned int pv ATTRIBUTE_UNUSED)
   3150 {
   3151   /* push/pop $ra5, $label=$sp */
   3152   char *argvm[3];
   3153 
   3154   if (argc == 2)
   3155     as_bad ("'push/pop $ra5, rb5' is deprecated.  "
   3156 	    "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
   3157 
   3158   argvm[0] = argv[0];
   3159   argvm[1] = argv[0];
   3160   argvm[2] = argv[argc];
   3161   do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
   3162 }
   3163 
   3164 static void
   3165 do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[],
   3166 		  unsigned int pv ATTRIBUTE_UNUSED)
   3167 {
   3168   md_assemblef ("push25 %s,%s", argv[0], argv[1]);
   3169 }
   3170 
   3171 static void
   3172 do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[],
   3173 		 unsigned int pv ATTRIBUTE_UNUSED)
   3174 {
   3175   md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
   3176 }
   3177 
   3178 /* pv == 0, parsing "push.s" pseudo instruction operands.
   3179    pv != 0, parsing "pop.s" pseudo instruction operands.  */
   3180 
   3181 static void
   3182 do_pseudo_pushpop_stack (int argc, char *argv[],
   3183 			 unsigned int pv)
   3184 {
   3185   /* push.s Rb,Re,{$fp $gp $lp $sp}  ==>  smw.adm Rb,[$sp],Re,Eable4  */
   3186   /* pop.s Rb,Re,{$fp $gp $lp $sp}   ==>  lmw.bim Rb,[$sp],Re,Eable4  */
   3187 
   3188   int rb, re;
   3189   int en4;
   3190   int last_arg_index;
   3191   const char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
   3192 
   3193   rb = re = 0;
   3194 
   3195   if (argc == 1)
   3196     {
   3197       /* argc=1, operands pattern: { $fp $gp $lp $sp }  */
   3198 
   3199       /* Set register number Rb = Re = $sp = $r31.  */
   3200       rb = re = 31;
   3201     }
   3202   else if (argc == 2 || argc == 3)
   3203     {
   3204       /* argc=2, operands pattern: Rb, Re  */
   3205       /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp }  */
   3206 
   3207       /* Get register number in integer.  */
   3208       rb = builtin_regnum (argv[0], NULL);
   3209       re = builtin_regnum (argv[1], NULL);
   3210 
   3211       /* Rb should be equal/less than Re.  */
   3212       if (rb > re)
   3213 	as_bad ("The first operand (%s) should be equal to or smaller than "
   3214 		"second operand (%s).", argv[0], argv[1]);
   3215 
   3216       /* forbid using $fp|$gp|$lp|$sp in Rb or Re
   3217 		      r28 r29 r30 r31  */
   3218       if (rb >= 28)
   3219 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
   3220       if (re >= 28)
   3221 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
   3222     }
   3223   else
   3224     {
   3225       as_bad ("Invalid operands pattern !!");
   3226     }
   3227 
   3228   /* Build Enable4 mask.  */
   3229   /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
   3230      and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
   3231      which is also valid for code generation.  */
   3232   en4 = 0;
   3233   last_arg_index = argc - 1;
   3234   if (strstr (argv[last_arg_index], "$fp"))
   3235     en4 |= 8;
   3236   if (strstr (argv[last_arg_index], "$gp"))
   3237     en4 |= 4;
   3238   if (strstr (argv[last_arg_index], "$lp"))
   3239     en4 |= 2;
   3240   if (strstr (argv[last_arg_index], "$sp"))
   3241     en4 |= 1;
   3242 
   3243   md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
   3244 }
   3245 
   3246 static void
   3247 do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
   3248 		     unsigned int pv ATTRIBUTE_UNUSED)
   3249 {
   3250   char size = 'x';
   3251   /* If users omit push location, use $sp as default value.  */
   3252   char location[8] = "$sp";  /* 8 is enough for register name.  */
   3253 
   3254   switch (pv & 0x3)
   3255     {
   3256     case 0: size = 'b'; break;
   3257     case 1: size = 'h'; break;
   3258     case 2: size = 'w'; break;
   3259     case 3: size = 'w'; break;
   3260     }
   3261 
   3262   if (argc == 2)
   3263     {
   3264       strncpy (location, argv[1], sizeof (location) - 1);
   3265       location[sizeof (location) - 1] = '\0';
   3266     }
   3267 
   3268   md_assemblef ("l.%c $ta,%s", size, argv[0]);
   3269   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   3270 
   3271   if ((pv & 0x3) == 0x3) /* double-word */
   3272     {
   3273       md_assemblef ("l.w $ta,%s+4", argv[0]);
   3274       md_assemblef ("smw.adm $ta,[%s],$ta", location);
   3275     }
   3276 }
   3277 
   3278 static void
   3279 do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
   3280 		    unsigned int pv ATTRIBUTE_UNUSED)
   3281 {
   3282   char size = 'x';
   3283   /* If users omit pop location, use $sp as default value.  */
   3284   char location[8] = "$sp";  /* 8 is enough for register name.  */
   3285 
   3286   switch (pv & 0x3)
   3287     {
   3288     case 0: size = 'b'; break;
   3289     case 1: size = 'h'; break;
   3290     case 2: size = 'w'; break;
   3291     case 3: size = 'w'; break;
   3292     }
   3293 
   3294   if (argc == 3)
   3295     {
   3296       strncpy (location, argv[2], sizeof (location) - 1);
   3297       location[sizeof (location) - 1] = '\0';
   3298     }
   3299 
   3300   if ((pv & 0x3) == 0x3) /* double-word */
   3301     {
   3302       md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
   3303       md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
   3304     }
   3305 
   3306   md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
   3307   md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
   3308 }
   3309 
   3310 static void
   3311 do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[],
   3312 		 unsigned int pv ATTRIBUTE_UNUSED)
   3313 {
   3314   /* If users omit push location, use $sp as default value.  */
   3315   char location[8] = "$sp";  /* 8 is enough for register name.  */
   3316 
   3317   if (argc == 2)
   3318     {
   3319       strncpy (location, argv[1], sizeof (location) - 1);
   3320       location[sizeof (location) - 1] = '\0';
   3321     }
   3322 
   3323   md_assemblef ("la $ta,%s", argv[0]);
   3324   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   3325 }
   3326 
   3327 static void
   3328 do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
   3329 		 unsigned int pv ATTRIBUTE_UNUSED)
   3330 {
   3331   /* If users omit push location, use $sp as default value.  */
   3332   char location[8] = "$sp";  /* 8 is enough for register name.  */
   3333 
   3334   if (argc == 2)
   3335     {
   3336       strncpy (location, argv[1], sizeof (location) - 1);
   3337       location[sizeof (location) - 1] = '\0';
   3338     }
   3339 
   3340   md_assemblef ("li $ta,%s", argv[0]);
   3341   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   3342 }
   3343 
   3344 static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
   3345 {
   3346   {"b",      1, do_pseudo_b,      0, 0},
   3347   {"bal",    1, do_pseudo_bal,    0, 0},
   3348 
   3349   {"bge",    3, do_pseudo_bge,    0, 0},
   3350   {"bges",   3, do_pseudo_bges,   0, 0},
   3351 
   3352   {"bgt",    3, do_pseudo_bgt,    0, 0},
   3353   {"bgts",   3, do_pseudo_bgts,   0, 0},
   3354 
   3355   {"ble",    3, do_pseudo_ble,    0, 0},
   3356   {"bles",   3, do_pseudo_bles,   0, 0},
   3357 
   3358   {"blt",    3, do_pseudo_blt,    0, 0},
   3359   {"blts",   3, do_pseudo_blts,   0, 0},
   3360 
   3361   {"br",     1, do_pseudo_br,     0, 0},
   3362   {"bral",   1, do_pseudo_bral,   0, 0},
   3363 
   3364   {"call",   1, do_pseudo_bal,    0, 0},
   3365 
   3366   {"la",     2, do_pseudo_la, 0, 0},
   3367   {"li",     2, do_pseudo_li, 0, 0},
   3368 
   3369   {"l.b",    2, do_pseudo_ls_bhw, 0, 0},
   3370   {"l.h",    2, do_pseudo_ls_bhw, 1, 0},
   3371   {"l.w",    2, do_pseudo_ls_bhw, 2, 0},
   3372   {"l.bs",   2, do_pseudo_ls_bhw, 0 | 0x10, 0},
   3373   {"l.hs",   2, do_pseudo_ls_bhw, 1 | 0x10, 0},
   3374   {"s.b",    2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
   3375   {"s.h",    2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
   3376   {"s.w",    2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
   3377 
   3378   {"l.bp",   3, do_pseudo_ls_bhwp, 0, 0},
   3379   {"l.bpc",  3, do_pseudo_ls_bhwpc, 0, 0},
   3380   {"l.hp",   3, do_pseudo_ls_bhwp, 1, 0},
   3381   {"l.hpc",  3, do_pseudo_ls_bhwpc, 1, 0},
   3382   {"l.wp",   3, do_pseudo_ls_bhwp, 2, 0},
   3383   {"l.wpc",  3, do_pseudo_ls_bhwpc, 2, 0},
   3384   {"l.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
   3385   {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
   3386   {"l.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
   3387   {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
   3388   {"s.bp",   3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
   3389   {"s.bpc",   3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
   3390   {"s.hp",   3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
   3391   {"s.hpc",   3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
   3392   {"s.wp",   3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
   3393   {"s.wpc",   3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
   3394   {"s.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
   3395   {"s.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
   3396 
   3397   {"lbi.p",  3, do_pseudo_ls_bhwi, 0, 0},
   3398   {"lhi.p",  3, do_pseudo_ls_bhwi, 1, 0},
   3399   {"lwi.p",  3, do_pseudo_ls_bhwi, 2, 0},
   3400   {"sbi.p",  3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
   3401   {"shi.p",  3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
   3402   {"swi.p",  3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
   3403   {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
   3404   {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
   3405   {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
   3406 
   3407   {"move",   2, do_pseudo_move, 0, 0},
   3408   {"neg",    2, do_pseudo_neg,  0, 0},
   3409   {"not",    2, do_pseudo_not,  0, 0},
   3410 
   3411   {"pop",    2, do_pseudo_pushpop,   0, 0},
   3412   {"push",   2, do_pseudo_pushpop,   0, 0},
   3413   {"popm",   2, do_pseudo_pushpopm,  0, 0},
   3414   {"pushm",   3, do_pseudo_pushpopm, 0, 0},
   3415 
   3416   {"v3push", 2, do_pseudo_v3push, 0, 0},
   3417   {"v3pop",  2, do_pseudo_v3pop,  0, 0},
   3418 
   3419   /* Support pseudo instructions of pushing/poping registers into/from stack
   3420      push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
   3421      pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
   3422   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
   3423   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
   3424   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
   3425   { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
   3426   { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
   3427   { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
   3428   { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
   3429   { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
   3430   { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
   3431   { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
   3432   { "pusha", 2, do_pseudo_pusha, 0, 0 },
   3433   { "pushi", 2, do_pseudo_pushi, 0, 0 },
   3434 
   3435   {NULL, 0, NULL, 0, 0}
   3436 };
   3437 
   3438 static void
   3439 nds32_init_nds32_pseudo_opcodes (void)
   3440 {
   3441   struct nds32_pseudo_opcode *opcode;
   3442 
   3443   nds32_pseudo_opcode_hash = str_htab_create ();
   3444   for (opcode = nds32_pseudo_opcode_table; opcode->opcode; opcode++)
   3445     if (str_hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode, 0))
   3446       as_fatal (_("duplicate %s"), opcode->opcode);
   3447 }
   3448 
   3449 static struct nds32_pseudo_opcode *
   3450 nds32_lookup_pseudo_opcode (const char *str)
   3451 {
   3452   struct nds32_pseudo_opcode *result;
   3453   int i = 0;
   3454 
   3455   /* (*op) is the first word of current source line (*str)  */
   3456   int maxlen = strlen (str);
   3457   char *op = xmalloc (maxlen + 1);
   3458 
   3459   for (i = 0; i < maxlen; i++)
   3460     {
   3461       if (is_whitespace (op[i] = str[i]))
   3462 	break;
   3463     }
   3464   op[i] = '\0';
   3465 
   3466   result = str_hash_find (nds32_pseudo_opcode_hash, op);
   3467   free (op);
   3468   return result;
   3469 }
   3470 
   3471 static void
   3472 nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
   3473 {
   3474   int argc = 0;
   3475   char *argv[8] = {NULL};
   3476   char *s;
   3477   char *str = xstrdup (line);
   3478 
   3479   /* Parse arguments for opcode.  */
   3480   s = str + strlen (opcode->opcode);
   3481 
   3482   if (!s[0])
   3483     goto end;
   3484 
   3485   /* Dummy comma to ease separate arguments as below.  */
   3486   s[0] = ',';
   3487   do
   3488     {
   3489       if (s[0] == ',')
   3490 	{
   3491 	  if (argc >= opcode->argc
   3492 	      || (argc >= (int)ARRAY_SIZE (argv) - 1))
   3493 	    as_bad (_("Too many argument. `%s'"), line);
   3494 
   3495 	  argv[argc] = s + 1;
   3496 	  argc ++;
   3497 	  s[0] = '\0';
   3498 	}
   3499       ++s;
   3500     } while (s[0] != '\0');
   3501  end:
   3502   /* Put the origin line for debugging.  */
   3503   argv[argc] = line;
   3504   opcode->proc (argc, argv, opcode->pseudo_val);
   3505   free (str);
   3506 }
   3507 
   3508 /* This function will be invoked from function `nds32_after_parse_args'.
   3510    Thus, if the value of option has been set, keep the value the way it is.  */
   3511 
   3512 static int
   3513 nds32_parse_arch (const char *str)
   3514 {
   3515   static const struct nds32_arch
   3516   {
   3517     const char *name;
   3518     int baseline;
   3519     int reduced_reg;
   3520     int fpu_sp_ext;
   3521     int fpu_dp_ext;
   3522     int fpu_freg;
   3523     int abi;
   3524   } archs[] =
   3525   {
   3526     {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3527     {"v3j", ISA_V3,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3528     {"v3s", ISA_V3,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3529     {"v3f", ISA_V3,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3530     {"v3",  ISA_V3,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3531     {"v2j", ISA_V2,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3532     {"v2s", ISA_V2,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3533     {"v2f", ISA_V2,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3534     {"v2",  ISA_V2,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3535   };
   3536   size_t i;
   3537 
   3538   for (i = 0; i < ARRAY_SIZE (archs); i++)
   3539     {
   3540       if (strcmp (str, archs[i].name) != 0)
   3541 	continue;
   3542 
   3543       /* The value `-1' represents this option has *NOT* been set.  */
   3544       nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
   3545       nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
   3546       nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
   3547       nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
   3548       nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
   3549       nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
   3550 
   3551       return 1;
   3552     }
   3553 
   3554   /* Logic here rejects the input arch name.  */
   3555   as_bad (_("unknown arch name `%s'\n"), str);
   3556 
   3557   return 1;
   3558 }
   3559 
   3560 /* This function parses "baseline" specified.  */
   3561 
   3562 static int
   3563 nds32_parse_baseline (const char *str)
   3564 {
   3565   if (strcmp (str, "v3") == 0)
   3566     nds32_baseline = ISA_V3;
   3567   else if (strcmp (str, "v3m") == 0)
   3568     nds32_baseline = ISA_V3M;
   3569   else if (strcmp (str, "v2") == 0)
   3570     nds32_baseline = ISA_V2;
   3571   else
   3572     {
   3573       /* Logic here rejects the input baseline.  */
   3574       as_bad (_("unknown baseline `%s'\n"), str);
   3575       return 0;
   3576     }
   3577 
   3578   return 1;
   3579 }
   3580 
   3581 /* This function parses "fpu-freg" specified.  */
   3582 
   3583 static int
   3584 nds32_parse_freg (const char *str)
   3585 {
   3586   if (strcmp (str, "2") == 0)
   3587     nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
   3588   else if (strcmp (str, "3") == 0)
   3589     nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
   3590   else if (strcmp (str, "1") == 0)
   3591     nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
   3592   else if (strcmp (str, "0") == 0)
   3593     nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
   3594   else
   3595     {
   3596       /* Logic here rejects the input FPU configuration.  */
   3597       as_bad (_("unknown FPU configuration `%s'\n"), str);
   3598       return 0;
   3599     }
   3600 
   3601   return 1;
   3602 }
   3603 
   3604 /* This function parse "abi=" specified.  */
   3605 
   3606 static int
   3607 nds32_parse_abi (const char *str)
   3608 {
   3609   if (strcmp (str, "v2") == 0)
   3610     nds32_abi = E_NDS_ABI_AABI;
   3611   /* Obsolete.  */
   3612   else if (strcmp (str, "v2fp") == 0)
   3613     nds32_abi = E_NDS_ABI_V2FP;
   3614   else if (strcmp (str, "v1") == 0)
   3615     nds32_abi = E_NDS_ABI_V1;
   3616   else if (strcmp (str,"v2fpp") == 0)
   3617     nds32_abi = E_NDS_ABI_V2FP_PLUS;
   3618   else
   3619     {
   3620       /* Logic here rejects the input abi version.  */
   3621       as_bad (_("unknown ABI version`%s'\n"), str);
   3622       return 0;
   3623     }
   3624 
   3625   return 1;
   3626 }
   3627 
   3628 /* This function turn on all extensions and instructions support.  */
   3629 
   3630 static int
   3631 nds32_all_ext (void)
   3632 {
   3633   nds32_mac = 1;
   3634   nds32_div = 1;
   3635   nds32_dx_regs = 1;
   3636   nds32_16bit_ext = 1;
   3637   nds32_perf_ext = 1;
   3638   nds32_perf_ext2 = 1;
   3639   nds32_string_ext = 1;
   3640   nds32_audio_ext = 1;
   3641   nds32_fpu_fma = 1;
   3642   nds32_fpu_sp_ext = 1;
   3643   nds32_fpu_dp_ext = 1;
   3644   nds32_dsp_ext = 1;
   3645   nds32_zol_ext = 1;
   3646   /* Turn off reduced register.  */
   3647   nds32_gpr16 = 0;
   3648 
   3649   return 1;
   3650 }
   3651 
   3652 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
   3653    presumably indicating a special code value which appears in md_longopts.
   3654    This function should return non-zero if it handled the option and zero
   3655    otherwise.  There is no need to print a message about an option not being
   3656    recognized.  This will be handled by the generic code.  */
   3657 
   3658 int
   3659 nds32_parse_option (int c, const char *arg)
   3660 {
   3661   struct nds32_parse_option_table *coarse_tune;
   3662   struct nds32_set_option_table *fine_tune;
   3663   const char *ptr_arg = NULL;
   3664 
   3665   switch (c)
   3666     {
   3667     case OPTION_OPTIMIZE:
   3668       optimize = 1;
   3669       optimize_for_space = 0;
   3670       break;
   3671     case OPTION_OPTIMIZE_SPACE:
   3672       optimize = 0;
   3673       optimize_for_space = 1;
   3674       break;
   3675     case OPTION_BIG:
   3676       target_big_endian = 1;
   3677       break;
   3678     case OPTION_LITTLE:
   3679       target_big_endian = 0;
   3680       break;
   3681     case OPTION_TURBO:
   3682       nds32_all_ext ();
   3683       break;
   3684     case OPTION_PIC:
   3685       nds32_pic = 1;
   3686       break;
   3687     case OPTION_RELAX_FP_AS_GP_OFF:
   3688       nds32_relax_fp_as_gp = 0;
   3689       break;
   3690     case OPTION_RELAX_B2BB_ON:
   3691       nds32_relax_b2bb = 1;
   3692       break;
   3693     case OPTION_RELAX_ALL_OFF:
   3694       nds32_relax_all = 0;
   3695       break;
   3696     default:
   3697       /* Determination of which option table to search for to save time.  */
   3698       if (!arg)
   3699 	return 0;
   3700 
   3701       ptr_arg = strchr (arg, '=');
   3702 
   3703       if (ptr_arg)
   3704 	{
   3705 	  /* Find the value after '='.  */
   3706 	  if (ptr_arg != NULL)
   3707 	    ptr_arg++;
   3708 	  for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
   3709 	    {
   3710 	      if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
   3711 		{
   3712 		  coarse_tune->func (ptr_arg);
   3713 		  return 1;
   3714 		}
   3715 	    }
   3716 	}
   3717       else
   3718 	{
   3719 	  int disable = 0;
   3720 
   3721 	  /* Filter out the Disable option first.  */
   3722 	  if (startswith (arg, "no-"))
   3723 	    {
   3724 	      disable = 1;
   3725 	      arg += 3;
   3726 	    }
   3727 
   3728 	  for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
   3729 	    {
   3730 	      if (strcmp (arg, fine_tune->name) == 0)
   3731 		{
   3732 		  if (fine_tune->var != NULL)
   3733 		    *fine_tune->var = (disable) ? 0 : 1;
   3734 		  return 1;
   3735 		}
   3736 	    }
   3737 	}
   3738       /* Nothing match.  */
   3739       return 0;
   3740     }
   3741 
   3742   return 1;
   3743 }
   3744 
   3745 /* tc_check_label  */
   3746 
   3747 void
   3748 nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
   3749 {
   3750   /* The code used to create BB is move to frob_label.
   3751      They should go there.  */
   3752 }
   3753 
   3754 static void
   3755 set_endian_little (int on)
   3756 {
   3757   target_big_endian = !on;
   3758 }
   3759 
   3760 /* These functions toggles the generation of 16-bit.  First encounter signals
   3761    the beginning of not generating 16-bit instructions and next encounter
   3762    signals the restoring back to default behavior.  */
   3763 
   3764 static void
   3765 trigger_16bit (int trigger)
   3766 {
   3767   enable_16bit = trigger;
   3768 }
   3769 
   3770 static int backup_16bit_mode;
   3771 static void
   3772 restore_16bit (int no_use ATTRIBUTE_UNUSED)
   3773 {
   3774   enable_16bit = backup_16bit_mode;
   3775 }
   3776 
   3777 static void
   3778 off_16bit (int no_use ATTRIBUTE_UNUSED)
   3779 {
   3780   backup_16bit_mode = enable_16bit;
   3781   enable_16bit = 0;
   3782 }
   3783 
   3784 /* Built-in segments for small object.  */
   3785 typedef struct nds32_seg_entryT
   3786 {
   3787   segT s;
   3788   const char *name;
   3789   flagword flags;
   3790 } nds32_seg_entry;
   3791 
   3792 nds32_seg_entry nds32_seg_table[] =
   3793 {
   3794   {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3795 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3796   {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3797 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3798   {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3799 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3800   {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3801 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3802   {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3803 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3804   {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
   3805   {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
   3806   {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
   3807   {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
   3808   {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
   3809 };
   3810 
   3811 /* Indexes to nds32_seg_table[].  */
   3812 enum NDS32_SECTIONS_ENUM
   3813 {
   3814   SDATA_F_SECTION = 0,
   3815   SDATA_B_SECTION = 1,
   3816   SDATA_H_SECTION = 2,
   3817   SDATA_W_SECTION = 3,
   3818   SDATA_D_SECTION = 4,
   3819   SBSS_F_SECTION = 5,
   3820   SBSS_B_SECTION = 6,
   3821   SBSS_H_SECTION = 7,
   3822   SBSS_W_SECTION = 8,
   3823   SBSS_D_SECTION = 9
   3824 };
   3825 
   3826 /* The following code is borrowed from v850_seg.  Revise this is needed.  */
   3827 
   3828 static void
   3829 do_nds32_seg (int i, subsegT sub)
   3830 {
   3831   nds32_seg_entry *seg = nds32_seg_table + i;
   3832 
   3833   obj_elf_section_change_hook ();
   3834 
   3835   if (seg->s != NULL)
   3836     subseg_set (seg->s, sub);
   3837   else
   3838     {
   3839       seg->s = subseg_new (seg->name, sub);
   3840       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
   3841 	{
   3842 	  bfd_set_section_flags (seg->s, seg->flags);
   3843 	  if ((seg->flags & SEC_LOAD) == 0)
   3844 	    seg_info (seg->s)->bss = 1;
   3845 	}
   3846     }
   3847 }
   3848 
   3849 static void
   3850 nds32_seg (int i)
   3851 {
   3852   subsegT sub = get_absolute_expression ();
   3853 
   3854   do_nds32_seg (i, sub);
   3855   demand_empty_rest_of_line ();
   3856 }
   3857 
   3858 /* Set if label adjustment is needed.  I should not adjust .xbyte in dwarf.  */
   3859 static symbolS *nds32_last_label;	/* Last label for alignment.  */
   3860 
   3861 static void
   3862 add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align)
   3863 {
   3864   if ((shift > 1) && (addr & 1))
   3865     {
   3866       int n = (1 << shift) - 1;
   3867       if (!is_data_align)
   3868 	add_mapping_symbol (MAP_CODE, 1, 0);
   3869       else if ((int) (addr & n) != n)
   3870 	add_mapping_symbol (MAP_CODE, 1, 0);
   3871     }
   3872   else if ((shift > 1) && ((int) (addr & 1) == 0))
   3873     add_mapping_symbol (MAP_CODE, 0, 0);
   3874 }
   3875 
   3876 /* This code is referred from D30V for adjust label to be with pending
   3877    alignment.  For example,
   3878      LBYTE: .byte	0x12
   3879      LHALF: .half	0x12
   3880      LWORD: .word	0x12
   3881    Without this, the above label will not attach to incoming data.  */
   3882 
   3883 static void
   3884 nds32_adjust_label (int n)
   3885 {
   3886   /* FIXME: I think adjust label and alignment is
   3887      the programmer's obligation.  Sadly, VLSI team doesn't
   3888      properly use .align for their test cases.
   3889      So I re-implement cons_align and auto adjust labels, again.
   3890 
   3891      I think d30v's implementation is simple and good enough.  */
   3892 
   3893   symbolS *label = nds32_last_label;
   3894   nds32_last_label = NULL;
   3895 
   3896   /* SEC_ALLOC is used to eliminate .debug_ sections.
   3897      SEC_CODE is used to include section for ILM.  */
   3898   if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
   3899       || strcmp (now_seg->name, ".eh_frame") == 0
   3900       || strcmp (now_seg->name, ".gcc_except_table") == 0)
   3901     return;
   3902 
   3903   /* Only frag by alignment when needed.
   3904      Otherwise, it will fail to optimize labels on 4-byte boundary.  (bug8454)
   3905      See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details.  */
   3906   if (frag_now_fix () & (((addressT) 1 << n) - 1))
   3907     {
   3908       if (subseg_text_p (now_seg))
   3909 	{
   3910 	  add_mapping_symbol_for_align (n, frag_now_fix (), 1);
   3911 	  frag_align_code (n, 0);
   3912 	}
   3913       else
   3914 	frag_align (n, 0, 0);
   3915 
   3916       /* Record the minimum alignment for this segment.  */
   3917       record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
   3918     }
   3919 
   3920   if (label != NULL)
   3921     {
   3922       symbolS *sym;
   3923       int label_seen = false;
   3924       struct frag *old_frag;
   3925       valueT old_value, new_value;
   3926 
   3927       gas_assert (S_GET_SEGMENT (label) == now_seg);
   3928 
   3929       old_frag  = symbol_get_frag (label);
   3930       old_value = S_GET_VALUE (label);
   3931       new_value = frag_now_fix ();
   3932 
   3933       /* Multiple labels may be on the same address.  And the last symbol
   3934 	 may not be a label at all, e.g., register name, external function names,
   3935 	 so I have to track the last label in tc_frob_label instead of
   3936 	 just using symbol_lastP.  */
   3937       for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
   3938 	{
   3939 	  if (symbol_get_frag (sym) == old_frag
   3940 	      && S_GET_VALUE (sym) == old_value)
   3941 	    {
   3942 	      /* Warning HERE! */
   3943 	      label_seen = true;
   3944 	      symbol_set_frag (sym, frag_now);
   3945 	      S_SET_VALUE (sym, new_value);
   3946 	    }
   3947 	  else if (label_seen && symbol_get_frag (sym) != old_frag)
   3948 	    break;
   3949 	}
   3950     }
   3951 }
   3952 
   3953 void
   3954 nds32_cons_align (int size ATTRIBUTE_UNUSED)
   3955 {
   3956   /* Do nothing here.
   3957      This is called before `md_flush_pending_output' is called by `cons'.
   3958 
   3959      There are two things should be done for auto-adjust-label.
   3960      1. Align data/instructions and adjust label to be attached to them.
   3961      2. Clear auto-adjust state, so incoming data/instructions will not
   3962 	adjust the label.
   3963 
   3964      For example,
   3965 	  .byte 0x1
   3966 	.L0:
   3967 	  .word 0x2
   3968 	  .word 0x3
   3969      in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
   3970 
   3971      I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
   3972      but it is also called by `cons' before this function.
   3973      To simplify the code, instead of overriding .zero, .fill, .space, etc,
   3974      I think we should just adjust label in `nds32_aligned_X_cons' instead of here.  */
   3975 }
   3976 
   3977 static void
   3978 make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align)
   3979 {
   3980   symbolS *symbol_p = NULL;
   3981   const char *symbol_name = NULL;
   3982   switch (state)
   3983     {
   3984     case MAP_DATA:
   3985       if (align == 0)
   3986 	symbol_name = "$d0";
   3987       else if (align == 1)
   3988 	symbol_name = "$d1";
   3989       else if (align == 2)
   3990 	symbol_name = "$d2";
   3991       else if (align == 3)
   3992 	symbol_name = "$d3";
   3993       else if (align == 4)
   3994 	symbol_name = "$d4";
   3995       break;
   3996     case MAP_CODE:
   3997       symbol_name = "$c";
   3998       break;
   3999     default:
   4000       abort ();
   4001     }
   4002 
   4003   symbol_p = symbol_new (symbol_name, now_seg, frag, value);
   4004   /* local scope attribute  */
   4005   symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL;
   4006 }
   4007 
   4008 static void
   4009 add_mapping_symbol (enum mstate state, unsigned int padding_byte,
   4010 		    unsigned int align)
   4011 {
   4012   enum mstate current_mapping_state =
   4013     seg_info (now_seg)->tc_segment_info_data.mapstate;
   4014 
   4015   if (state == MAP_CODE
   4016       && current_mapping_state == state)
   4017     return;
   4018 
   4019   if (!SEG_NORMAL (now_seg)
   4020       || !subseg_text_p (now_seg))
   4021     return;
   4022 
   4023   /* start adding mapping symbol  */
   4024   seg_info (now_seg)->tc_segment_info_data.mapstate = state;
   4025   make_mapping_symbol (state, frag_now_fix () + padding_byte,
   4026 		       frag_now, align);
   4027 }
   4028 
   4029 static void
   4030 nds32_aligned_cons (int idx)
   4031 {
   4032   nds32_adjust_label (idx);
   4033   add_mapping_symbol (MAP_DATA, 0, idx);
   4034   /* Call default handler.  */
   4035   cons (1 << idx);
   4036   if (now_seg->flags & SEC_CODE
   4037       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
   4038     {
   4039       /* Use BFD_RELOC_NDS32_DATA to avoid linker
   4040 	 optimization replacing data.  */
   4041       expressionS exp;
   4042 
   4043       exp.X_add_number = 0;
   4044       exp.X_op = O_constant;
   4045       fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
   4046 		   &exp, 0, BFD_RELOC_NDS32_DATA);
   4047     }
   4048 }
   4049 
   4050 /* `.double' directive.  */
   4051 
   4052 static void
   4053 nds32_aligned_float_cons (int type)
   4054 {
   4055   switch (type)
   4056     {
   4057     case 'f':
   4058     case 'F':
   4059     case 's':
   4060     case 'S':
   4061       nds32_adjust_label (2);
   4062       break;
   4063     case 'd':
   4064     case 'D':
   4065     case 'r':
   4066     case 'R':
   4067       nds32_adjust_label (4);
   4068       break;
   4069     default:
   4070       as_bad ("Unrecognized float type, %c\n", (char)type);
   4071     }
   4072   /* Call default handler.  */
   4073   float_cons (type);
   4074 }
   4075 
   4076 static void
   4077 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
   4078 {
   4079   /* Another way to do -mpic.
   4080      This is for GCC internal use and should always be first line
   4081      of code, otherwise, the effect is not determined.  */
   4082   nds32_pic = 1;
   4083 }
   4084 
   4085 static void
   4086 nds32_set_abi (int ver)
   4087 {
   4088   nds32_abi = ver;
   4089 }
   4090 
   4091 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value.  */
   4092 
   4093 static void
   4094 nds32_relax_relocs (int relax)
   4095 {
   4096   char saved_char;
   4097   char *name;
   4098   int i;
   4099   const char *subtype_relax[] =
   4100     {"", "",};
   4101 
   4102   name = input_line_pointer;
   4103   while (*input_line_pointer && !is_whitespace (*input_line_pointer))
   4104     input_line_pointer++;
   4105   saved_char = *input_line_pointer;
   4106   *input_line_pointer = 0;
   4107 
   4108   for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
   4109     {
   4110       if (strcmp (name, subtype_relax[i]) == 0)
   4111 	{
   4112 	  switch (i)
   4113 	    {
   4114 	    case 0:
   4115 	    case 1:
   4116 	      enable_relax_relocs = relax & enable_relax_relocs;
   4117 	      break;
   4118 	    default:
   4119 	      break;
   4120 	    }
   4121 	  break;
   4122 	}
   4123     }
   4124   *input_line_pointer = saved_char;
   4125   ignore_rest_of_line ();
   4126 }
   4127 
   4128 /* Record which arguments register($r0 ~ $r5) is not used in callee.
   4129    bit[i] for $ri  */
   4130 
   4131 static void
   4132 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
   4133 {
   4134   ignore_rest_of_line ();
   4135 }
   4136 
   4137 /* Insert relocations to mark the begin and end of a fp-omitted function,
   4138    for further relaxation use.
   4139    bit[i] for $ri  */
   4140 
   4141 static void
   4142 nds32_omit_fp_begin (int mode)
   4143 {
   4144   expressionS exp;
   4145 
   4146   if (nds32_relax_fp_as_gp == 0)
   4147     return;
   4148   exp.X_op = O_symbol;
   4149   exp.X_add_symbol = abs_section_sym;
   4150   if (mode == 1)
   4151     {
   4152       in_omit_fp = 1;
   4153       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
   4154       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   4155 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
   4156     }
   4157   else
   4158     {
   4159       in_omit_fp = 0;
   4160       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
   4161       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   4162 		   BFD_RELOC_NDS32_RELAX_REGION_END);
   4163     }
   4164 }
   4165 
   4166 static void
   4167 nds32_loop_begin (int mode)
   4168 {
   4169   /* Insert loop region relocation here.  */
   4170   expressionS exp;
   4171 
   4172   exp.X_op = O_symbol;
   4173   exp.X_add_symbol = abs_section_sym;
   4174   if (mode == 1)
   4175     {
   4176       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
   4177       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   4178 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
   4179     }
   4180   else
   4181     {
   4182       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
   4183       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   4184 		   BFD_RELOC_NDS32_RELAX_REGION_END);
   4185     }
   4186 }
   4187 
   4188 struct nds32_relocs_group
   4189 {
   4190   struct nds32_relocs_pattern *pattern;
   4191   struct nds32_relocs_group *next;
   4192 };
   4193 
   4194 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
   4195 /* Used to reorder the id for ".relax_hint id".  */
   4196 static int relax_hint_bias = 0;
   4197 /* Record current relax hint id.  */
   4198 static int relax_hint_id_current = -1;
   4199 int reset_bias = 0;
   4200 /* If ".relax_hint begin" is triggered?  */
   4201 int relax_hint_begin = 0;
   4202 
   4203 /* Record the reordered relax hint id.  */
   4204 
   4205 struct relax_hint_id
   4206 {
   4207   int old_id;
   4208   int new_id;
   4209   struct relax_hint_id *next;
   4210 };
   4211 
   4212 /* FIXME: Need to find somewhere to free the list.  */
   4213 struct relax_hint_id *record_id_head = NULL;
   4214 
   4215 /* Is the buffer large enough?  */
   4216 #define MAX_BUFFER 12
   4217 
   4218 static char *
   4219 nds_itoa (int n)
   4220 {
   4221   char *buf = xmalloc (MAX_BUFFER * sizeof (char));
   4222   snprintf (buf, MAX_BUFFER, "%d", n);
   4223   return buf;
   4224 }
   4225 
   4226 /* Insert a relax hint.  */
   4227 
   4228 static void
   4229 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   4230 {
   4231   char *name = NULL;
   4232   char saved_char;
   4233   struct nds32_relocs_pattern *relocs = NULL;
   4234   struct nds32_relocs_group *group, *new;
   4235   struct relax_hint_id *record_id;
   4236 
   4237   name = input_line_pointer;
   4238   while (*input_line_pointer && !is_whitespace (*input_line_pointer))
   4239     input_line_pointer++;
   4240   saved_char = *input_line_pointer;
   4241   *input_line_pointer = 0;
   4242   name = strdup (name);
   4243 
   4244   if (name && strcmp (name, "begin") == 0)
   4245     {
   4246       if (relax_hint_id_current == -1)
   4247 	reset_bias = 1;
   4248       relax_hint_bias++;
   4249       relax_hint_id_current++;
   4250       relax_hint_begin = 1;
   4251     }
   4252 
   4253   /* Original case ".relax_hint id".  It's id may need to be reordered. */
   4254   if (!relax_hint_begin)
   4255     {
   4256       int tmp = strtol (name, NULL, 10);
   4257       record_id = record_id_head;
   4258       while (record_id)
   4259 	{
   4260 	  if (record_id->old_id == tmp)
   4261 	    {
   4262 	      name = nds_itoa (record_id->new_id);
   4263 	      goto reordered_id;
   4264 	    }
   4265 	  record_id = record_id->next;
   4266 	}
   4267       if (reset_bias)
   4268 	{
   4269 	  relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
   4270 	  reset_bias = 0;
   4271 	}
   4272       relax_hint_id_current = tmp + relax_hint_bias;
   4273 
   4274       /* Insert the element to the head of the link list.  */
   4275       struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
   4276       tmp_id->old_id = tmp;
   4277       tmp_id->new_id = relax_hint_id_current;
   4278       tmp_id->next = record_id_head;
   4279       record_id_head = tmp_id;
   4280     }
   4281 
   4282   if (name && strcmp (name, "end") == 0)
   4283     relax_hint_begin = 0;
   4284   name = nds_itoa (relax_hint_id_current);
   4285 
   4286  reordered_id:
   4287 
   4288   /* Find relax hint entry for next instruction, and all member will be
   4289      initialized at that time.  */
   4290   relocs = str_hash_find (nds32_hint_hash, name);
   4291   if (relocs == NULL)
   4292     {
   4293       relocs = notes_calloc (1, sizeof (*relocs));
   4294       str_hash_insert (nds32_hint_hash, name, relocs, 0);
   4295     }
   4296   else
   4297     {
   4298       while (relocs->next)
   4299 	relocs = relocs->next;
   4300       relocs->next = notes_calloc (1, sizeof (*relocs));
   4301       relocs = relocs->next;
   4302     }
   4303 
   4304   *input_line_pointer = saved_char;
   4305   ignore_rest_of_line ();
   4306 
   4307   /* Get the final one of relax hint series.  */
   4308 
   4309   /* It has to build this list because there are maybe more than one
   4310      instructions relative to the same instruction.  It to connect to
   4311      next instruction after md_assemble.  */
   4312   new = XNEW (struct nds32_relocs_group);
   4313   memset (new, 0, sizeof (struct nds32_relocs_group));
   4314   new->pattern = relocs;
   4315   new->next = NULL;
   4316   group = nds32_relax_hint_current;
   4317   if (!group)
   4318     nds32_relax_hint_current = new;
   4319   else
   4320     {
   4321       while (group->next != NULL)
   4322 	group = group->next;
   4323       group->next = new;
   4324     }
   4325   relaxing = true;
   4326 }
   4327 
   4328 /* Decide the size of vector entries, only accepts 4 or 16 now.  */
   4329 
   4330 static void
   4331 nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
   4332 {
   4333   expressionS exp;
   4334 
   4335   expression (&exp);
   4336 
   4337   if (exp.X_op == O_constant)
   4338     {
   4339       if (exp.X_add_number == 4 || exp.X_add_number == 16)
   4340 	{
   4341 	  if (vec_size == 0)
   4342 	    vec_size = exp.X_add_number;
   4343 	  else if (vec_size != exp.X_add_number)
   4344 	    as_warn (_("Different arguments of .vec_size are found, "
   4345 		       "previous %d, current %d"),
   4346 		     (int) vec_size, (int) exp.X_add_number);
   4347 	}
   4348       else
   4349 	as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
   4350 		 (int) exp.X_add_number);
   4351     }
   4352   else
   4353     as_warn (_("Argument of .vec_size is not a constant."));
   4354 }
   4355 
   4356 /* The behavior of ".flag" directive varies depending on the target.
   4357    In nds32 target, we use it to recognize whether this assembly content is
   4358    generated by compiler.  Other features can also be added in this function
   4359    in the future.  */
   4360 
   4361 static void
   4362 nds32_flag (int ignore ATTRIBUTE_UNUSED)
   4363 {
   4364   char *name;
   4365   char saved_char;
   4366   int i;
   4367   const char *possible_flags[] = { "verbatim" };
   4368 
   4369   /* Skip whitespaces.  */
   4370   name = input_line_pointer;
   4371   while (*input_line_pointer && !is_whitespace (*input_line_pointer))
   4372     input_line_pointer++;
   4373   saved_char = *input_line_pointer;
   4374   *input_line_pointer = 0;
   4375 
   4376   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
   4377     {
   4378       if (strcmp (name, possible_flags[i]) == 0)
   4379 	{
   4380 	  switch (i)
   4381 	    {
   4382 	    case 0:
   4383 	      /* flag: verbatim */
   4384 	      verbatim = 1;
   4385 	      break;
   4386 	    default:
   4387 	      break;
   4388 	    }
   4389 	  /* Already found the flag, no need to continue next loop.   */
   4390 	  break;
   4391 	}
   4392     }
   4393 
   4394   *input_line_pointer = saved_char;
   4395   ignore_rest_of_line ();
   4396 }
   4397 
   4398 static void
   4399 ict_model (int ignore ATTRIBUTE_UNUSED)
   4400 {
   4401   char *name;
   4402   char saved_char;
   4403   int i;
   4404   const char *possible_flags[] = { "small", "large" };
   4405 
   4406   /* Skip whitespaces.  */
   4407   name = input_line_pointer;
   4408   while (*input_line_pointer && !is_whitespace (*input_line_pointer))
   4409     input_line_pointer++;
   4410   saved_char = *input_line_pointer;
   4411   *input_line_pointer = 0;
   4412 
   4413   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
   4414     {
   4415       if (strcmp (name, possible_flags[i]) == 0)
   4416 	{
   4417 	  switch (i)
   4418 	    {
   4419 	    case 0:
   4420 	      /* flag: verbatim  */
   4421 	      ict_flag = ICT_SMALL;
   4422 	      break;
   4423 	    case 1:
   4424 	      ict_flag = ICT_LARGE;
   4425 	      break;
   4426 	    default:
   4427 	      break;
   4428 	    }
   4429 	  /* Already found the flag, no need to continue next loop.   */
   4430 	  break;
   4431 	}
   4432     }
   4433 
   4434   *input_line_pointer = saved_char;
   4435   ignore_rest_of_line ();
   4436 }
   4437 
   4438 static void
   4439 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
   4440 {
   4441   /* N1213HC core is used.  */
   4442 }
   4443 
   4444 
   4445 /* The target specific pseudo-ops which we support.  */
   4446 const pseudo_typeS md_pseudo_table[] =
   4447 {
   4448   /* Forced alignment if declared these ways.  */
   4449   {"ascii", stringer, 8 + 0},
   4450   {"asciz", stringer, 8 + 1},
   4451   {"double", nds32_aligned_float_cons, 'd'},
   4452   {"dword", nds32_aligned_cons, 3},
   4453   {"float", nds32_aligned_float_cons, 'f'},
   4454   {"half", nds32_aligned_cons, 1},
   4455   {"hword", nds32_aligned_cons, 1},
   4456   {"int", nds32_aligned_cons, 2},
   4457   {"long", nds32_aligned_cons, 2},
   4458   {"octa", nds32_aligned_cons, 4},
   4459   {"quad", nds32_aligned_cons, 3},
   4460   {"qword", nds32_aligned_cons, 4},
   4461   {"short", nds32_aligned_cons, 1},
   4462   {"byte", nds32_aligned_cons, 0},
   4463   {"single", nds32_aligned_float_cons, 'f'},
   4464   {"string", stringer, 8 + 1},
   4465   {"word", nds32_aligned_cons, 2},
   4466 
   4467   {"little", set_endian_little, 1},
   4468   {"big", set_endian_little, 0},
   4469   {"16bit_on", trigger_16bit, 1},
   4470   {"16bit_off", trigger_16bit, 0},
   4471   {"restore_16bit", restore_16bit, 0},
   4472   {"off_16bit", off_16bit, 0},
   4473 
   4474   {"sdata_d", nds32_seg, SDATA_D_SECTION},
   4475   {"sdata_w", nds32_seg, SDATA_W_SECTION},
   4476   {"sdata_h", nds32_seg, SDATA_H_SECTION},
   4477   {"sdata_b", nds32_seg, SDATA_B_SECTION},
   4478   {"sdata_f", nds32_seg, SDATA_F_SECTION},
   4479 
   4480   {"sbss_d", nds32_seg, SBSS_D_SECTION},
   4481   {"sbss_w", nds32_seg, SBSS_W_SECTION},
   4482   {"sbss_h", nds32_seg, SBSS_H_SECTION},
   4483   {"sbss_b", nds32_seg, SBSS_B_SECTION},
   4484   {"sbss_f", nds32_seg, SBSS_F_SECTION},
   4485 
   4486   {"pic", nds32_enable_pic, 0},
   4487   {"n12_hc", nds32_n12hc, 0},
   4488   {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
   4489   {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
   4490   /* Obsolete.  */
   4491   {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
   4492   {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
   4493   {"relax", nds32_relax_relocs, 1},
   4494   {"no_relax", nds32_relax_relocs, 0},
   4495   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   4496   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   4497   {"omit_fp_end", nds32_omit_fp_begin, 0},
   4498   {"vec_size", nds32_vec_size, 0},
   4499   {"flag", nds32_flag, 0},
   4500   {"innermost_loop_begin", nds32_loop_begin, 1},
   4501   {"innermost_loop_end", nds32_loop_begin, 0},
   4502   {"relax_hint", nds32_relax_hint, 0},
   4503   {"ict_model", ict_model, 0},
   4504   {NULL, NULL, 0}
   4505 };
   4506 
   4507 void
   4508 nds32_pre_do_align (int n, char *fill, int len, int max)
   4509 {
   4510   /* Only make a frag if we HAVE to...  */
   4511   fragS *fragP;
   4512   if (n != 0 && !need_pass_2)
   4513     {
   4514       if (fill == NULL)
   4515 	{
   4516 	  if (subseg_text_p (now_seg))
   4517 	    {
   4518 	      dwarf2_emit_insn (0);
   4519 	      fragP = frag_now;
   4520 	      add_mapping_symbol_for_align (n, frag_now_fix (), 0);
   4521 	      frag_align_code (n, max);
   4522 
   4523 	      /* Tag this alignment when there is a label before it.  */
   4524 	      if (label_exist)
   4525 		{
   4526 		  fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   4527 		  label_exist = 0;
   4528 		}
   4529 	    }
   4530 	  else
   4531 	    frag_align (n, 0, max);
   4532 	}
   4533       else if (len <= 1)
   4534 	frag_align (n, *fill, max);
   4535       else
   4536 	frag_align_pattern (n, fill, len, max);
   4537     }
   4538 }
   4539 
   4540 void
   4541 nds32_do_align (int n)
   4542 {
   4543   /* Optimize for space and label exists.  */
   4544   expressionS exp;
   4545 
   4546   /* FIXME:I think this will break debug info sections and except_table.  */
   4547   if (!enable_relax_relocs || !subseg_text_p (now_seg))
   4548     return;
   4549 
   4550   /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
   4551      the size of instruction may not be correct because
   4552      it could be relaxable.  */
   4553   exp.X_op = O_symbol;
   4554   exp.X_add_symbol = section_symbol (now_seg);
   4555   exp.X_add_number = n;
   4556   fix_new_exp (frag_now,
   4557 	       frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
   4558 }
   4559 
   4560 /* Supported Andes machines.  */
   4561 struct nds32_machs
   4562 {
   4563   enum bfd_architecture bfd_mach;
   4564   int mach_flags;
   4565 };
   4566 
   4567 /* This is the callback for nds32-asm.c to parse operands.  */
   4568 
   4569 int
   4570 nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
   4571 			 struct nds32_asm_insn *pinsn,
   4572 			 char **pstr, int64_t *value)
   4573 {
   4574   char *hold;
   4575   expressionS *pexp = pinsn->info;
   4576 
   4577   hold = input_line_pointer;
   4578   input_line_pointer = *pstr;
   4579   expression (pexp);
   4580   resolve_register (pexp);
   4581   *pstr = input_line_pointer;
   4582   input_line_pointer = hold;
   4583 
   4584   switch (pexp->X_op)
   4585     {
   4586     case O_symbol:
   4587       *value = 0;
   4588       return NASM_R_SYMBOL;
   4589     case O_constant:
   4590       *value = pexp->X_add_number;
   4591       return NASM_R_CONST;
   4592     case O_illegal:
   4593     case O_absent:
   4594     case O_register:
   4595     default:
   4596       return NASM_R_ILLEGAL;
   4597     }
   4598 }
   4599 
   4600 /* GAS will call this function at the start of the assembly, after the command
   4601    line arguments have been parsed and all the machine independent
   4602    initializations have been completed.  */
   4603 
   4604 void
   4605 md_begin (void)
   4606 {
   4607   const struct nds32_keyword *k;
   4608   relax_info_t *relax_info;
   4609   int flags = 0;
   4610 
   4611   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
   4612 
   4613   nds32_init_nds32_pseudo_opcodes ();
   4614   asm_desc.parse_operand = nds32_asm_parse_operand;
   4615   if (nds32_gpr16)
   4616     flags |= NASM_OPEN_REDUCED_REG;
   4617   nds32_asm_init (&asm_desc, flags);
   4618 
   4619   /* Initial general purpose registers hash table.  */
   4620   nds32_gprs_hash = str_htab_create ();
   4621   for (k = nds32_keyword_gpr; k->name; k++)
   4622     str_hash_insert (nds32_gprs_hash, k->name, k, 0);
   4623 
   4624   /* Initial branch hash table.  */
   4625   nds32_relax_info_hash = str_htab_create ();
   4626   for (relax_info = relax_table; relax_info->opcode; relax_info++)
   4627     str_hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info, 0);
   4628 
   4629   /* Initial relax hint hash table.  */
   4630   nds32_hint_hash = str_htab_create ();
   4631   enable_16bit = nds32_16bit_ext;
   4632 }
   4633 
   4634 /* HANDLE_ALIGN in write.c.  */
   4635 
   4636 void
   4637 nds32_handle_align (fragS *fragp)
   4638 {
   4639   static const unsigned char nop16[] = { 0x92, 0x00 };
   4640   static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
   4641 
   4642   if (fragp->fr_type != rs_align_code)
   4643     return;
   4644 
   4645   int bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4646   char *p = fragp->fr_literal + fragp->fr_fix;
   4647   int fix = bytes & 1;
   4648 
   4649   if (fix != 0)
   4650     {
   4651       *p++ = 0;
   4652       bytes--;
   4653     }
   4654 
   4655   if (bytes & 2)
   4656     {
   4657       expressionS exp_t;
   4658       exp_t.X_op = O_symbol;
   4659       exp_t.X_add_symbol = abs_section_sym;
   4660       exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
   4661       fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
   4662 		   BFD_RELOC_NDS32_INSN16);
   4663       memcpy (p, nop16, 2);
   4664       p += 2;
   4665       bytes -= 2;
   4666       fix += 2;
   4667     }
   4668   fragp->fr_fix += fix;
   4669 
   4670   if (bytes != 0)
   4671     {
   4672       fragp->fr_var = 4;
   4673       memcpy (p, nop32, 4);
   4674     }
   4675 }
   4676 
   4677 /* md_flush_pending_output  */
   4678 
   4679 void
   4680 nds32_flush_pending_output (void)
   4681 {
   4682   nds32_last_label = NULL;
   4683 }
   4684 
   4685 void
   4686 nds32_frob_label (symbolS *label)
   4687 {
   4688   dwarf2_emit_label (label);
   4689 }
   4690 
   4691 /* TC_START_LABEL  */
   4692 
   4693 int
   4694 nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
   4695 {
   4696   if (optimize && subseg_text_p (now_seg))
   4697     label_exist = 1;
   4698   return 1;
   4699 }
   4700 
   4701 /* TARGET_FORMAT  */
   4702 
   4703 const char *
   4704 nds32_target_format (void)
   4705 {
   4706 #ifdef TE_LINUX
   4707   if (target_big_endian)
   4708     return "elf32-nds32be-linux";
   4709   else
   4710     return "elf32-nds32le-linux";
   4711 #else
   4712   if (target_big_endian)
   4713     return "elf32-nds32be";
   4714   else
   4715     return "elf32-nds32le";
   4716 #endif
   4717 }
   4718 
   4719 static enum nds32_br_range
   4720 get_range_type (const struct nds32_field *field)
   4721 {
   4722   gas_assert (field != NULL);
   4723 
   4724   if (field->bitpos != 0)
   4725     return BR_RANGE_U4G;
   4726 
   4727   if (field->bitsize == 24 && field->shift == 1)
   4728     return BR_RANGE_S16M;
   4729   else if (field->bitsize == 16 && field->shift == 1)
   4730     return BR_RANGE_S64K;
   4731   else if (field->bitsize == 14 && field->shift == 1)
   4732     return BR_RANGE_S16K;
   4733   else if (field->bitsize == 8 && field->shift == 1)
   4734     return BR_RANGE_S256;
   4735   else
   4736     return BR_RANGE_U4G;
   4737 }
   4738 
   4739 /* Save pseudo instruction relocation list.  */
   4740 
   4741 static struct nds32_relocs_pattern*
   4742 nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
   4743 			       char *out, symbolS *sym,
   4744 			       struct nds32_relocs_pattern *reloc_ptr,
   4745 			       fragS *fragP)
   4746 {
   4747   struct nds32_opcode *opcode = insn->opcode;
   4748   if (!reloc_ptr)
   4749     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   4750   reloc_ptr->seg = now_seg;
   4751   reloc_ptr->sym = sym;
   4752   reloc_ptr->frag = fragP;
   4753   reloc_ptr->frchain = frchain_now;
   4754   reloc_ptr->fixP = fixP;
   4755   reloc_ptr->opcode = opcode;
   4756   reloc_ptr->where = out;
   4757   reloc_ptr->insn = insn->insn;
   4758   reloc_ptr->next = NULL;
   4759   return reloc_ptr;
   4760 }
   4761 
   4762 /* Check X_md to transform relocation.  */
   4763 
   4764 static fixS*
   4765 nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
   4766 			    const struct nds32_field *fld,
   4767 			    expressionS *pexp, char* out,
   4768 			    struct nds32_asm_insn *insn)
   4769 {
   4770   int reloc = -1;
   4771   expressionS exp;
   4772   fixS *fixP = NULL;
   4773 
   4774   /* Handle instruction relocation.  */
   4775   if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
   4776     {
   4777       /* Relocation for hi20 modifier.  */
   4778       switch (pexp->X_md)
   4779 	{
   4780 	case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4781 	  reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
   4782 	  break;
   4783 	case BFD_RELOC_NDS32_GOT20:	/* @GOT */
   4784 	  reloc = BFD_RELOC_NDS32_GOT_HI20;
   4785 	  break;
   4786 	case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4787 	  if (!nds32_pic)
   4788 	    as_bad (_("Invalid PIC expression."));
   4789 	  else
   4790 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
   4791 	  break;
   4792 	case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4793 	  reloc = BFD_RELOC_NDS32_GOTPC_HI20;
   4794 	  break;
   4795 	case BFD_RELOC_NDS32_TPOFF:	/* @TPOFF */
   4796 	  reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
   4797 	  break;
   4798 	case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4799 	  reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
   4800 	  break;
   4801 	case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
   4802 	  reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
   4803 	  break;
   4804 	default:	/* No suffix */
   4805 	  if (nds32_pic)
   4806 	    /* When the file is pic, the address must be offset to gp.
   4807 	       It may define another relocation or use GOTOFF.  */
   4808 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
   4809 	  else
   4810 	    reloc = BFD_RELOC_NDS32_HI20;
   4811 	  break;
   4812 	}
   4813       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4814 			  insn->info, 0 /* pcrel */, reloc);
   4815     }
   4816   else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
   4817     {
   4818       /* Relocation for lo12 modifier.  */
   4819       if (fld->bitsize == 15 && fld->shift == 0)
   4820 	{
   4821 	  /* [ls]bi || ori */
   4822 	  switch (pexp->X_md)
   4823 	    {
   4824 	    case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4825 	      reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
   4826 	      break;
   4827 	    case BFD_RELOC_NDS32_GOT20:		/* @GOT */
   4828 	      reloc = BFD_RELOC_NDS32_GOT_LO12;
   4829 	      break;
   4830 	    case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4831 	      if (!nds32_pic)
   4832 		as_bad (_("Invalid PIC expression."));
   4833 	      else
   4834 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
   4835 	      break;
   4836 	    case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4837 	      reloc = BFD_RELOC_NDS32_GOTPC_LO12;
   4838 	      break;
   4839 	    case BFD_RELOC_NDS32_TPOFF:		/* @TPOFF */
   4840 	      reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
   4841 	      break;
   4842 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4843 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
   4844 	      break;
   4845 	    case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
   4846 	      reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
   4847 	      break;
   4848 	    default:	/* No suffix */
   4849 	      if (nds32_pic)
   4850 		/* When the file is pic, the address must be offset to gp.
   4851 		   It may define another relocation or use GOTOFF.  */
   4852 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
   4853 	      else
   4854 		reloc = BFD_RELOC_NDS32_LO12S0;
   4855 	      break;
   4856 	    }
   4857 	}
   4858       else if (fld->bitsize == 15 && fld->shift == 1)
   4859 	reloc = BFD_RELOC_NDS32_LO12S1;		/* [ls]hi */
   4860       else if (fld->bitsize == 15 && fld->shift == 2)
   4861 	{
   4862 	  /* [ls]wi */
   4863 	  switch (pexp->X_md)
   4864 	    {
   4865 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4866 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
   4867 	      break;
   4868 	    default:	/* No suffix */
   4869 	      reloc = BFD_RELOC_NDS32_LO12S2;
   4870 	      break;
   4871 	    }
   4872 	}
   4873       else if (fld->bitsize == 15 && fld->shift == 3)
   4874 	reloc = BFD_RELOC_NDS32_LO12S3;		/* [ls]di */
   4875       else if (fld->bitsize == 12 && fld->shift == 2)
   4876 	reloc = BFD_RELOC_NDS32_LO12S2_SP;	/* f[ls][sd]i */
   4877 
   4878       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4879 			  insn->info, 0 /* pcrel */, reloc);
   4880     }
   4881   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4882 	   && (insn->attr & NASM_ATTR_PCREL))
   4883     {
   4884       /* Relocation for 32-bit branch instructions.  */
   4885       if (fld->bitsize == 24 && fld->shift == 1)
   4886 	reloc = BFD_RELOC_NDS32_25_PCREL;
   4887       else if (fld->bitsize == 16 && fld->shift == 1)
   4888 	reloc = BFD_RELOC_NDS32_17_PCREL;
   4889       else if (fld->bitsize == 14 && fld->shift == 1)
   4890 	reloc = BFD_RELOC_NDS32_15_PCREL;
   4891       else if (fld->bitsize == 8 && fld->shift == 1)
   4892 	reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
   4893       else
   4894 	abort ();
   4895 
   4896       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4897 		   insn->info, 1 /* pcrel */, reloc);
   4898     }
   4899   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4900 	   && (insn->attr & NASM_ATTR_GPREL))
   4901     {
   4902       /* Relocation for 32-bit gp-relative instructions.  */
   4903       if (fld->bitsize == 19 && fld->shift == 0)
   4904 	reloc = BFD_RELOC_NDS32_SDA19S0;
   4905       else if (fld->bitsize == 18 && fld->shift == 1)
   4906 	reloc = BFD_RELOC_NDS32_SDA18S1;
   4907       else if (fld->bitsize == 17 && fld->shift == 2)
   4908 	reloc = BFD_RELOC_NDS32_SDA17S2;
   4909       else
   4910 	abort ();
   4911 
   4912       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4913 		   insn->info, 0 /* pcrel */, reloc);
   4914       /* Insert INSN16 for converting fp_as_gp.  */
   4915       exp.X_op = O_symbol;
   4916       exp.X_add_symbol = abs_section_sym;
   4917       exp.X_add_number = 0;
   4918       if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
   4919 	fix_new_exp (fragP, out - fragP->fr_literal,
   4920 		     insn->opcode->isize, &exp, 0 /* pcrel */,
   4921 		     BFD_RELOC_NDS32_INSN16);
   4922     }
   4923   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
   4924 	   && (insn->attr & NASM_ATTR_PCREL))
   4925     {
   4926       /* Relocation for 16-bit branch instructions.  */
   4927       if (fld->bitsize == 8 && fld->shift == 1)
   4928 	reloc = BFD_RELOC_NDS32_9_PCREL;
   4929       else
   4930 	abort ();
   4931 
   4932       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4933 		   insn->info, 1 /* pcrel */, reloc);
   4934     }
   4935   else if (fld)
   4936     as_bad (_("Don't know how to handle this field. %s"), str);
   4937 
   4938   return fixP;
   4939 }
   4940 
   4941 /* Build instruction pattern to relax.  There are two type group pattern
   4942    including pseudo instruction and relax hint.  */
   4943 
   4944 static void
   4945 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
   4946 				struct nds32_asm_insn *insn, fragS *fragP,
   4947 				const struct nds32_field *fld,
   4948 				bool pseudo_hint)
   4949 {
   4950   struct nds32_relocs_pattern *reloc_ptr;
   4951   struct nds32_relocs_group *group;
   4952   symbolS *sym = NULL;
   4953 
   4954   /* The expression may be used uninitialized.  */
   4955   if (fld)
   4956     sym = pexp->X_add_symbol;
   4957 
   4958   if (pseudo_hint)
   4959     {
   4960       /* We cannot know how many instructions will be expanded for
   4961 	 the pseudo instruction here.  The first expanded instruction fills
   4962 	 the memory created by relax_hint.  The follower will created and link
   4963 	 here.  */
   4964       group = nds32_relax_hint_current;
   4965       while (group)
   4966 	{
   4967 	  if (group->pattern->opcode == NULL)
   4968 	    nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4969 					   group->pattern, fragP);
   4970 	  else
   4971 	    {
   4972 	      group->pattern->next =
   4973 		nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4974 					       NULL, fragP);
   4975 	      group->pattern = group->pattern->next;
   4976 	    }
   4977 	  group = group->next;
   4978 	}
   4979     }
   4980   else if (pseudo_opcode)
   4981     {
   4982       /* Save instruction relation for pseudo instruction expanding pattern.  */
   4983       reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4984 						 NULL, fragP);
   4985       if (!relocs_list)
   4986 	relocs_list = reloc_ptr;
   4987       else
   4988 	{
   4989 	  struct nds32_relocs_pattern *temp = relocs_list;
   4990 	  while (temp->next)
   4991 	    temp = temp->next;
   4992 	  temp->next = reloc_ptr;
   4993 	}
   4994     }
   4995   else if (nds32_relax_hint_current)
   4996     {
   4997       /* Save instruction relation by relax hint.  */
   4998       group = nds32_relax_hint_current;
   4999       while (group)
   5000 	{
   5001 	  nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   5002 					 group->pattern, fragP);
   5003 	  group = group->next;
   5004 	  free (nds32_relax_hint_current);
   5005 	  nds32_relax_hint_current = group;
   5006 	}
   5007     }
   5008 
   5009   /* Set relaxing false only for relax_hint trigger it.  */
   5010   if (!pseudo_opcode)
   5011     relaxing = false;
   5012 }
   5013 
   5014 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
   5015 
   5016 /* Relax pattern for link time relaxation.  */
   5017 /* Relaxation types only! relocation types are not necessary.  */
   5018 /* Refer to nds32_elf_record_fixup_exp ().  */
   5019 
   5020 static struct nds32_relax_hint_table relax_ls_table[] =
   5021 {
   5022   {
   5023     /* LA and Floating LSI.  */
   5024     .main_type = NDS32_RELAX_HINT_LA_FLSI,
   5025     .relax_code_size = 12,
   5026     .relax_code_seq =
   5027       {
   5028 	OP6 (SETHI),
   5029 	OP6 (ORI),
   5030 	OP6 (LBI),
   5031       },
   5032     .relax_fixup =
   5033       {
   5034 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5035 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5036 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5037 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
   5038 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5039 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5040 	{0, 0, 0, 0}
   5041       }
   5042   },
   5043   {
   5044     /* Load Address / Load-Store (LALS).  */
   5045     .main_type = NDS32_RELAX_HINT_LALS,
   5046     .relax_code_size = 12,
   5047     .relax_code_seq =
   5048       {
   5049 	OP6 (SETHI),
   5050 	OP6 (ORI),
   5051 	OP6 (LBI),
   5052       },
   5053     .relax_fixup =
   5054       {
   5055 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5056 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5057 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5058 	{0, 0, 0, 0}
   5059       }
   5060   },
   5061   {
   5062     /* B(AL) symbol@PLT  */
   5063     .main_type = NDS32_RELAX_HINT_LA_PLT,
   5064     .relax_code_size = 16,
   5065     .relax_code_seq =
   5066       {
   5067 	OP6 (SETHI),
   5068 	OP6 (ORI),
   5069 	OP6 (ALU1),
   5070 	OP6 (JREG),
   5071       },
   5072     .relax_fixup =
   5073       {
   5074 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5075 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5076 	{8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5077 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
   5078 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5079 	{12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5080 	{0, 0, 0, 0}
   5081       }
   5082   },
   5083   {
   5084     /* LA (@GOT).  */
   5085     .main_type = NDS32_RELAX_HINT_LA_GOT,
   5086     .relax_code_size = 12,
   5087     .relax_code_seq =
   5088       {
   5089 	OP6 (SETHI),
   5090 	OP6 (ORI),
   5091 	OP6 (MEM),
   5092       },
   5093     .relax_fixup =
   5094       {
   5095 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5096 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5097 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5098 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
   5099 	{0, 0, 0, 0}
   5100       }
   5101   },
   5102   {
   5103     /* LA (@GOTOFF).  */
   5104     .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
   5105     .relax_code_size = 16,
   5106     .relax_code_seq =
   5107       {
   5108 	OP6 (SETHI),
   5109 	OP6 (ORI),
   5110 	OP6 (ALU1),
   5111 	OP6 (MEM),
   5112       },
   5113     .relax_fixup =
   5114       {
   5115 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5116 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5117 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5118 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
   5119 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5120 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
   5121 	{0, 0, 0, 0}
   5122       }
   5123   },
   5124   {
   5125     /* TLS LE LS|LA */
   5126     .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
   5127     .relax_code_size = 16,
   5128     .relax_code_seq =
   5129       {
   5130 	OP6(SETHI),
   5131 	OP6(ORI),
   5132 	OP6(MEM),
   5133 	OP6(ALU1),
   5134       },
   5135     .relax_fixup =
   5136       {
   5137 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5138 	{4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
   5139 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5140 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
   5141 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5142 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
   5143 	{0, 0, 0, 0}
   5144       }
   5145   },
   5146   {
   5147     /* TLS IE LA */
   5148     .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
   5149     .relax_code_size = 8,
   5150     .relax_code_seq =
   5151       {
   5152 	OP6(SETHI),
   5153 	OP6(LBI),
   5154       },
   5155     .relax_fixup =
   5156       {
   5157 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5158 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5159 	{0, 0, 0, 0}
   5160       }
   5161   },
   5162   {
   5163     /* TLS IEGP LA */
   5164     .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
   5165     .relax_code_size = 12,
   5166     .relax_code_seq =
   5167       {
   5168 	OP6 (SETHI),
   5169 	OP6 (ORI),
   5170 	OP6 (MEM),
   5171       },
   5172     .relax_fixup =
   5173       {
   5174 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5175 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
   5176 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5177 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
   5178 	{0, 0, 0, 0}
   5179       }
   5180   },
   5181   {
   5182     /* TLS DESC LS:  */
   5183     .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
   5184     .relax_code_size = 24,
   5185     .relax_code_seq =
   5186       {
   5187 	OP6 (SETHI),
   5188 	OP6 (ORI),
   5189 	OP6 (ALU1),
   5190 	OP6 (LBI),	/* load argument */
   5191 	OP6 (JREG),
   5192 	OP6 (MEM),	/* load/store variable or load argument */
   5193       },
   5194     .relax_fixup =
   5195       {
   5196 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5197 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
   5198 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5199 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
   5200 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
   5201 	{16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
   5202 	{20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
   5203 	{0, 0, 0, 0}
   5204       }
   5205   },
   5206   {
   5207     .main_type = 0,
   5208     .relax_code_seq = {0},
   5209     .relax_fixup = {{0, 0 , 0, 0}}
   5210   }
   5211 };
   5212 
   5213 /* Since sethi loadstore relocation has to using next instruction to determine
   5214    elimination itself or not, we have to return the next instruction range.  */
   5215 
   5216 static int
   5217 nds32_elf_sethi_range (const struct nds32_relocs_pattern *pattern)
   5218 {
   5219   int range = 0;
   5220   while (pattern)
   5221     {
   5222       switch (pattern->opcode->value)
   5223 	{
   5224 	case INSN_LBI:
   5225 	case INSN_SBI:
   5226 	case INSN_LBSI:
   5227 	case N32_MEM_EXT (N32_MEM_LB):
   5228 	case N32_MEM_EXT (N32_MEM_LBS):
   5229 	case N32_MEM_EXT (N32_MEM_SB):
   5230 	  range = NDS32_LOADSTORE_BYTE;
   5231 	  break;
   5232 	case INSN_LHI:
   5233 	case INSN_SHI:
   5234 	case INSN_LHSI:
   5235 	case N32_MEM_EXT (N32_MEM_LH):
   5236 	case N32_MEM_EXT (N32_MEM_LHS):
   5237 	case N32_MEM_EXT (N32_MEM_SH):
   5238 	  range = NDS32_LOADSTORE_HALF;
   5239 	  break;
   5240 	case INSN_LWI:
   5241 	case INSN_SWI:
   5242 	case N32_MEM_EXT (N32_MEM_LW):
   5243 	case N32_MEM_EXT (N32_MEM_SW):
   5244 	  range = NDS32_LOADSTORE_WORD;
   5245 	  break;
   5246 	case INSN_FLSI:
   5247 	case INSN_FSSI:
   5248 	  range = NDS32_LOADSTORE_FLOAT_S;
   5249 	  break;
   5250 	case INSN_FLDI:
   5251 	case INSN_FSDI:
   5252 	  range = NDS32_LOADSTORE_FLOAT_D;
   5253 	  break;
   5254 	case INSN_ORI:
   5255 	  range = NDS32_LOADSTORE_IMM;
   5256 	  break;
   5257 	default:
   5258 	  range = NDS32_LOADSTORE_NONE;
   5259 	  break;
   5260 	}
   5261       if (range != NDS32_LOADSTORE_NONE)
   5262 	break;
   5263       pattern = pattern->next;
   5264     }
   5265   return range;
   5266 }
   5267 
   5268 /* The args means: instruction size, the 1st instruction is converted to 16 or
   5269    not, optimize option, 16 bit instruction is enable.  */
   5270 
   5271 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   5272   (((size) & 0xff) | ((convertible) ? 1u << 31 : 0) \
   5273    | ((optimize) ? 1 << 30 : 0) | (insn16_on ? 1 << 29 : 0))
   5274 #define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
   5275 
   5276 static void
   5277 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
   5278 {
   5279   static int skip_flags = NASM_ATTR_FPU_FMA
   5280     | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT
   5281     | NASM_ATTR_GPREL | NASM_ATTR_DXREG
   5282     | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2
   5283     | NASM_ATTR_ISA_V3 | NASM_ATTR_ISA_V3M
   5284     | NASM_ATTR_PCREL;
   5285 
   5286   int new_flags = insn->opcode->attr & ~skip_flags;
   5287   while (new_flags)
   5288     {
   5289       int next = 1 << (ffs (new_flags) - 1);
   5290       new_flags &= ~next;
   5291       switch (next)
   5292 	{
   5293 	case NASM_ATTR_PERF_EXT:
   5294 	  {
   5295 	    if (nds32_perf_ext)
   5296 	      {
   5297 		nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
   5298 		skip_flags |= NASM_ATTR_PERF_EXT;
   5299 	      }
   5300 	    else
   5301 	      as_bad (_("instruction %s requires enabling performance "
   5302 			"extension"), insn->opcode->opcode);
   5303 	  }
   5304 	  break;
   5305 	case NASM_ATTR_PERF2_EXT:
   5306 	  {
   5307 	    if (nds32_perf_ext2)
   5308 	      {
   5309 		nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
   5310 		skip_flags |= NASM_ATTR_PERF2_EXT;
   5311 	      }
   5312 	    else
   5313 	      as_bad (_("instruction %s requires enabling performance "
   5314 			"extension II"), insn->opcode->opcode);
   5315 	  }
   5316 	  break;
   5317 	case NASM_ATTR_AUDIO_ISAEXT:
   5318 	  {
   5319 	    if (nds32_audio_ext)
   5320 	      {
   5321 		nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
   5322 		skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
   5323 	      }
   5324 	    else
   5325 	      as_bad (_("instruction %s requires enabling AUDIO extension"),
   5326 		      insn->opcode->opcode);
   5327 	  }
   5328 	  break;
   5329 	case NASM_ATTR_STR_EXT:
   5330 	  {
   5331 	    if (nds32_string_ext)
   5332 	      {
   5333 		nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
   5334 		skip_flags |= NASM_ATTR_STR_EXT;
   5335 	      }
   5336 	    else
   5337 	      as_bad (_("instruction %s requires enabling STRING extension"),
   5338 		      insn->opcode->opcode);
   5339 	  }
   5340 	  break;
   5341 	case NASM_ATTR_DIV:
   5342 	  {
   5343 	    if (insn->opcode->attr & NASM_ATTR_DXREG)
   5344 	      {
   5345 		if (nds32_div && nds32_dx_regs)
   5346 		  {
   5347 		    nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
   5348 		    skip_flags |= NASM_ATTR_DIV;
   5349 		  }
   5350 		else
   5351 		  as_bad (_("instruction %s requires enabling DIV & DX_REGS "
   5352 			    "extension"), insn->opcode->opcode);
   5353 	      }
   5354 	  }
   5355 	  break;
   5356 	case NASM_ATTR_FPU:
   5357 	  {
   5358 	    if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
   5359 	      {
   5360 		if (!(nds32_elf_flags
   5361 		      & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   5362 		  nds32_fpu_com = 1;
   5363 		skip_flags |= NASM_ATTR_FPU;
   5364 	      }
   5365 	    else
   5366 	      as_bad (_("instruction %s requires enabling FPU extension"),
   5367 		      insn->opcode->opcode);
   5368 	  }
   5369 	  break;
   5370 	case NASM_ATTR_FPU_SP_EXT:
   5371 	  {
   5372 	    if (nds32_fpu_sp_ext)
   5373 	      {
   5374 		nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
   5375 		skip_flags |= NASM_ATTR_FPU_SP_EXT;
   5376 	      }
   5377 	    else
   5378 	      as_bad (_("instruction %s requires enabling FPU_SP extension"),
   5379 		      insn->opcode->opcode);
   5380 	  }
   5381 	  break;
   5382 	case NASM_ATTR_FPU_DP_EXT:
   5383 	  {
   5384 	    if (nds32_fpu_dp_ext)
   5385 	      {
   5386 		nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
   5387 		skip_flags |= NASM_ATTR_FPU_DP_EXT;
   5388 	      }
   5389 	    else
   5390 	      as_bad (_("instruction %s requires enabling FPU_DP extension"),
   5391 		      insn->opcode->opcode);
   5392 	  }
   5393 	  break;
   5394 	case NASM_ATTR_MAC:
   5395 	  {
   5396 	    if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
   5397 	      {
   5398 		if (nds32_fpu_sp_ext && nds32_mac)
   5399 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   5400 		else
   5401 		  as_bad (_("instruction %s requires enabling FPU_MAC "
   5402 			    "extension"), insn->opcode->opcode);
   5403 	      }
   5404 	    else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
   5405 	      {
   5406 		if (nds32_fpu_dp_ext && nds32_mac)
   5407 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   5408 		else
   5409 		  as_bad (_("instruction %s requires enabling FPU_MAC "
   5410 			    "extension"), insn->opcode->opcode);
   5411 	      }
   5412 	    else if (insn->opcode->attr & NASM_ATTR_DXREG)
   5413 	      {
   5414 		if (nds32_dx_regs && nds32_mac)
   5415 		  nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
   5416 		else
   5417 		  as_bad (_("instruction %s requires enabling DX_REGS "
   5418 			    "extension"), insn->opcode->opcode);
   5419 	      }
   5420 
   5421 	    if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
   5422 	      skip_flags |= NASM_ATTR_MAC;
   5423 	  }
   5424 	  break;
   5425 	case NASM_ATTR_DSP_ISAEXT:
   5426 	  {
   5427 	    if (nds32_dsp_ext)
   5428 	      {
   5429 		nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
   5430 		skip_flags |= NASM_ATTR_DSP_ISAEXT;
   5431 	      }
   5432 	    else
   5433 	      as_bad (_("instruction %s requires enabling dsp extension"),
   5434 		      insn->opcode->opcode);
   5435 	  }
   5436 	  break;
   5437 	case NASM_ATTR_ZOL:
   5438 	  {
   5439 	    if (nds32_zol_ext)
   5440 	      {
   5441 		nds32_elf_flags |= E_NDS32_HAS_ZOL;
   5442 		skip_flags |= NASM_ATTR_ZOL;
   5443 	      }
   5444 	    else
   5445 	      as_bad (_("instruction %s requires enabling zol extension"),
   5446 		      insn->opcode->opcode);
   5447 	  }
   5448 	  break;
   5449 	default:
   5450 	  as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
   5451 		  next);
   5452 	}
   5453     }
   5454 }
   5455 
   5456 /* Flag for analysis relaxation type.  */
   5457 
   5458 enum nds32_insn_type
   5459 {
   5460   N32_RELAX_SETHI = 1,
   5461   N32_RELAX_BR = (1 << 1),
   5462   N32_RELAX_LSI = (1 << 2),
   5463   N32_RELAX_JUMP = (1 << 3),
   5464   N32_RELAX_CALL = (1 << 4),
   5465   N32_RELAX_ORI = (1 << 5),
   5466   N32_RELAX_MEM = (1 << 6),
   5467   N32_RELAX_MOVI = (1 << 7),
   5468   N32_RELAX_ALU1 = (1 << 8),
   5469   N32_RELAX_16BIT = (1 << 9),
   5470 };
   5471 
   5472 struct nds32_hint_map
   5473 {
   5474   /* the preamble relocation */
   5475   bfd_reloc_code_real_type hi_type;
   5476   /* mnemonic */
   5477   const char *opc;
   5478   /* relax pattern ID */
   5479   enum nds32_relax_hint_type hint_type;
   5480   /* range */
   5481   enum nds32_br_range range;
   5482   /* pattern character flags */
   5483   enum nds32_insn_type insn_list;
   5484   /* optional pattern character flags */
   5485   enum nds32_insn_type option_list;
   5486 };
   5487 
   5488 /* Table to match instructions with hint and relax pattern.  */
   5489 
   5490 static struct nds32_hint_map hint_map [] =
   5491 {
   5492   {
   5493     /* LONGCALL4.  */
   5494     BFD_RELOC_NDS32_HI20,
   5495     "jal",
   5496     NDS32_RELAX_HINT_NONE,
   5497     BR_RANGE_U4G,
   5498     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
   5499     0,
   5500   },
   5501   {
   5502     /* LONGCALL5.  */
   5503     _dummy_first_bfd_reloc_code_real,
   5504     "bgezal",
   5505     NDS32_RELAX_HINT_NONE,
   5506     BR_RANGE_S16M,
   5507     N32_RELAX_BR | N32_RELAX_CALL,
   5508     0,
   5509   },
   5510   {
   5511     /* LONGCALL6.  */
   5512     BFD_RELOC_NDS32_HI20,
   5513     "bgezal",
   5514     NDS32_RELAX_HINT_NONE,
   5515     BR_RANGE_U4G,
   5516     N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
   5517     0,
   5518   },
   5519   {
   5520     /* LONGJUMP4.  */
   5521     BFD_RELOC_NDS32_HI20,
   5522     "j",
   5523     NDS32_RELAX_HINT_NONE,
   5524     BR_RANGE_U4G,
   5525     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
   5526     0,
   5527   },
   5528   {
   5529     /* LONGJUMP5.  */
   5530     /* There is two kinds of variation of LONGJUMP5.  One of them
   5531        generate EMPTY relocation for converted INSN16 if needed.
   5532        But we don't distinguish them here.  */
   5533     _dummy_first_bfd_reloc_code_real,
   5534     "beq",
   5535     NDS32_RELAX_HINT_NONE,
   5536     BR_RANGE_S16M,
   5537     N32_RELAX_BR | N32_RELAX_JUMP,
   5538     0,
   5539   },
   5540   {
   5541     /* LONGJUMP6.  */
   5542     BFD_RELOC_NDS32_HI20,
   5543     "beq",
   5544     NDS32_RELAX_HINT_NONE,
   5545     BR_RANGE_U4G,
   5546     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
   5547     0,
   5548   },
   5549   {
   5550     /* LONGJUMP7.  */
   5551     _dummy_first_bfd_reloc_code_real,
   5552     "beqc",
   5553     NDS32_RELAX_HINT_NONE,
   5554     BR_RANGE_S16K,
   5555     N32_RELAX_MOVI | N32_RELAX_BR,
   5556     0,
   5557   },
   5558   {
   5559     /* LONGCALL (BAL|JR|LA symbol@PLT).  */
   5560     BFD_RELOC_NDS32_PLT_GOTREL_HI20,
   5561     NULL,
   5562     NDS32_RELAX_HINT_LA_PLT,
   5563     BR_RANGE_U4G,
   5564     N32_RELAX_SETHI | N32_RELAX_ORI,
   5565     N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
   5566   },
   5567   /* relative issue: #12566 */
   5568   {
   5569     /* LA and Floating LSI.  */
   5570     BFD_RELOC_NDS32_HI20,
   5571     NULL,
   5572     NDS32_RELAX_HINT_LA_FLSI,
   5573     BR_RANGE_U4G,
   5574     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
   5575     0,
   5576   },
   5577   /* relative issue: #11685 #11602 */
   5578   {
   5579     /* load address / load-store (LALS).  */
   5580     BFD_RELOC_NDS32_HI20,
   5581     NULL,
   5582     NDS32_RELAX_HINT_LALS,
   5583     BR_RANGE_U4G,
   5584     N32_RELAX_SETHI,
   5585     N32_RELAX_ORI | N32_RELAX_LSI,
   5586   },
   5587   {
   5588     /* setup $GP (_GLOBAL_OFFSET_TABLE_)  */
   5589     BFD_RELOC_NDS32_GOTPC_HI20,
   5590     NULL,
   5591     NDS32_RELAX_HINT_LALS,
   5592     BR_RANGE_U4G,
   5593     N32_RELAX_SETHI | N32_RELAX_ORI,
   5594     0,
   5595   },
   5596   {
   5597     /* GOT LA/LS (symbol@GOT)  */
   5598     BFD_RELOC_NDS32_GOT_HI20,
   5599     NULL,
   5600     NDS32_RELAX_HINT_LA_GOT,
   5601     BR_RANGE_U4G,
   5602     N32_RELAX_SETHI | N32_RELAX_ORI,
   5603     N32_RELAX_MEM,
   5604   },
   5605   {
   5606     /* GOTOFF LA/LS (symbol@GOTOFF)  */
   5607     BFD_RELOC_NDS32_GOTOFF_HI20,
   5608     NULL,
   5609     NDS32_RELAX_HINT_LA_GOTOFF,
   5610     BR_RANGE_U4G,
   5611     N32_RELAX_SETHI | N32_RELAX_ORI,
   5612     N32_RELAX_ALU1  | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
   5613   },
   5614   {
   5615     /* TLS LE LA|LS (@TPOFF)  */
   5616     BFD_RELOC_NDS32_TLS_LE_HI20,
   5617     NULL,
   5618     NDS32_RELAX_HINT_TLS_LE_LS,
   5619     BR_RANGE_U4G,
   5620     N32_RELAX_SETHI | N32_RELAX_ORI,
   5621     N32_RELAX_ALU1 | N32_RELAX_MEM,
   5622   },
   5623   {
   5624     /* TLS IE LA */
   5625     BFD_RELOC_NDS32_TLS_IE_HI20,
   5626     NULL,
   5627     NDS32_RELAX_HINT_TLS_IE_LA,
   5628     BR_RANGE_U4G,
   5629     N32_RELAX_SETHI | N32_RELAX_LSI,
   5630     0,
   5631   },
   5632 {
   5633     /* TLS IE LS */
   5634     BFD_RELOC_NDS32_TLS_IE_HI20,
   5635     NULL,
   5636     NDS32_RELAX_HINT_TLS_IE_LS,
   5637     BR_RANGE_U4G,
   5638     N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
   5639     0,
   5640   },
   5641   {
   5642     /* TLS IEGP LA */
   5643     BFD_RELOC_NDS32_TLS_IEGP_HI20,
   5644     NULL,
   5645     NDS32_RELAX_HINT_TLS_IEGP_LA,
   5646     BR_RANGE_U4G,
   5647     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
   5648     0,
   5649   },
   5650   {
   5651     /* TLS DESC LS */
   5652     BFD_RELOC_NDS32_TLS_DESC_HI20,
   5653     NULL,
   5654     NDS32_RELAX_HINT_TLS_DESC_LS,
   5655     BR_RANGE_U4G,
   5656     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
   5657     N32_RELAX_LSI | N32_RELAX_MEM,
   5658   },
   5659   /* last one */
   5660   {0, NULL, 0, 0 ,0, 0}
   5661 };
   5662 
   5663 /* Find the relaxation pattern according to instructions.  */
   5664 
   5665 static bool
   5666 nds32_find_reloc_table (const struct nds32_relocs_pattern *relocs_pattern,
   5667 			struct nds32_relax_hint_table *hint_info)
   5668 {
   5669   unsigned int opcode, seq_size;
   5670   enum nds32_br_range range;
   5671   const struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
   5672   const char *opc = NULL;
   5673   relax_info_t *relax_info = NULL;
   5674   nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
   5675   enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
   5676   struct nds32_relax_hint_table *table_ptr;
   5677   uint32_t *code_seq, *hint_code;
   5678   enum nds32_insn_type relax_type = 0;
   5679   struct nds32_hint_map *map_ptr = hint_map;
   5680   unsigned int i;
   5681   const char *check_insn[] =
   5682     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
   5683 
   5684   /* TODO: PLT GOT.  */
   5685   /* Traverse all pattern instruction and set flag.  */
   5686   pattern = relocs_pattern;
   5687   while (pattern)
   5688     {
   5689       if (pattern->opcode->isize == 4)
   5690 	{
   5691 	  /* 4 byte instruction.  */
   5692 	  opcode = N32_OP6 (pattern->opcode->value);
   5693 	  switch (opcode)
   5694 	    {
   5695 	    case N32_OP6_SETHI:
   5696 	      hi_pattern = pattern;
   5697 	      relax_type |= N32_RELAX_SETHI;
   5698 	      break;
   5699 	    case N32_OP6_MEM:
   5700 	      relax_type |= N32_RELAX_MEM;
   5701 	      break;
   5702 	    case N32_OP6_ALU1:
   5703 	      relax_type |= N32_RELAX_ALU1;
   5704 	      break;
   5705 	    case N32_OP6_ORI:
   5706 	      relax_type |= N32_RELAX_ORI;
   5707 	      break;
   5708 	    case N32_OP6_BR1:
   5709 	    case N32_OP6_BR2:
   5710 	    case N32_OP6_BR3:
   5711 	      relax_type |= N32_RELAX_BR;
   5712 	      break;
   5713 	    case N32_OP6_MOVI:
   5714 	      relax_type |= N32_RELAX_MOVI;
   5715 	      break;
   5716 	    case N32_OP6_LBI:
   5717 	    case N32_OP6_SBI:
   5718 	    case N32_OP6_LBSI:
   5719 	    case N32_OP6_LHI:
   5720 	    case N32_OP6_SHI:
   5721 	    case N32_OP6_LHSI:
   5722 	    case N32_OP6_LWI:
   5723 	    case N32_OP6_SWI:
   5724 	    case N32_OP6_LWC:
   5725 	    case N32_OP6_SWC:
   5726 	    case N32_OP6_LDC:
   5727 	    case N32_OP6_SDC:
   5728 	      relax_type |= N32_RELAX_LSI;
   5729 	      break;
   5730 	    case N32_OP6_JREG:
   5731 	      if (__GF (pattern->opcode->value, 0, 1) == 1)
   5732 		relax_type |= N32_RELAX_CALL;
   5733 	      else
   5734 		relax_type |= N32_RELAX_JUMP;
   5735 	      break;
   5736 	    case N32_OP6_JI:
   5737 	      if (__GF (pattern->opcode->value, 24, 1) == 1)
   5738 		relax_type |= N32_RELAX_CALL;
   5739 	      else
   5740 		relax_type |= N32_RELAX_JUMP;
   5741 	      break;
   5742 	    default:
   5743 	      as_warn (_("relax hint unrecognized instruction: line %d."),
   5744 		       pattern->frag->fr_line);
   5745 	      return false;
   5746 	    }
   5747 	}
   5748       else
   5749 	{
   5750 	  /* 2 byte instruction.  Compare by opcode name because
   5751 	     the opcode of 2byte instruction is not regular.  */
   5752 	  int is_matched = 0;
   5753 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5754 	    {
   5755 	      if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
   5756 		{
   5757 		  relax_type |= N32_RELAX_BR;
   5758 		  is_matched += 1;
   5759 		  break;
   5760 		}
   5761 	    }
   5762 	  if (!is_matched)
   5763 	    relax_type |= N32_RELAX_16BIT;
   5764 	}
   5765       pattern = pattern->next;
   5766     }
   5767 
   5768   /* Analysis instruction flag to choose relaxation table.  */
   5769   while (map_ptr->insn_list != 0)
   5770     {
   5771       struct nds32_hint_map *hint = map_ptr++;
   5772       enum nds32_insn_type must = hint->insn_list;
   5773       enum nds32_insn_type optional = hint->option_list;
   5774       enum nds32_insn_type extra;
   5775 
   5776       if (must != (must & relax_type))
   5777 	continue;
   5778 
   5779       extra = relax_type ^ must;
   5780       if (extra != (extra & optional))
   5781 	continue;
   5782 
   5783       if (!hi_pattern
   5784 	  || (hi_pattern->fixP
   5785 	      && hi_pattern->fixP->fx_r_type == hint->hi_type))
   5786 	{
   5787 	  opc = hint->opc;
   5788 	  hint_type = hint->hint_type;
   5789 	  range = hint->range;
   5790 	  map_ptr = hint;
   5791 	  break;
   5792 	}
   5793     }
   5794 
   5795   if (map_ptr->insn_list == 0)
   5796     {
   5797       if (!nds32_pic)
   5798 	as_warn (_("Can not find match relax hint.  Line: %d"),
   5799 		 relocs_pattern->frag->fr_line);
   5800       return false;
   5801     }
   5802 
   5803   /* Get the match table.  */
   5804   if (opc)
   5805     {
   5806       /* Branch relax pattern.  */
   5807       relax_info = str_hash_find (nds32_relax_info_hash, opc);
   5808       if (!relax_info)
   5809 	return false;
   5810       fixup_info = relax_info->relax_fixup[range];
   5811       code_seq = relax_info->relax_code_seq[range];
   5812       seq_size = relax_info->relax_code_size[range];
   5813     }
   5814   else if (hint_type)
   5815     {
   5816       /* Load-store relax pattern.  */
   5817       table_ptr = relax_ls_table;
   5818       while (table_ptr->main_type != 0)
   5819 	{
   5820 	  if (table_ptr->main_type == hint_type)
   5821 	    {
   5822 	      fixup_info = table_ptr->relax_fixup;
   5823 	      code_seq = table_ptr->relax_code_seq;
   5824 	      seq_size = table_ptr->relax_code_size;
   5825 	      break;
   5826 	    }
   5827 	  table_ptr++;
   5828 	}
   5829       if (table_ptr->main_type == 0)
   5830 	return false;
   5831     }
   5832   else
   5833     return false;
   5834 
   5835   hint_fixup = hint_info->relax_fixup;
   5836   hint_code = hint_info->relax_code_seq;
   5837   hint_info->relax_code_size = seq_size;
   5838 
   5839   while (fixup_info->size != 0)
   5840     {
   5841       if (fixup_info->ramp & NDS32_HINT)
   5842 	{
   5843 	  memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
   5844 	  hint_fixup++;
   5845 	}
   5846       fixup_info++;
   5847     }
   5848   /* Clear final relocation.  */
   5849   memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
   5850   /* Copy code sequence.  */
   5851   memcpy (hint_code, code_seq, seq_size);
   5852   return true;
   5853 }
   5854 
   5855 /* Because there are a lot of variant of load-store, check
   5856    all these type here.  */
   5857 
   5858 #define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
   5859 #define GET_OPCODE(insn) ((insn) & 0xfe000000)
   5860 
   5861 static bool
   5862 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
   5863 {
   5864   const char *check_insn[] =
   5865     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
   5866   uint32_t insn = opcode->value;
   5867   unsigned int i;
   5868 
   5869   insn = CLEAN_REG (opcode->value);
   5870   if (insn == seq)
   5871     return true;
   5872 
   5873   switch (seq)
   5874     {
   5875     case OP6 (LBI):
   5876       /* In relocation_table, it regards instruction LBI as representation
   5877 	 of all the NDS32_RELAX_HINT_LS pattern.  */
   5878       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
   5879 	  || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
   5880 	  || insn == OP6 (LWI) || insn == OP6 (SWI)
   5881 	  || insn == OP6 (LWC) || insn == OP6 (SWC)
   5882 	  || insn == OP6 (LDC) || insn == OP6 (SDC))
   5883 	return true;
   5884       break;
   5885     case OP6 (BR2):
   5886       /* This is for LONGCALL5 and LONGCALL6.  */
   5887       if (insn == OP6 (BR2))
   5888 	return true;
   5889       break;
   5890     case OP6 (BR1):
   5891       /* This is for LONGJUMP5 and LONGJUMP6.  */
   5892       if (opcode->isize == 4
   5893 	  && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
   5894 	return true;
   5895       else if (opcode->isize == 2)
   5896 	{
   5897 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5898 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
   5899 	      return true;
   5900 	}
   5901       break;
   5902     case OP6 (MOVI):
   5903       /* This is for LONGJUMP7.  */
   5904       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
   5905 	return true;
   5906       break;
   5907     case OP6 (MEM):
   5908       if (OP6 (MEM) == GET_OPCODE (insn))
   5909 	return true;
   5910       break;
   5911     case OP6 (JREG):
   5912       /* bit 24: N32_JI_JAL  */ /* feed me!  */
   5913       if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
   5914 	return true;
   5915       break;
   5916     default:
   5917       if (opcode->isize == 2)
   5918 	{
   5919 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5920 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
   5921 	      return true;
   5922 
   5923 	  if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
   5924 	      (strcmp (opcode->opcode, "add45") == 0))
   5925 	    return true;
   5926 	}
   5927     }
   5928   return false;
   5929 }
   5930 
   5931 /* Append relax relocation for link time relaxing.  */
   5932 
   5933 static void
   5934 nds32_elf_append_relax_relocs (const char *key, const void *value)
   5935 {
   5936   const struct nds32_relocs_pattern *relocs_pattern = value;
   5937   const struct nds32_relocs_pattern *pattern_temp, *pattern_now;
   5938   symbolS *sym, *hi_sym = NULL;
   5939   expressionS exp;
   5940   fragS *fragP;
   5941   segT seg_bak = now_seg;
   5942   frchainS *frchain_bak = frchain_now;
   5943   struct nds32_relax_hint_table hint_info;
   5944   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
   5945   size_t fixup_size;
   5946   offsetT branch_offset, hi_branch_offset = 0;
   5947   fixS *fixP;
   5948   int range, offset;
   5949   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
   5950   uint32_t *code_seq, code_insn;
   5951   char *where;
   5952   int pcrel;
   5953 
   5954   if (!relocs_pattern)
   5955     return;
   5956 
   5957   if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
   5958     return;
   5959 
   5960   /* Save symbol for some EMPTY relocation using.  */
   5961   pattern_now = relocs_pattern;
   5962   while (pattern_now)
   5963     {
   5964       if (pattern_now->opcode->value == OP6 (SETHI))
   5965 	{
   5966 	  hi_sym = pattern_now->sym;
   5967 	  hi_branch_offset = pattern_now->fixP->fx_offset;
   5968 	  break;
   5969 	}
   5970       pattern_now = pattern_now->next;
   5971     }
   5972 
   5973   /* Inserting fix up must specify now_seg or frchain_now.  */
   5974   now_seg = relocs_pattern->seg;
   5975   frchain_now = relocs_pattern->frchain;
   5976   fragP = relocs_pattern->frag;
   5977   branch_offset = fragP->fr_offset;
   5978 
   5979   hint_fixup = hint_info.relax_fixup;
   5980   code_seq = hint_info.relax_code_seq;
   5981   relax_code_size = hint_info.relax_code_size;
   5982   pattern_now = relocs_pattern;
   5983 
   5984 #ifdef NDS32_LINUX_TOOLCHAIN
   5985   /* prepare group relocation ID (number).  */
   5986   long group_id = 0;
   5987   if (key)
   5988     {
   5989       /* convert .relax_hint key to number */
   5990       errno = 0;
   5991       group_id = strtol (key, NULL, 10);
   5992       if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
   5993 	  || (errno != 0 && group_id == 0))
   5994 	{
   5995 	  as_bad (_("Internal error: .relax_hint KEY is not a number!"));
   5996 	  goto restore;
   5997 	}
   5998     }
   5999 #endif
   6000 
   6001   /* Insert relaxation.  */
   6002   exp.X_op = O_symbol;
   6003 
   6004   /* For each instruction in the hint group.  */
   6005   while (pattern_now)
   6006     {
   6007       if (count >= relax_code_size / 4)
   6008 	count = 0;
   6009 
   6010       /* Choose the match fixup by instruction.  */
   6011       code_insn = CLEAN_REG (*(code_seq + count));
   6012       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   6013 	{
   6014 	  /* Try search from head again */
   6015 	  count = 0;
   6016 	  code_insn = CLEAN_REG (*(code_seq + count));
   6017 
   6018 	  while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   6019 	    {
   6020 	      count++;
   6021 	      if (count >= relax_code_size / 4)
   6022 		{
   6023 		  as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
   6024 			  key,
   6025 			  now_seg->name,
   6026 			  pattern_now->opcode->opcode,
   6027 			  pattern_now->opcode->value);
   6028 		  goto restore;
   6029 		}
   6030 	      code_insn = CLEAN_REG (*(code_seq + count));
   6031 	    }
   6032 	}
   6033       fragP = pattern_now->frag;
   6034       sym = pattern_now->sym;
   6035       branch_offset = fragP->fr_offset;
   6036       offset = count * 4;
   6037       where = pattern_now->where;
   6038       /* Find the instruction map fix.  */
   6039       fixup_now = hint_fixup;
   6040       while (fixup_now->offset != offset)
   6041 	{
   6042 	  fixup_now++;
   6043 	  if (fixup_now->size == 0)
   6044 	    break;
   6045 	}
   6046       /* This element is without relaxation relocation.  */
   6047       if (fixup_now->size == 0)
   6048 	{
   6049 	  pattern_now = pattern_now->next;
   6050 	  continue;
   6051 	}
   6052       fixup_size = fixup_now->size;
   6053 
   6054       /* Insert all fixup.  */
   6055       pcrel = 0;
   6056       while (fixup_size != 0 && fixup_now->offset == offset)
   6057 	{
   6058 	  /* Set the real instruction size in element.  */
   6059 	  fixup_size = pattern_now->opcode->isize;
   6060 	  pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
   6061 	  if (fixup_now->ramp & NDS32_FIX)
   6062 	    {
   6063 	      /* Convert original relocation.  */
   6064 	      pattern_now->fixP->fx_r_type = fixup_now->r_type ;
   6065 	      fixup_size = 0;
   6066 	    }
   6067 	  else if ((fixup_now->ramp & NDS32_PTR) != 0)
   6068 	    {
   6069 	      /* This relocation has to point to another instruction.  Make
   6070 		 sure each resolved relocation has to be pointed.  */
   6071 	      pattern_temp = relocs_pattern;
   6072 	      /* All instruction in relax_table should be 32-bit.  */
   6073 	      hint_count = hint_info.relax_code_size / 4;
   6074 	      code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
   6075 	      while (pattern_temp)
   6076 		{
   6077 		  /* Point to every resolved relocation.  */
   6078 		  if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
   6079 		    {
   6080 		      ptr_offset =
   6081 			pattern_temp->where - pattern_temp->frag->fr_literal;
   6082 		      exp.X_add_symbol = symbol_temp_new (now_seg,
   6083 							  pattern_temp->frag,
   6084 							  ptr_offset);
   6085 		      exp.X_add_number = 0;
   6086 		      fixP =
   6087 			fix_new_exp (fragP, where - fragP->fr_literal,
   6088 				     fixup_size, &exp, 0, fixup_now->r_type);
   6089 		      fixP->fx_addnumber = fixP->fx_offset;
   6090 		    }
   6091 		  pattern_temp = pattern_temp->next;
   6092 		}
   6093 	      fixup_size = 0;
   6094 	    }
   6095 	  else if (fixup_now->ramp & NDS32_ADDEND)
   6096 	    {
   6097 	      range = nds32_elf_sethi_range (relocs_pattern);
   6098 	      if (range == NDS32_LOADSTORE_NONE)
   6099 		{
   6100 		  as_bad (_("Internal error: Range error. %s"), now_seg->name);
   6101 		  return;
   6102 		}
   6103 	      exp.X_add_symbol = abs_section_sym;
   6104 	      exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
   6105 	      exp.X_add_number |= ((range & 0x3f) << 8);
   6106 	    }
   6107 	  else if ((fixup_now->ramp & NDS32_ABS) != 0)
   6108 	    {
   6109 	      /* This is a tag relocation.  */
   6110 	      exp.X_add_symbol = abs_section_sym;
   6111 	      exp.X_add_number = 0;
   6112 	    }
   6113 	  else if ((fixup_now->ramp & NDS32_INSN16) != 0)
   6114 	    {
   6115 	      if (!enable_16bit)
   6116 		fixup_size = 0;
   6117 	      /* This is a tag relocation.  */
   6118 	      exp.X_add_symbol = abs_section_sym;
   6119 	      exp.X_add_number = 0;
   6120 	    }
   6121 	  else if ((fixup_now->ramp & NDS32_SYM) != 0)
   6122 	    {
   6123 	      /* For EMPTY relocation save the true symbol.  */
   6124 	      exp.X_add_symbol = hi_sym;
   6125 	      exp.X_add_number = hi_branch_offset;
   6126 	    }
   6127 	  else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
   6128 	    {
   6129 	      /* Do the same as NDS32_SYM.  */
   6130 	      exp.X_add_symbol = hi_sym;
   6131 	      exp.X_add_number = hi_branch_offset;
   6132 
   6133 	      /* Extra to NDS32_SYM.  */
   6134 	      /* Detect if DESC_FUNC relax type do apply.  */
   6135 	      if ((REG_GP == N32_RA5 (pattern_now->insn))
   6136 		  || (REG_GP == N32_RB5 (pattern_now->insn)))
   6137 		{
   6138 		  fixP = fix_new_exp (fragP, where - fragP->fr_literal,
   6139 				      fixup_size, &exp, pcrel,
   6140 				      BFD_RELOC_NDS32_TLS_DESC_FUNC);
   6141 		  fixP->fx_addnumber = fixP->fx_offset;
   6142 
   6143 		  fixup_size = 0;
   6144 		}
   6145 	      /* Else do as usual.  */
   6146 	    }
   6147 	  else if (fixup_now->ramp & NDS32_PTR_PATTERN)
   6148 	    {
   6149 	      /* Find out PTR_RESOLVED code pattern.  */
   6150 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
   6151 	      uint32_t resolved_pattern = 0;
   6152 	      while (next_fixup->offset)
   6153 		{
   6154 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
   6155 		    {
   6156 		      uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
   6157 		      if (!resolved_pattern)
   6158 			resolved_pattern = new_pattern;
   6159 		      else if (new_pattern != resolved_pattern)
   6160 			{
   6161 			  as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
   6162 				     "patterns are not supported yet!"));
   6163 			  break;
   6164 			}
   6165 		    }
   6166 		  ++next_fixup;
   6167 		}
   6168 
   6169 	      /* Find matched code and insert fix-ups.  */
   6170 	      struct nds32_relocs_pattern *next_pattern = pattern_now->next;
   6171 	      /* This relocation has to point to another instruction.
   6172 		 Make sure each resolved relocation has to be pointed.  */
   6173 	      /* All instruction in relax_table should be 32-bit.  */
   6174 	      while (next_pattern)
   6175 		{
   6176 		  uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
   6177 		  if (cur_pattern == resolved_pattern)
   6178 		    {
   6179 		      ptr_offset = next_pattern->where
   6180 			- next_pattern->frag->fr_literal;
   6181 		      exp.X_add_symbol = symbol_temp_new (now_seg,
   6182 							  next_pattern->frag,
   6183 							  ptr_offset);
   6184 		      exp.X_add_number = 0;
   6185 		      fixP = fix_new_exp (fragP, where - fragP->fr_literal,
   6186 					  fixup_size, &exp, 0,
   6187 					  fixup_now->r_type);
   6188 		      fixP->fx_addnumber = fixP->fx_offset;
   6189 		    }
   6190 		  next_pattern = next_pattern->next;
   6191 		}
   6192 
   6193 	      fixup_size = 0;
   6194 	    }
   6195 	  else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
   6196 	    {
   6197 	      /* Find each PTR_RESOLVED pattern after PTR.  */
   6198 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
   6199 	      while (next_fixup->offset)
   6200 		{
   6201 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
   6202 		    {
   6203 		      uint32_t pattern = code_seq[next_fixup->offset >> 2];
   6204 		      /* Find matched code to insert fix-ups.  */
   6205 		      struct nds32_relocs_pattern *next_insn = pattern_now->next;
   6206 		      while (next_insn)
   6207 			{
   6208 			  uint32_t insn_pattern = GET_OPCODE (next_insn->opcode->value);
   6209 			  if (insn_pattern == pattern)
   6210 			    {
   6211 			      ptr_offset = next_insn->where
   6212 				- next_insn->frag->fr_literal;
   6213 			      exp.X_add_symbol = symbol_temp_new (now_seg,
   6214 								  next_insn->frag,
   6215 								  ptr_offset);
   6216 			      exp.X_add_number = 0;
   6217 			      fixP = fix_new_exp (fragP,
   6218 						  where - fragP->fr_literal,
   6219 						  fixup_size, &exp, 0,
   6220 						  fixup_now->r_type);
   6221 			      fixP->fx_addnumber = fixP->fx_offset;
   6222 			    }
   6223 			  next_insn = next_insn->next;
   6224 			}
   6225 		    }
   6226 		  ++next_fixup;
   6227 		}
   6228 	      fixup_size = 0;
   6229 	    }
   6230 	  else
   6231 	    {
   6232 	      exp.X_add_symbol = sym;
   6233 	      exp.X_add_number = branch_offset;
   6234 	    }
   6235 
   6236 	  if (fixup_size != 0)
   6237 	    {
   6238 	      fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
   6239 				  &exp, pcrel, fixup_now->r_type);
   6240 	      fixP->fx_addnumber = fixP->fx_offset;
   6241 	    }
   6242 	  fixup_now++;
   6243 	  fixup_size = fixup_now->size;
   6244 	}
   6245 
   6246 #ifdef NDS32_LINUX_TOOLCHAIN
   6247       /* Insert group relocation for each relax hint.  */
   6248       if (key)
   6249 	{
   6250 	  exp.X_add_symbol = hi_sym; /* for eyes only */
   6251 	  exp.X_add_number = group_id;
   6252 	  fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
   6253 			      &exp, pcrel, BFD_RELOC_NDS32_GROUP);
   6254 	  fixP->fx_addnumber = fixP->fx_offset;
   6255 	}
   6256 #endif
   6257 
   6258       if (count < relax_code_size / 4)
   6259 	count++;
   6260       pattern_now = pattern_now->next;
   6261     }
   6262 
   6263  restore:
   6264   now_seg = seg_bak;
   6265   frchain_now = frchain_bak;
   6266 }
   6267 
   6268 static int
   6269 nds32_elf_append_relax_relocs_traverse (void **slot, void *arg ATTRIBUTE_UNUSED)
   6270 {
   6271   string_tuple_t *tuple = *((string_tuple_t **) slot);
   6272   nds32_elf_append_relax_relocs (tuple->key, (const void *) tuple->value);
   6273   return 1;
   6274 }
   6275 
   6276 
   6277 static void
   6278 nds32_str_tolower (const char *src, char *dest)
   6279 {
   6280   unsigned int i, len;
   6281 
   6282   len = strlen (src);
   6283 
   6284   for (i = 0; i < len; i++)
   6285     *(dest + i) = TOLOWER (*(src + i));
   6286 
   6287   *(dest + i) = '\0';
   6288 }
   6289 
   6290 /* Check instruction if it can be used for the baseline.  */
   6291 
   6292 static bool
   6293 nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
   6294 {
   6295   int attr = insn.attr & ATTR_ALL;
   6296   static int baseline_isa = 0;
   6297   char *s;
   6298 
   6299   s = xmalloc (strlen (str) + 1);
   6300   nds32_str_tolower (str, s);
   6301   if (verbatim
   6302       && (((insn.opcode->value == ALU2 (MTUSR)
   6303 	    || insn.opcode->value == ALU2 (MFUSR))
   6304 	   && (strstr (s, "lc")
   6305 	       || strstr (s, "le")
   6306 	       || strstr (s, "lb")))
   6307 	  || (insn.attr & NASM_ATTR_ZOL)))
   6308     {
   6309       as_bad (_("Not support instruction %s in verbatim."), str);
   6310       return false;
   6311     }
   6312   free (s);
   6313 
   6314   if (!enable_16bit && insn.opcode->isize == 2)
   6315     {
   6316       as_bad (_("16-bit instruction is disabled: %s."), str);
   6317       return false;
   6318     }
   6319 
   6320   /* No isa setting or all isa can use.  */
   6321   if (attr == 0 || attr == ATTR_ALL)
   6322     return true;
   6323 
   6324   if (baseline_isa == 0)
   6325     {
   6326       /* Map option baseline and instruction attribute.  */
   6327       switch (nds32_baseline)
   6328 	{
   6329 	case ISA_V2:
   6330 	  baseline_isa = ATTR (ISA_V2);
   6331 	  break;
   6332 	case ISA_V3:
   6333 	  baseline_isa = ATTR (ISA_V3);
   6334 	  break;
   6335 	case ISA_V3M:
   6336 	  baseline_isa = ATTR (ISA_V3M);
   6337 	  break;
   6338 	}
   6339     }
   6340 
   6341   if  ((baseline_isa & attr) == 0)
   6342     {
   6343       as_bad (_("Instruction %s not supported in the baseline."), str);
   6344       return false;
   6345     }
   6346   return true;
   6347 }
   6348 
   6349 /* Stub of machine dependent.  */
   6350 
   6351 void
   6352 md_assemble (char *str)
   6353 {
   6354   struct nds32_asm_insn insn;
   6355   char *out;
   6356   struct nds32_pseudo_opcode *popcode;
   6357   const struct nds32_field *fld = NULL;
   6358   fixS *fixP;
   6359   uint16_t insn_16;
   6360   struct nds32_relocs_pattern *relocs_temp;
   6361   struct nds32_relocs_group *group_temp;
   6362   fragS *fragP;
   6363   int label = label_exist;
   6364   static bool pseudo_hint = false;
   6365 
   6366   popcode = nds32_lookup_pseudo_opcode (str);
   6367   /* Note that we need to check 'verbatim' and
   6368      'opcode->physical_op'.  If the assembly content is generated by
   6369      compiler and this opcode is a physical instruction, there is no
   6370      need to perform pseudo instruction expansion/transformation.  */
   6371   if (popcode && !(verbatim && popcode->physical_op))
   6372     {
   6373       /* Pseudo instruction is with relax_hint.  */
   6374       if (relaxing)
   6375 	pseudo_hint = true;
   6376       pseudo_opcode = true;
   6377       nds32_pseudo_opcode_wrapper (str, popcode);
   6378       pseudo_opcode = false;
   6379       pseudo_hint = false;
   6380       nds32_elf_append_relax_relocs (NULL, relocs_list);
   6381 
   6382       /* Free relax_hint group list.  */
   6383       while (nds32_relax_hint_current)
   6384 	{
   6385 	  group_temp = nds32_relax_hint_current->next;
   6386 	  free (nds32_relax_hint_current);
   6387 	  nds32_relax_hint_current = group_temp;
   6388 	}
   6389 
   6390       /* Free pseudo list.  */
   6391       relocs_temp = relocs_list;
   6392       while (relocs_temp)
   6393 	{
   6394 	  relocs_list = relocs_list->next;
   6395 	  free (relocs_temp);
   6396 	  relocs_temp = relocs_list;
   6397 	}
   6398 
   6399       return;
   6400     }
   6401 
   6402   label_exist = 0;
   6403   insn.info = XNEW (expressionS);
   6404   asm_desc.result = NASM_OK;
   6405   nds32_assemble (&asm_desc, &insn, str);
   6406 
   6407   switch (asm_desc.result)
   6408     {
   6409     case NASM_ERR_UNKNOWN_OP:
   6410       as_bad (_("Unrecognized opcode, %s."), str);
   6411       return;
   6412     case NASM_ERR_SYNTAX:
   6413       as_bad (_("Incorrect syntax, %s."), str);
   6414       return;
   6415     case NASM_ERR_OPERAND:
   6416       as_bad (_("Unrecognized operand/register, %s."), str);
   6417       return;
   6418     case NASM_ERR_OUT_OF_RANGE:
   6419       as_bad (_("Operand out of range, %s."), str);
   6420       return;
   6421     case NASM_ERR_REG_REDUCED:
   6422       as_bad (_("Prohibited register used for reduced-register, %s."), str);
   6423       return;
   6424     case NASM_ERR_JUNK_EOL:
   6425       as_bad (_("Junk at end of line, %s."), str);
   6426       return;
   6427     }
   6428 
   6429   gas_assert (insn.opcode);
   6430 
   6431   nds32_set_elf_flags_by_insn (&insn);
   6432 
   6433   gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
   6434 
   6435   if (!nds32_check_insn_available (insn, str))
   6436     return;
   6437 
   6438   /* Make sure the beginning of text being 2-byte align.  */
   6439   nds32_adjust_label (1);
   6440   add_mapping_symbol (MAP_CODE, 0, 0);
   6441   fld = insn.field;
   6442   /* Try to allocate the max size to guarantee relaxable same branch
   6443      instructions in the same fragment.  */
   6444   frag_grow (NDS32_MAXCHAR);
   6445   fragP = frag_now;
   6446 
   6447   if (fld && (insn.attr & NASM_ATTR_BRANCH)
   6448       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
   6449 			    && insn.opcode->value != INSN_J))
   6450       && (!verbatim || pseudo_opcode))
   6451     {
   6452       /* User assembly code branch relax for it.  */
   6453       /* If fld is not NULL, it is a symbol.  */
   6454       /* Branch must relax to proper pattern in user assembly code exclude
   6455 	 J and JAL.  Keep these two in original type for users which wants
   6456 	 to keep their size be fixed.  In general, assembler does not convert
   6457 	 instruction generated by compiler.  But jump instruction may be
   6458 	 truncated in text virtual model.  For workaround, compiler generate
   6459 	 pseudo jump to fix this issue currently.  */
   6460 
   6461       /* Get branch range type.  */
   6462       dwarf2_emit_insn (0);
   6463       enum nds32_br_range range_type;
   6464       expressionS *pexp = insn.info;
   6465 
   6466       range_type = get_range_type (fld);
   6467 
   6468       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
   6469 		      0, /* VAR is un-used.  */
   6470 		      range_type, /* SUBTYPE is used as range type.  */
   6471 		      pexp->X_add_symbol, pexp->X_add_number, 0);
   6472 
   6473       fragP->fr_fix += insn.opcode->isize;
   6474       fragP->tc_frag_data.opcode = insn.opcode;
   6475       fragP->tc_frag_data.insn = insn.insn;
   6476       if (insn.opcode->isize == 4)
   6477 	bfd_putb32 (insn.insn, out);
   6478       else if (insn.opcode->isize == 2)
   6479 	bfd_putb16 (insn.insn, out);
   6480       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
   6481 
   6482       free (insn.info);
   6483       return;
   6484       /* md_convert_frag will insert relocations.  */
   6485     }
   6486   else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
   6487 	   && ((!fld && !verbatim && insn.opcode->isize == 4
   6488 		&& nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
   6489 	       || (insn.opcode->isize == 2
   6490 		   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
   6491     {
   6492       /* Record this one is relaxable.  */
   6493       expressionS *pexp = insn.info;
   6494       dwarf2_emit_insn (0);
   6495       if (fld)
   6496 	{
   6497 	  out = frag_var (rs_machine_dependent,
   6498 			  4, /* Max size is 32-bit instruction.  */
   6499 			  0, /* VAR is un-used.  */
   6500 			  0, pexp->X_add_symbol, pexp->X_add_number, 0);
   6501 	  fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
   6502 	}
   6503       else
   6504 	out = frag_var (rs_machine_dependent,
   6505 			4, /* Max size is 32-bit instruction.  */
   6506 			0, /* VAR is un-used.  */
   6507 			0, NULL, 0, NULL);
   6508       fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
   6509       fragP->tc_frag_data.opcode = insn.opcode;
   6510       fragP->tc_frag_data.insn = insn.insn;
   6511       fragP->fr_fix += 2;
   6512 
   6513       /* In original, we don't relax the instruction with label on it,
   6514 	 but this may cause some redundant nop16.  Therefore, tag this
   6515 	 relaxable instruction and relax it carefully.  */
   6516       if (label)
   6517 	fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
   6518 
   6519       if (insn.opcode->isize == 4)
   6520 	bfd_putb16 (insn_16, out);
   6521       else if (insn.opcode->isize == 2)
   6522 	bfd_putb16 (insn.insn, out);
   6523 
   6524       free (insn.info);
   6525       return;
   6526     }
   6527   else if ((verbatim || !relaxing) && optimize && label)
   6528     {
   6529       /* This instruction is with label.  */
   6530       expressionS exp;
   6531       out = frag_var (rs_machine_dependent, insn.opcode->isize,
   6532 		      0, 0, NULL, 0, NULL);
   6533       /* If this instruction is branch target, it is not relaxable.  */
   6534       fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   6535       fragP->tc_frag_data.opcode = insn.opcode;
   6536       fragP->tc_frag_data.insn = insn.insn;
   6537       fragP->fr_fix += insn.opcode->isize;
   6538       if (insn.opcode->isize == 4)
   6539 	{
   6540 	  exp.X_op = O_symbol;
   6541 	  exp.X_add_symbol = abs_section_sym;
   6542 	  exp.X_add_number = 0;
   6543 	  fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
   6544 			      0, BFD_RELOC_NDS32_LABEL);
   6545 	  if (!verbatim)
   6546 	    fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
   6547 	}
   6548     }
   6549   else
   6550     out = frag_more (insn.opcode->isize);
   6551 
   6552   if (insn.opcode->isize == 4)
   6553     bfd_putb32 (insn.insn, out);
   6554   else if (insn.opcode->isize == 2)
   6555     bfd_putb16 (insn.insn, out);
   6556 
   6557   dwarf2_emit_insn (insn.opcode->isize);
   6558 
   6559   /* Compiler generating code and user assembly pseudo load-store, insert
   6560      fixup here.  */
   6561   expressionS *pexp = insn.info;
   6562   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   6563   /* Build relaxation pattern when relaxing is enable.  */
   6564   if (relaxing)
   6565     nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
   6566 				    pseudo_hint);
   6567 
   6568   free (insn.info);
   6569 }
   6570 
   6571 /* md_macro_start  */
   6572 
   6573 void
   6574 nds32_macro_start (void)
   6575 {
   6576 }
   6577 
   6578 /* md_macro_info  */
   6579 
   6580 void
   6581 nds32_macro_info (void *info ATTRIBUTE_UNUSED)
   6582 {
   6583 }
   6584 
   6585 /* md_macro_end  */
   6586 
   6587 void
   6588 nds32_macro_end (void)
   6589 {
   6590 }
   6591 
   6592 /* GAS will call this function with one argument, an expressionS pointer, for
   6593    any expression that can not be recognized.  When the function is called,
   6594    input_line_pointer will point to the start of the expression.  */
   6595 
   6596 void
   6597 md_operand (expressionS *expressionP)
   6598 {
   6599   if (*input_line_pointer == '#')
   6600     {
   6601       input_line_pointer++;
   6602       expression (expressionP);
   6603     }
   6604 }
   6605 
   6606 /* GAS will call this function for each section at the end of the assembly, to
   6607    permit the CPU back end to adjust the alignment of a section.  The function
   6608    must take two arguments, a segT for the section and a valueT for the size of
   6609    the section, and return a valueT for the rounded size.  */
   6610 
   6611 valueT
   6612 md_section_align (segT segment, valueT size)
   6613 {
   6614   int align = bfd_section_alignment (segment);
   6615 
   6616   return (size + ((valueT) 1 << align) - 1) & -((valueT) 1 << align);
   6617 }
   6618 
   6619 /* GAS will call this function when a symbol table lookup fails, before it
   6620    creates a new symbol.  Typically this would be used to supply symbols whose
   6621    name or value changes dynamically, possibly in a context sensitive way.
   6622    Predefined symbols with fixed values, such as register names or condition
   6623    codes, are typically entered directly into the symbol table when md_begin
   6624    is called.  One argument is passed, a char * for the symbol.  */
   6625 
   6626 symbolS *
   6627 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   6628 {
   6629   return NULL;
   6630 }
   6631 
   6632 static long
   6633 nds32_calc_branch_offset (segT segment, fragS *fragP,
   6634 			  long stretch ATTRIBUTE_UNUSED,
   6635 			  relax_info_t *relax_info,
   6636 			  enum nds32_br_range branch_range_type)
   6637 {
   6638   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   6639   symbolS *branch_symbol = fragP->fr_symbol;
   6640   offsetT branch_offset = fragP->fr_offset;
   6641   offsetT branch_target_address;
   6642   offsetT branch_insn_address;
   6643   long offset = 0;
   6644 
   6645   if ((S_GET_SEGMENT (branch_symbol) != segment)
   6646       || S_IS_WEAK (branch_symbol))
   6647     {
   6648       /* The symbol is not in the SEGMENT.  It could be far far away.  */
   6649       offset = 0x80000000;
   6650     }
   6651   else
   6652     {
   6653       /* Calculate symbol-to-instruction offset.  */
   6654       branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   6655       /* If the destination symbol is beyond current frag address,
   6656 	 STRETCH will take effect to symbol's position.  */
   6657       if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
   6658 	branch_target_address += stretch;
   6659 
   6660       branch_insn_address = fragP->fr_address + fragP->fr_fix;
   6661       branch_insn_address -= opcode->isize;
   6662 
   6663       /* Update BRANCH_INSN_ADDRESS to relaxed position.  */
   6664       branch_insn_address += (relax_info->relax_code_size[branch_range_type]
   6665 			      - relax_info->relax_branch_isize[branch_range_type]);
   6666 
   6667       offset = branch_target_address - branch_insn_address;
   6668     }
   6669 
   6670   return offset;
   6671 }
   6672 
   6673 static enum nds32_br_range
   6674 nds32_convert_to_range_type (long offset)
   6675 {
   6676   enum nds32_br_range range_type;
   6677 
   6678   if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
   6679     range_type = BR_RANGE_S256;
   6680   else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
   6681     range_type = BR_RANGE_S16K;
   6682   else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
   6683     range_type = BR_RANGE_S64K;
   6684   else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
   6685     range_type = BR_RANGE_S16M;
   6686   else /* 4G bytes */
   6687     range_type = BR_RANGE_U4G;
   6688 
   6689   return range_type;
   6690 }
   6691 
   6692 /* Set instruction register mask.  */
   6693 
   6694 static void
   6695 nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
   6696 			uint32_t ori_insn, int range)
   6697 {
   6698   nds32_cond_field_t *cond_fields = relax_info->cond_field;
   6699   nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
   6700   uint32_t mask;
   6701   int i = 0;
   6702 
   6703   /* The instruction has conditions.  Collect condition values.  */
   6704   while (code_seq_cond[i].bitmask != 0)
   6705     {
   6706       if (offset == code_seq_cond[i].offset)
   6707 	{
   6708 	  mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
   6709 	  /* Sign extend.  */
   6710 	  if (cond_fields[i].signed_extend)
   6711 	    mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
   6712 	      ((cond_fields[i].bitmask + 1) >> 1);
   6713 	  *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
   6714 	}
   6715       i++;
   6716     }
   6717 }
   6718 
   6719 static int
   6720 nds32_relax_branch_instructions (segT segment, fragS *fragP,
   6721 				 long stretch ATTRIBUTE_UNUSED,
   6722 				 int init)
   6723 {
   6724   enum nds32_br_range branch_range_type;
   6725   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   6726   long offset = 0;
   6727   enum nds32_br_range real_range_type;
   6728   int adjust = 0;
   6729   relax_info_t *relax_info;
   6730   int diff = 0;
   6731   int i, j, k;
   6732   int code_seq_size;
   6733   uint32_t *code_seq;
   6734   uint32_t insn;
   6735   int insn_size;
   6736   int code_seq_offset;
   6737 
   6738   /* Replace with gas_assert (fragP->fr_symbol != NULL); */
   6739   if (fragP->fr_symbol == NULL)
   6740     return adjust;
   6741 
   6742   /* If frag_var is not enough room, the previous frag is fr_full and with
   6743      opcode.  The new one is rs_dependent but without opcode.  */
   6744   if (opcode == NULL)
   6745     return adjust;
   6746 
   6747   /* Use U4G mode for b and bal in verbatim mode because lto may combine
   6748      functions into a file.  And order the file in the last when linking.
   6749      Once there is multiple definition, the same function will be kicked.
   6750      This may cause relocation truncated error.  */
   6751   if (verbatim && !nds32_pic
   6752       && (strcmp (opcode->opcode, "j") == 0
   6753 	  || strcmp (opcode->opcode, "jal") == 0))
   6754     {
   6755       fragP->fr_subtype = BR_RANGE_U4G;
   6756       if (init)
   6757 	return 8;
   6758       else
   6759 	return 0;
   6760     }
   6761 
   6762   relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   6763 
   6764   if (relax_info == NULL)
   6765     return adjust;
   6766 
   6767   if (init)
   6768     {
   6769       branch_range_type = relax_info->br_range;
   6770       i = BR_RANGE_S256;
   6771     }
   6772   else
   6773     {
   6774       branch_range_type = fragP->fr_subtype;
   6775       i = branch_range_type;
   6776     }
   6777 
   6778   offset = nds32_calc_branch_offset (segment, fragP, stretch,
   6779 				     relax_info, branch_range_type);
   6780 
   6781   real_range_type = nds32_convert_to_range_type (offset);
   6782 
   6783   /* If actual range is equal to instruction jump range, do nothing.  */
   6784   if (real_range_type == branch_range_type)
   6785     {
   6786       fragP->fr_subtype = real_range_type;
   6787       return adjust;
   6788     }
   6789 
   6790   /* Find out proper relaxation code sequence.  */
   6791   for (; i < BR_RANGE_NUM; i++)
   6792     {
   6793       if (real_range_type <= (unsigned int) i)
   6794 	{
   6795 	  if (init)
   6796 	    diff = relax_info->relax_code_size[i] - opcode->isize;
   6797 	  else if (real_range_type < (unsigned int) i)
   6798 	    diff = relax_info->relax_code_size[real_range_type]
   6799 	      - relax_info->relax_code_size[branch_range_type];
   6800 	  else
   6801 	    diff = relax_info->relax_code_size[i]
   6802 	      - relax_info->relax_code_size[branch_range_type];
   6803 
   6804 	  /* If the instruction could be converted to 16-bits,
   6805 	     minus the difference.  */
   6806 	  code_seq_offset = 0;
   6807 	  j = 0;
   6808 	  k = 0;
   6809 	  code_seq_size = relax_info->relax_code_size[i];
   6810 	  code_seq = relax_info->relax_code_seq[i];
   6811 	  while (code_seq_offset < code_seq_size)
   6812 	    {
   6813 	      insn = code_seq[j];
   6814 	      if (insn & 0x80000000) /* 16-bits instruction.  */
   6815 		{
   6816 		  insn_size = 2;
   6817 		}
   6818 	      else /* 32-bits instruction.  */
   6819 		{
   6820 		  insn_size = 4;
   6821 
   6822 		  while (relax_info->relax_fixup[i][k].size !=0
   6823 			 && relax_info->relax_fixup[i][k].offset < code_seq_offset)
   6824 		    k++;
   6825 		}
   6826 
   6827 	      code_seq_offset += insn_size;
   6828 	      j++;
   6829 	    }
   6830 
   6831 	  /* Update fr_subtype to new NDS32_BR_RANGE.  */
   6832 	  fragP->fr_subtype = real_range_type;
   6833 	  break;
   6834 	}
   6835     }
   6836 
   6837   return diff + adjust;
   6838 }
   6839 
   6840 /* Adjust relaxable frag till current frag.  */
   6841 
   6842 static int
   6843 nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
   6844 {
   6845   int adj;
   6846   if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   6847     adj = -2;
   6848   else
   6849     adj = 2;
   6850 
   6851   startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
   6852 
   6853   while (startP)
   6854     {
   6855       startP = startP->fr_next;
   6856       if (startP)
   6857 	{
   6858 	  startP->fr_address += adj;
   6859 	  if (startP == fragP)
   6860 	    break;
   6861 	}
   6862     }
   6863   return adj;
   6864 }
   6865 
   6866 static addressT
   6867 nds32_get_align (addressT address, int align)
   6868 {
   6869   addressT mask, new_address;
   6870 
   6871   mask = ~((addressT) (~0) << align);
   6872   new_address = (address + mask) & (~mask);
   6873   return (new_address - address);
   6874 }
   6875 
   6876 /* Check the prev_frag is legal.  */
   6877 static void
   6878 invalid_prev_frag (fragS * fragP, fragS **prev_frag, bool relax)
   6879 {
   6880   addressT address;
   6881   fragS *frag_start = *prev_frag;
   6882 
   6883   if (!frag_start || !relax)
   6884     return;
   6885 
   6886   if (frag_start->last_fr_address >= fragP->last_fr_address)
   6887     {
   6888       *prev_frag = NULL;
   6889       return;
   6890     }
   6891 
   6892   fragS *frag_t = *prev_frag;
   6893   while (frag_t != fragP)
   6894     {
   6895       if (frag_t->fr_type == rs_align
   6896 	  || frag_t->fr_type == rs_align_code
   6897 	  || frag_t->fr_type == rs_align_test)
   6898 	{
   6899 	  /* Relax instruction can not walk across label.  */
   6900 	  if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6901 	    {
   6902 	      prev_frag = NULL;
   6903 	      return;
   6904 	    }
   6905 	  /* Relax previous relaxable to align rs_align frag.  */
   6906 	  address = frag_t->fr_address + frag_t->fr_fix;
   6907 	  addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
   6908 	  if (offset & 0x2)
   6909 	    {
   6910 	      /* If there is label on the prev_frag, check if it is aligned.  */
   6911 	      if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6912 		  || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   6913 		      & 0x2) == 0)
   6914 		nds32_adjust_relaxable_frag (*prev_frag, frag_t);
   6915 	    }
   6916 	  *prev_frag = NULL;
   6917 	  return;
   6918 	}
   6919       frag_t = frag_t->fr_next;
   6920     }
   6921 
   6922   if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
   6923     {
   6924       address = fragP->fr_address;
   6925       addressT offset = nds32_get_align (address, 2);
   6926       if (offset & 0x2)
   6927 	{
   6928 	  /* If there is label on the prev_frag, check if it is aligned.  */
   6929 	  if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6930 	      || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   6931 		  & 0x2) == 0)
   6932 	    nds32_adjust_relaxable_frag (*prev_frag, fragP);
   6933 	}
   6934       *prev_frag = NULL;
   6935       return;
   6936     }
   6937 }
   6938 
   6939 /* md_relax_frag  */
   6940 
   6941 int
   6942 nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   6943 {
   6944   /* Currently, there are two kinds of relaxation in nds32 assembler.
   6945      1. relax for branch
   6946      2. relax for 32-bits to 16-bits  */
   6947 
   6948   static fragS *prev_frag = NULL;
   6949   int adjust = 0;
   6950 
   6951   invalid_prev_frag (fragP, &prev_frag, true);
   6952 
   6953   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   6954     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
   6955   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6956     prev_frag = NULL;
   6957   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
   6958       && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
   6959     /* Here is considered relaxed case originally.  But it may cause
   6960        an endless loop when relaxing.  Once the instruction is relaxed,
   6961        it can not be undone.  */
   6962     prev_frag = fragP;
   6963 
   6964   return adjust;
   6965 }
   6966 
   6967 /* This function returns an initial guess of the length by which a fragment
   6968    must grow to hold a branch to reach its destination.  Also updates
   6969    fr_type/fr_subtype as necessary.
   6970 
   6971    It is called just before doing relaxation.  Any symbol that is now undefined
   6972    will not become defined.  The guess for fr_var is ACTUALLY the growth beyond
   6973    fr_fix.  Whatever we do to grow fr_fix or fr_var contributes to our returned
   6974    value.  Although it may not be explicit in the frag, pretend fr_var starts
   6975    with a 0 value.  */
   6976 
   6977 int
   6978 md_estimate_size_before_relax (fragS *fragP, segT segment)
   6979 {
   6980   /* Currently, there are two kinds of relaxation in nds32 assembler.
   6981      1. relax for branch
   6982      2. relax for 32-bits to 16-bits  */
   6983 
   6984   /* Save previous relaxable frag.  */
   6985   static fragS *prev_frag = NULL;
   6986   int adjust = 0;
   6987 
   6988   invalid_prev_frag (fragP, &prev_frag, false);
   6989 
   6990   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   6991     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
   6992   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6993     prev_frag = NULL;
   6994   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   6995     adjust = 2;
   6996   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
   6997     prev_frag = fragP;
   6998 
   6999   return adjust;
   7000 }
   7001 
   7002 /* GAS will call this for each rs_machine_dependent fragment.  The instruction
   7003    is completed using the data from the relaxation pass.  It may also create any
   7004    necessary relocations.
   7005 
   7006    *FRAGP has been relaxed to its final size, and now needs to have the bytes
   7007    inside it modified to conform to the new size.  It is called after relaxation
   7008    is finished.
   7009 
   7010    fragP->fr_type == rs_machine_dependent.
   7011    fragP->fr_subtype is the subtype of what the address relaxed to.  */
   7012 
   7013 void
   7014 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
   7015 {
   7016   /* Convert branch relaxation instructions.  */
   7017   symbolS *branch_symbol = fragP->fr_symbol;
   7018   offsetT branch_offset = fragP->fr_offset;
   7019   enum nds32_br_range branch_range_type = fragP->fr_subtype;
   7020   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   7021   uint32_t origin_insn = fragP->tc_frag_data.insn;
   7022   relax_info_t *relax_info;
   7023   char *fr_buffer;
   7024   int fr_where;
   7025   int addend ATTRIBUTE_UNUSED;
   7026   offsetT branch_target_address, branch_insn_address;
   7027   expressionS exp;
   7028   fixS *fixP;
   7029   uint32_t *code_seq;
   7030   uint32_t insn;
   7031   int code_size, insn_size, offset, fixup_size;
   7032   int buf_offset, pcrel;
   7033   int i, k;
   7034   uint16_t insn_16;
   7035   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
   7036   /* Save the 1st instruction is converted to 16 bit or not.  */
   7037   unsigned int branch_size;
   7038   enum bfd_reloc_code_real final_r_type;
   7039 
   7040   /* Replace with gas_assert (branch_symbol != NULL); */
   7041   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
   7042     return;
   7043 
   7044   /* If frag_var is not enough room, the previous frag is fr_full and with
   7045      opcode.  The new one is rs_dependent but without opcode.  */
   7046   if (opcode == NULL)
   7047     return;
   7048 
   7049   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
   7050     {
   7051       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   7052 
   7053       if (relax_info == NULL)
   7054 	return;
   7055 
   7056       i = BR_RANGE_S256;
   7057       while (i < BR_RANGE_NUM
   7058 	     && relax_info->relax_code_size[i]
   7059 	     != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
   7060 	i++;
   7061 
   7062       if (i >= BR_RANGE_NUM)
   7063 	as_bad ("Internal error: Cannot find relocation of"
   7064 		"relaxable branch.");
   7065 
   7066       exp.X_op = O_symbol;
   7067       exp.X_add_symbol = branch_symbol;
   7068       exp.X_add_number = branch_offset;
   7069       pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   7070       fr_where = fragP->fr_fix - 2;
   7071       fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
   7072 			  &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
   7073       fixP->fx_addnumber = fixP->fx_offset;
   7074 
   7075       if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   7076 	{
   7077 	  insn_16 = fragP->tc_frag_data.insn;
   7078 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   7079 	  fr_buffer = fragP->fr_literal + fr_where;
   7080 	  fragP->fr_fix += 2;
   7081 	  exp.X_op = O_symbol;
   7082 	  exp.X_add_symbol = abs_section_sym;
   7083 	  exp.X_add_number = 0;
   7084 	  fix_new_exp (fragP, fr_where, 4,
   7085 		       &exp, 0, BFD_RELOC_NDS32_INSN16);
   7086 	  number_to_chars_bigendian (fr_buffer, insn, 4);
   7087 	}
   7088     }
   7089   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   7090     {
   7091       if (fragP->tc_frag_data.opcode->isize == 2)
   7092 	{
   7093 	  insn_16 = fragP->tc_frag_data.insn;
   7094 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   7095 	}
   7096       else
   7097 	insn = fragP->tc_frag_data.insn;
   7098       fragP->fr_fix += 2;
   7099       fr_where = fragP->fr_fix - 4;
   7100       fr_buffer = fragP->fr_literal + fr_where;
   7101       exp.X_op = O_symbol;
   7102       exp.X_add_symbol = abs_section_sym;
   7103       exp.X_add_number = 0;
   7104       fix_new_exp (fragP, fr_where, 4, &exp, 0,
   7105 		   BFD_RELOC_NDS32_INSN16);
   7106       number_to_chars_bigendian (fr_buffer, insn, 4);
   7107     }
   7108   else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   7109     {
   7110       /* Branch instruction adjust and append relocations.  */
   7111       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   7112 
   7113       if (relax_info == NULL)
   7114 	return;
   7115 
   7116       fr_where = fragP->fr_fix - opcode->isize;
   7117       fr_buffer = fragP->fr_literal + fr_where;
   7118 
   7119       if ((S_GET_SEGMENT (branch_symbol) != sec)
   7120 	  || S_IS_WEAK (branch_symbol))
   7121 	{
   7122 	  if (fragP->fr_offset & 3)
   7123 	    as_warn (_("Addend to unresolved symbol is not on word boundary."));
   7124 	  addend = 0;
   7125 	}
   7126       else
   7127 	{
   7128 	  /* Calculate symbol-to-instruction offset.  */
   7129 	  branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   7130 	  branch_insn_address = fragP->fr_address + fr_where;
   7131 	  addend = (branch_target_address - branch_insn_address) >> 1;
   7132 	}
   7133 
   7134       code_size = relax_info->relax_code_size[branch_range_type];
   7135       code_seq = relax_info->relax_code_seq[branch_range_type];
   7136 
   7137       memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
   7138 	      sizeof (fixup_info));
   7139 
   7140       /* Fill in frag.  */
   7141       i = 0;
   7142       k = 0;
   7143       offset = 0; /* code_seq offset */
   7144       buf_offset = 0; /* fr_buffer offset */
   7145       while (offset < code_size)
   7146 	{
   7147 	  insn = code_seq[i];
   7148 	  if (insn & 0x80000000) /* 16-bits instruction.  */
   7149 	    {
   7150 	      insn = (insn >> 16) & 0xFFFF;
   7151 	      insn_size = 2;
   7152 	    }
   7153 	  else /* 32-bits instruction.  */
   7154 	    {
   7155 	      insn_size = 4;
   7156 	    }
   7157 
   7158 	  nds32_elf_get_set_cond (relax_info, offset, &insn,
   7159 				  origin_insn, branch_range_type);
   7160 
   7161 	  /* Try to convert to 16-bits instruction.  Currently, only the first
   7162 	     instruction in pattern can be converted.  EX: bnez sethi ori jr,
   7163 	     only bnez can be converted to 16 bit and ori can't.  */
   7164 
   7165 	  while (fixup_info[k].size != 0
   7166 		 && relax_info->relax_fixup[branch_range_type][k].offset < offset)
   7167 	    k++;
   7168 
   7169 	  number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
   7170 	  buf_offset += insn_size;
   7171 
   7172 	  offset += insn_size;
   7173 	  i++;
   7174 	}
   7175 
   7176       /* Set up fixup.  */
   7177       exp.X_op = O_symbol;
   7178 
   7179       for (i = 0; fixup_info[i].size != 0; i++)
   7180 	{
   7181 	  fixup_size = fixup_info[i].size;
   7182 	  pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   7183 
   7184 	  if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
   7185 	    {
   7186 	      /* This is a reverse branch.  */
   7187 	      exp.X_add_symbol = symbol_temp_new (sec, fragP->fr_next, 0);
   7188 	      exp.X_add_number = 0;
   7189 	    }
   7190 	  else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
   7191 	    {
   7192 	      /* This relocation has to point to another instruction.  */
   7193 	      branch_size = fr_where + code_size - 4;
   7194 	      exp.X_add_symbol = symbol_temp_new (sec, fragP, branch_size);
   7195 	      exp.X_add_number = 0;
   7196 	    }
   7197 	  else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
   7198 	    {
   7199 	      /* This is a tag relocation.  */
   7200 	      exp.X_add_symbol = abs_section_sym;
   7201 	      exp.X_add_number = 0;
   7202 	    }
   7203 	  else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
   7204 	    {
   7205 	      if (!enable_16bit)
   7206 		continue;
   7207 	      /* This is a tag relocation.  */
   7208 	      exp.X_add_symbol = abs_section_sym;
   7209 	      exp.X_add_number = 0;
   7210 	    }
   7211 	  else
   7212 	    {
   7213 	      exp.X_add_symbol = branch_symbol;
   7214 	      exp.X_add_number = branch_offset;
   7215 	    }
   7216 
   7217 	  if (fixup_info[i].r_type != 0)
   7218 	    {
   7219 	      final_r_type = fixup_info[i].r_type;
   7220 	      fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
   7221 				  fixup_size, &exp, pcrel,
   7222 				  final_r_type);
   7223 	      fixP->fx_addnumber = fixP->fx_offset;
   7224 	    }
   7225 	}
   7226 
   7227       fragP->fr_fix = fr_where + buf_offset;
   7228     }
   7229 }
   7230 
   7231 /* tc_frob_file_before_fix  */
   7232 
   7233 void
   7234 nds32_frob_file_before_fix (void)
   7235 {
   7236 }
   7237 
   7238 static bool
   7239 nds32_relaxable_section (asection *sec)
   7240 {
   7241   return ((sec->flags & SEC_DEBUGGING) == 0
   7242 	  && strcmp (sec->name, ".eh_frame") != 0);
   7243 }
   7244 
   7245 /* TC_FORCE_RELOCATION */
   7246 int
   7247 nds32_force_relocation (fixS * fix)
   7248 {
   7249   switch (fix->fx_r_type)
   7250     {
   7251     case BFD_RELOC_NDS32_INSN16:
   7252     case BFD_RELOC_NDS32_LABEL:
   7253     case BFD_RELOC_NDS32_LONGCALL1:
   7254     case BFD_RELOC_NDS32_LONGCALL2:
   7255     case BFD_RELOC_NDS32_LONGCALL3:
   7256     case BFD_RELOC_NDS32_LONGJUMP1:
   7257     case BFD_RELOC_NDS32_LONGJUMP2:
   7258     case BFD_RELOC_NDS32_LONGJUMP3:
   7259     case BFD_RELOC_NDS32_LOADSTORE:
   7260     case BFD_RELOC_NDS32_9_FIXED:
   7261     case BFD_RELOC_NDS32_15_FIXED:
   7262     case BFD_RELOC_NDS32_17_FIXED:
   7263     case BFD_RELOC_NDS32_25_FIXED:
   7264     case BFD_RELOC_NDS32_9_PCREL:
   7265     case BFD_RELOC_NDS32_15_PCREL:
   7266     case BFD_RELOC_NDS32_17_PCREL:
   7267     case BFD_RELOC_NDS32_WORD_9_PCREL:
   7268     case BFD_RELOC_NDS32_10_UPCREL:
   7269     case BFD_RELOC_NDS32_25_PCREL:
   7270     case BFD_RELOC_NDS32_MINUEND:
   7271     case BFD_RELOC_NDS32_SUBTRAHEND:
   7272       return 1;
   7273 
   7274     case BFD_RELOC_8:
   7275     case BFD_RELOC_16:
   7276     case BFD_RELOC_32:
   7277     case BFD_RELOC_NDS32_DIFF_ULEB128:
   7278       /* Linker should handle difference between two symbol.  */
   7279       return fix->fx_subsy != NULL
   7280 	&& nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
   7281     case BFD_RELOC_64:
   7282       if (fix->fx_subsy)
   7283 	as_bad ("Double word for difference between two symbols "
   7284 		"is not supported across relaxation.");
   7285     default:
   7286       ;
   7287     }
   7288 
   7289   if (generic_force_reloc (fix))
   7290     return 1;
   7291 
   7292   return fix->fx_pcrel;
   7293 }
   7294 
   7295 /* TC_VALIDATE_FIX_SUB  */
   7296 
   7297 int
   7298 nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
   7299 {
   7300   segT sub_symbol_segment;
   7301 
   7302   /* This code is referred from Xtensa.  Check their implementation for
   7303      details.  */
   7304 
   7305   /* Make sure both symbols are in the same segment, and that segment is
   7306      "normal" and relaxable.  */
   7307   sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
   7308   return (sub_symbol_segment == add_symbol_segment
   7309 	  && add_symbol_segment != undefined_section);
   7310 }
   7311 
   7312 void
   7313 md_number_to_chars (char *buf, valueT val, int n)
   7314 {
   7315   if (target_big_endian)
   7316     number_to_chars_bigendian (buf, val, n);
   7317   else
   7318     number_to_chars_littleendian (buf, val, n);
   7319 }
   7320 
   7321 /* This function is called to convert an ASCII string into a floating point
   7322    value in format used by the CPU.  */
   7323 
   7324 const char *
   7325 md_atof (int type, char *litP, int *sizeP)
   7326 {
   7327   int i;
   7328   int prec;
   7329   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   7330   char *t;
   7331 
   7332   switch (type)
   7333     {
   7334     case 'f':
   7335     case 'F':
   7336     case 's':
   7337     case 'S':
   7338       prec = 2;
   7339       break;
   7340     case 'd':
   7341     case 'D':
   7342     case 'r':
   7343     case 'R':
   7344       prec = 4;
   7345       break;
   7346     default:
   7347       *sizeP = 0;
   7348       return _("Bad call to md_atof()");
   7349     }
   7350 
   7351   t = atof_ieee (input_line_pointer, type, words);
   7352   if (t)
   7353     input_line_pointer = t;
   7354   *sizeP = prec * sizeof (LITTLENUM_TYPE);
   7355 
   7356   if (target_big_endian)
   7357     {
   7358       for (i = 0; i < prec; i++)
   7359 	{
   7360 	  md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
   7361 	  litP += sizeof (LITTLENUM_TYPE);
   7362 	}
   7363     }
   7364   else
   7365     {
   7366       for (i = prec - 1; i >= 0; i--)
   7367 	{
   7368 	  md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
   7369 	  litP += sizeof (LITTLENUM_TYPE);
   7370 	}
   7371     }
   7372 
   7373   return 0;
   7374 }
   7375 
   7376 /* md_elf_section_change_hook  */
   7377 
   7378 void
   7379 nds32_elf_section_change_hook (void)
   7380 {
   7381 }
   7382 
   7383 /* md_cleanup  */
   7384 
   7385 void
   7386 nds32_cleanup (void)
   7387 {
   7388 }
   7389 
   7390 /* This function is used to scan leb128 subtraction expressions,
   7391    and insert fixups for them.
   7392 
   7393       e.g., .leb128  .L1 - .L0
   7394 
   7395    These expressions are heavily used in debug information or
   7396    exception tables.  Because relaxation will change code size,
   7397    we must resolve them in link time.  */
   7398 
   7399 static void
   7400 nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
   7401 			   asection *sec, void *xxx ATTRIBUTE_UNUSED)
   7402 {
   7403   segment_info_type *seginfo = seg_info (sec);
   7404   struct frag *fragP;
   7405 
   7406   subseg_set (sec, 0);
   7407 
   7408   for (fragP = seginfo->frchainP->frch_root;
   7409        fragP; fragP = fragP->fr_next)
   7410     {
   7411       expressionS *exp;
   7412 
   7413       /* Only unsigned leb128 can be handle.  */
   7414       if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
   7415 	  || fragP->fr_symbol == NULL)
   7416 	continue;
   7417 
   7418       exp = symbol_get_value_expression (fragP->fr_symbol);
   7419 
   7420       if (exp->X_op != O_subtract)
   7421 	continue;
   7422 
   7423       fix_new_exp (fragP, fragP->fr_fix, 0,
   7424 		   exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
   7425     }
   7426 }
   7427 
   7428 static void
   7429 nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   7430 			  void *xxx ATTRIBUTE_UNUSED)
   7431 {
   7432   segment_info_type *seginfo;
   7433   fragS *fragP;
   7434   fixS *fixP;
   7435   expressionS exp;
   7436   fixS *fixp;
   7437 
   7438   seginfo = seg_info (sec);
   7439   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
   7440     return;
   7441 
   7442   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
   7443     if (!fixp->fx_done)
   7444       break;
   7445 
   7446   if (!fixp && !verbatim && ict_flag == ICT_NONE)
   7447     return;
   7448 
   7449   subseg_change (sec, 0);
   7450 
   7451   /* Set RELAX_ENTRY flags for linker.  */
   7452   fragP = seginfo->frchainP->frch_root;
   7453   exp.X_op = O_symbol;
   7454   exp.X_add_symbol = abs_section_sym;
   7455   exp.X_add_number = 0;
   7456   if (!enable_relax_relocs)
   7457     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
   7458   else
   7459     {
   7460       /* These flags are only enabled when global relax is enabled.
   7461 	 Maybe we can check DISABLE_RELAX_FLAG at link-time,
   7462 	 so we set them anyway.  */
   7463       if (verbatim)
   7464 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
   7465       if (ict_flag == ICT_SMALL)
   7466 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL;
   7467       else if (ict_flag == ICT_LARGE)
   7468 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE;
   7469     }
   7470   if (optimize)
   7471     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
   7472   if (optimize_for_space)
   7473     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
   7474 
   7475   fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
   7476   fixP->fx_no_overflow = 1;
   7477 }
   7478 
   7479 /* Analysis relax hint and insert suitable relocation pattern.  */
   7480 
   7481 static void
   7482 nds32_elf_analysis_relax_hint (void)
   7483 {
   7484   htab_traverse_noresize (nds32_hint_hash,
   7485 			  nds32_elf_append_relax_relocs_traverse, NULL);
   7486 }
   7487 
   7488 static void
   7489 nds32_elf_insert_final_frag (void)
   7490 {
   7491   struct frchain *frchainP;
   7492   asection *s;
   7493   fragS *fragP;
   7494 
   7495   if (!optimize)
   7496     return;
   7497 
   7498   for (s = stdoutput->sections; s; s = s->next)
   7499     {
   7500       segment_info_type *seginfo = seg_info (s);
   7501       if (!seginfo)
   7502 	continue;
   7503 
   7504       for (frchainP = seginfo->frchainP; frchainP != NULL;
   7505 	   frchainP = frchainP->frch_next)
   7506 	{
   7507 	  subseg_set (s, frchainP->frch_subseg);
   7508 
   7509 	  if (subseg_text_p (now_seg))
   7510 	    {
   7511 	      fragP = frag_now;
   7512 	      frag_var (rs_machine_dependent, 2, /* Max size.  */
   7513 			0, /* VAR is un-used.  */ 0, NULL, 0, NULL);
   7514 	      fragP->tc_frag_data.flag |= NDS32_FRAG_FINAL;
   7515 	    }
   7516 	}
   7517     }
   7518 }
   7519 
   7520 void
   7521 md_finish (void)
   7522 {
   7523   nds32_elf_insert_final_frag ();
   7524   nds32_elf_analysis_relax_hint ();
   7525   bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
   7526 }
   7527 
   7528 /* Implement md_allow_local_subtract.  */
   7529 
   7530 bool
   7531 nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
   7532 			    expressionS *expr_r ATTRIBUTE_UNUSED,
   7533 			    segT sec ATTRIBUTE_UNUSED)
   7534 {
   7535   /* Don't allow any subtraction, because relax may change the code.  */
   7536   return false;
   7537 }
   7538 
   7539 long
   7540 nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
   7541 {
   7542   if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
   7543       || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
   7544     {
   7545       /* Let linker resolve undefined symbols.  */
   7546       return 0;
   7547     }
   7548 
   7549   return fixP->fx_frag->fr_address + fixP->fx_where;
   7550 }
   7551 
   7552 /* md_post_relax_hook ()
   7553    Insert relax entry relocation into sections.  */
   7554 
   7555 void
   7556 nds32_post_relax_hook (void)
   7557 {
   7558   bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
   7559 }
   7560 
   7561 /* tc_fix_adjustable ()
   7562 
   7563    Return whether this symbol (fixup) can be replaced with
   7564    section symbols.  */
   7565 
   7566 bool
   7567 nds32_fix_adjustable (fixS *fixP)
   7568 {
   7569   switch (fixP->fx_r_type)
   7570     {
   7571     case BFD_RELOC_NDS32_WORD_9_PCREL:
   7572     case BFD_RELOC_NDS32_9_PCREL:
   7573     case BFD_RELOC_NDS32_15_PCREL:
   7574     case BFD_RELOC_NDS32_17_PCREL:
   7575     case BFD_RELOC_NDS32_25_PCREL:
   7576     case BFD_RELOC_NDS32_HI20:
   7577     case BFD_RELOC_NDS32_LO12S0:
   7578     case BFD_RELOC_8:
   7579     case BFD_RELOC_16:
   7580     case BFD_RELOC_32:
   7581     case BFD_RELOC_NDS32_PTR:
   7582     case BFD_RELOC_NDS32_LONGCALL4:
   7583     case BFD_RELOC_NDS32_LONGCALL5:
   7584     case BFD_RELOC_NDS32_LONGCALL6:
   7585     case BFD_RELOC_NDS32_LONGJUMP4:
   7586     case BFD_RELOC_NDS32_LONGJUMP5:
   7587     case BFD_RELOC_NDS32_LONGJUMP6:
   7588     case BFD_RELOC_NDS32_LONGJUMP7:
   7589       return 1;
   7590     default:
   7591       return 0;
   7592     }
   7593 }
   7594 
   7595 /* elf_tc_final_processing  */
   7596 
   7597 void
   7598 elf_nds32_final_processing (void)
   7599 {
   7600   /* An FPU_COM instruction is found without previous non-FPU_COM
   7601      instruction.  */
   7602   if (nds32_fpu_com
   7603       && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   7604     {
   7605       /* Since only FPU_COM instructions are used and no other FPU instructions
   7606 	 are used.  The nds32_elf_flags will be decided by the enabled options
   7607 	 by command line or default configuration.  */
   7608       if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
   7609 	{
   7610 	  nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
   7611 	  nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
   7612 	}
   7613       else
   7614 	{
   7615 	  /* Should never here.  */
   7616 	  as_bad (_("Used FPU instructions requires enabling FPU extension"));
   7617 	}
   7618     }
   7619 
   7620   if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
   7621     {
   7622       /* Single/double FPU has been used, set FPU register config.  */
   7623       /* We did not check the actual number of register used.  We may
   7624 	 want to do it while assemble.  */
   7625       nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
   7626       nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
   7627     }
   7628 
   7629   if (nds32_pic)
   7630     nds32_elf_flags |= E_NDS32_HAS_PIC;
   7631 
   7632   if (nds32_gpr16)
   7633     nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
   7634 
   7635   nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
   7636   elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
   7637 }
   7638 
   7639 /* Implement md_apply_fix.  Apply the fix-up or transform the fix-up for
   7640    later relocation generation.  */
   7641 
   7642 void
   7643 nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   7644 {
   7645   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
   7646   bfd_vma value = *valP;
   7647 
   7648   if (fixP->fx_r_type < BFD_RELOC_UNUSED
   7649       && fixP->fx_r_type > BFD_RELOC_NONE
   7650       && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
   7651     {
   7652       /* In our old nds32 binutils, it must convert relocations which is
   7653 	 generated by CGEN.  However, it does not have to consider this anymore.
   7654 	 In current, it only deal with data relocations which enum
   7655 	 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
   7656 	 It is believed that we can construct a better mechanism to
   7657 	 deal with the whole relocation issue in nds32 target
   7658 	 without using CGEN.  */
   7659       fixP->fx_addnumber = value;
   7660       fixP->tc_fix_data = NULL;
   7661 
   7662       /* Transform specific relocations here for later relocation generation.
   7663 	 Tag tls data for linker.  */
   7664       switch (fixP->fx_r_type)
   7665 	{
   7666 	case BFD_RELOC_NDS32_DATA:
   7667 	  /* This reloc is obselete, we do not need it so far.  */
   7668 	  fixP->fx_done = 1;
   7669 	  break;
   7670 	case BFD_RELOC_NDS32_TPOFF:
   7671 	case BFD_RELOC_NDS32_TLS_LE_HI20:
   7672 	case BFD_RELOC_NDS32_TLS_LE_LO12:
   7673 	case BFD_RELOC_NDS32_TLS_LE_ADD:
   7674 	case BFD_RELOC_NDS32_TLS_LE_LS:
   7675 	case BFD_RELOC_NDS32_GOTTPOFF:
   7676 	case BFD_RELOC_NDS32_TLS_IE_HI20:
   7677 	case BFD_RELOC_NDS32_TLS_IE_LO12S2:
   7678 	case BFD_RELOC_NDS32_TLS_DESC_HI20:
   7679 	case BFD_RELOC_NDS32_TLS_DESC_LO12:
   7680 	case BFD_RELOC_NDS32_TLS_IE_LO12:
   7681 	case BFD_RELOC_NDS32_TLS_IEGP_HI20:
   7682 	case BFD_RELOC_NDS32_TLS_IEGP_LO12:
   7683 	case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
   7684 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
   7685 	  break;
   7686 	default:
   7687 	  break;
   7688 	}
   7689       return;
   7690     }
   7691 
   7692   if (fixP->fx_addsy == NULL)
   7693     fixP->fx_done = 1;
   7694 
   7695   if (fixP->fx_subsy != NULL)
   7696     {
   7697       /* HOW DIFF RELOCATION WORKS.
   7698 
   7699 	 First of all, this relocation is used to calculate the distance
   7700 	 between two symbols in the SAME section.  It is used for  jump-
   7701 	 table, debug information, exception table, et al.    Therefore,
   7702 	 it is a unsigned positive value.   It is NOT used for  general-
   7703 	 purpose arithmetic.
   7704 
   7705 	 Consider this example,  the distance between  .LEND and .LBEGIN
   7706 	 is stored at the address of foo.
   7707 
   7708 	 ---- >8 ---- >8 ---- >8 ---- >8 ----
   7709 	  .data
   7710 	  foo:
   7711 	    .word	.LBEGIN - .LEND
   7712 
   7713 	  .text
   7714 	     [before]
   7715 	  .LBEGIN
   7716 			 \
   7717 	     [between]    distance
   7718 			 /
   7719 	  .LEND
   7720 	     [after]
   7721 	 ---- 8< ---- 8< ---- 8< ---- 8< ----
   7722 
   7723 	 We use a single relocation entry for this expression.
   7724 	 * The initial distance value is stored directly in that location
   7725 	   specified by r_offset (i.e., foo in this example.)
   7726 	 * The begin of the region, i.e., .LBEGIN, is specified by
   7727 	   r_info/R_SYM and r_addend, e.g., .text + 0x32.
   7728 	 * The end of region, i.e., .LEND, is represented by
   7729 	   .LBEGIN + distance instead of .LEND, so we only need
   7730 	   a single relocation entry instead of two.
   7731 
   7732 	 When an instruction is relaxed, we adjust the relocation entry
   7733 	 depending on where the instruction locates.    There are three
   7734 	 cases, before, after and between the region.
   7735 	 * between: Distance value is read from r_offset,  adjusted and
   7736 	   written back into r_offset.
   7737 	 * before: Only r_addend is adjust.
   7738 	 * after: We don't care about it.
   7739 
   7740 	 Hereby, there are some limitation.
   7741 
   7742 	 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
   7743 	 are semantically different, and we cannot handle latter case
   7744 	 when relaxation.
   7745 
   7746 	 The latter expression means subtracting 1 from the distance
   7747 	 between .LEND and .LBEGIN.  And the former expression means
   7748 	 the distance between (.LEND - 1) and .LBEGIN.
   7749 
   7750 	 The nuance affects whether to adjust distance value when relax
   7751 	 an instruction.  In another words, whether the instruction
   7752 	 locates in the region.  Because we use a single relocation entry,
   7753 	 there is no field left for .LEND and the subtrahend.
   7754 
   7755 	 Since GCC-4.5, GCC may produce debug information in such expression
   7756 	     .long  .L1-1-.L0
   7757 	 in order to describe register clobbering during an function-call.
   7758 	     .L0:
   7759 		call foo
   7760 	     .L1:
   7761 
   7762 	 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
   7763 	 for details.  */
   7764 
   7765       value -= S_GET_VALUE (fixP->fx_subsy);
   7766       *valP = value;
   7767       fixP->fx_subsy = NULL;
   7768       fixP->fx_offset -= value;
   7769 
   7770       switch (fixP->fx_r_type)
   7771 	{
   7772 	case BFD_RELOC_8:
   7773 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
   7774 	  md_number_to_chars (where, value, 1);
   7775 	  break;
   7776 	case BFD_RELOC_16:
   7777 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
   7778 	  md_number_to_chars (where, value, 2);
   7779 	  break;
   7780 	case BFD_RELOC_32:
   7781 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
   7782 	  md_number_to_chars (where, value, 4);
   7783 	  break;
   7784 	case BFD_RELOC_NDS32_DIFF_ULEB128:
   7785 	  /* cvt_frag_to_fill () has called output_leb128 () for us.  */
   7786 	  break;
   7787 	default:
   7788 	  as_bad_subtract (fixP);
   7789 	  return;
   7790 	}
   7791     }
   7792   else if (fixP->fx_done)
   7793     {
   7794       /* We're finished with this fixup.  Install it because
   7795 	 bfd_install_relocation won't be called to do it.  */
   7796       switch (fixP->fx_r_type)
   7797 	{
   7798 	case BFD_RELOC_8:
   7799 	  md_number_to_chars (where, value, 1);
   7800 	  break;
   7801 	case BFD_RELOC_16:
   7802 	  md_number_to_chars (where, value, 2);
   7803 	  break;
   7804 	case BFD_RELOC_32:
   7805 	  md_number_to_chars (where, value, 4);
   7806 	  break;
   7807 	case BFD_RELOC_64:
   7808 	  md_number_to_chars (where, value, 8);
   7809 	  break;
   7810 	default:
   7811 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   7812 			_("Internal error: Unknown fixup type %d (`%s')"),
   7813 			fixP->fx_r_type,
   7814 			bfd_get_reloc_code_name (fixP->fx_r_type));
   7815 	  break;
   7816 	}
   7817     }
   7818 }
   7819 
   7820 /* Implement tc_gen_reloc.  Generate ELF relocation for a fix-up.  */
   7821 
   7822 arelent *
   7823 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   7824 {
   7825   arelent *reloc;
   7826   bfd_reloc_code_real_type code;
   7827 
   7828   reloc = notes_alloc (sizeof (arelent));
   7829   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   7830   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   7831   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   7832 
   7833   code = fixP->fx_r_type;
   7834 
   7835   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   7836   if (reloc->howto == NULL)
   7837     {
   7838       as_bad_where (fixP->fx_file, fixP->fx_line,
   7839 		    _("internal error: can't export reloc type %d (`%s')"),
   7840 		    fixP->fx_r_type, bfd_get_reloc_code_name (code));
   7841       return NULL;
   7842     }
   7843 
   7844   /* Add relocation handling here.  */
   7845 
   7846   switch (fixP->fx_r_type)
   7847     {
   7848     default:
   7849       /* In general, addend of a relocation is the offset to the
   7850 	 associated symbol.  */
   7851       reloc->addend = fixP->fx_offset;
   7852       break;
   7853 
   7854     case BFD_RELOC_NDS32_DATA:
   7855       /* Prevent linker from optimizing data in text sections.
   7856 	 For example, jump table.  */
   7857       reloc->addend = fixP->fx_size;
   7858       break;
   7859     }
   7860 
   7861   return reloc;
   7862 }
   7863 
   7864 static struct suffix_name suffix_table[] =
   7865 {
   7866   {"GOTOFF",	BFD_RELOC_NDS32_GOTOFF},
   7867   {"GOT",	BFD_RELOC_NDS32_GOT20},
   7868   {"TPOFF",	BFD_RELOC_NDS32_TPOFF},
   7869   {"PLT",	BFD_RELOC_NDS32_25_PLTREL},
   7870   {"GOTTPOFF",	BFD_RELOC_NDS32_GOTTPOFF},
   7871   {"TLSDESC",  BFD_RELOC_NDS32_TLS_DESC},
   7872 };
   7873 
   7874 /* Implement md_parse_name.  */
   7875 
   7876 int
   7877 nds32_parse_name (char const *name, expressionS *exprP,
   7878 		  enum expr_mode mode ATTRIBUTE_UNUSED,
   7879 		  char *nextcharP ATTRIBUTE_UNUSED)
   7880 {
   7881   segT segment;
   7882 
   7883   exprP->X_op_symbol = NULL;
   7884   exprP->X_md = BFD_RELOC_UNUSED;
   7885 
   7886   exprP->X_add_symbol = symbol_find_or_make (name);
   7887   exprP->X_op = O_symbol;
   7888   exprP->X_add_number = 0;
   7889 
   7890   /* Check the special name if a symbol.  */
   7891   segment = S_GET_SEGMENT (exprP->X_add_symbol);
   7892   if ((segment != undefined_section) && (*nextcharP != '@'))
   7893     return 0;
   7894 
   7895   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
   7896     {
   7897       /* Set for _GOT_OFFSET_TABLE_.  */
   7898       exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
   7899     }
   7900   else if (*nextcharP == '@')
   7901     {
   7902       size_t i;
   7903       char *next;
   7904       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
   7905 	{
   7906 	  next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
   7907 	  if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
   7908 			   strlen (suffix_table[i].suffix)) == 0
   7909 	      && !is_part_of_name (*next))
   7910 	    {
   7911 	      exprP->X_md = suffix_table[i].reloc;
   7912 	      *input_line_pointer = *nextcharP;
   7913 	      input_line_pointer = next;
   7914 	      *nextcharP = *input_line_pointer;
   7915 	      *input_line_pointer = '\0';
   7916 	      break;
   7917 	    }
   7918 	}
   7919     }
   7920 
   7921   return 1;
   7922 }
   7923 
   7924 /* Implement tc_regname_to_dw2regnum.  */
   7925 
   7926 int
   7927 tc_nds32_regname_to_dw2regnum (char *regname)
   7928 {
   7929   struct nds32_keyword *sym = str_hash_find (nds32_gprs_hash, regname);
   7930 
   7931   if (!sym)
   7932     return -1;
   7933 
   7934   return sym->value;
   7935 }
   7936 
   7937 void
   7938 tc_nds32_frame_initial_instructions (void)
   7939 {
   7940   /* CIE */
   7941   /* Default cfa is register-31/sp.  */
   7942   cfi_add_CFA_def_cfa (31, 0);
   7943 }
   7944